Recently I was given the opportunity to write an online email client at my job. Throughout the application, at key points of contact, we will integrate message creation for students to seamlessly contact instructors, advisors, classmates, fellow club members, etc. Also, we wanted a full email client worked into the application. My point is, there are good reasons for writing the email client. This is not just some pipe dream.
Technology Background
Here's the technology background for this work:
| Email Server: | Exchange 2007 SP1 (with Exchange Web Services enabled) |
| Programming Language: | Java 1.5 or later |
| Application Server: | Oracle Application Server 10g (production) |
| Glassfish v2 (local development) | |
| Web Service Stack: | Glassfish Metro (guide for deployment on OC4J later) |
| Development IDE: | NetBeans 6.1 (guide for Eclipse 3.4 later) |
Enable Exchange Web Services
The first step in this process, is to speak with your Exchange administrator. Have him or her turn on Exchange Web Services. If they're turned on, you should be able to get the WSDL at https://mail.example.com/EWS/exchange.asmx (which redirects to https://mail.example.com/ews/Services.wsdl in most cases, I believe). Remember this URL for later.
Set up your development environment
You will need two core pieces of technology to get started developing. The first is an application server. Download Glassfish v2 (or Glassfish v3 if you're savvy). You will also need a development environment. Install NetBeans 6.1. If you're using Linux, check your package manager first. The files may be available through your distribution. If you're on Ubuntu Linux, like I am, install the netbeans and glassfishv2 packages. If you're on Windows, Mac, or feel like doing a manual Linux install, use the links above and the corresponding installation directions.
Preparing NetBeans
We will need a few NetBeans plugins: Java EE, Web Applications, Web Services, and Glassfish. Install them through the plugin manager at Tools → Plugins. Also, do any recommended plugin/platform updates at this time as well.
Now we have to add Glassfishv2 as a server in NetBeans:
- Go to Tools → Servers → Add Server...
- In the 'Choose Server' dialog box that comes up, select Glassfishv2 as your server and click 'Next'.
- In the next screen, set 'Platform Location' to the directory where you installed Glassfish.
- Note: On Ubuntu, if you installed from the repositories, this is
/usr/share/glassfishv2
- Note: On Ubuntu, if you installed from the repositories, this is
- Also, select 'Register Local Default Domain'. The default domain for most installs is
${glassfish_home}/domains.- I ran into several issues on Ubuntu setting 'Register Local Domain'. The following instructions are for Ubuntu users only:
- The pre-configured default domain from the package manager is et up at
/var/lib/glassfishv2/domains/domain1but if you try to enter this as the 'Domain Folder' you will get the errorCannot find valid domain.xml file. I believe this is because the platform location and domain folder are in two different locations. - So I had to stop the default domain executing
sudo /var/lib/glassfishv2/domains/domain1/bin/stopserv. - Then, back in NetBeans at the 'Platform Folder Location' dialog, I selected 'Create Personal Domain' with the default profile.
- Go out to the operating system's file manager and create the folder
/home/[your username]/glassfishv2/domains - Back in NetBeans on the 'Domain Folder Location' dialog. Set the 'Domain Folder' to
/home/[your username]/glassfishv2/domains/netbeans_domainand click next. - Set your desired administrator username and password and click next.
- On the 'Creation Properties' dialog I noticed I was not suggested the standard ports for my application server. So if you want to use the standard port numbers (recommended) make sure they're all set to the following values:
- Click 'Finish'
- The pre-configured default domain from the package manager is et up at
- I ran into several issues on Ubuntu setting 'Register Local Domain'. The following instructions are for Ubuntu users only:
- After finishing you should now see the server startup messages show up in the NetBeans console. It will end in
Domain netbeans_domain created.
Setting up the NetBeans Project
Create a new project of type Web → Web Application. I set mine up as a JavaEE 5 project. After the project has been created you'll see a generic NetBeans web project.
Remember that WSDL file from earlier? We're finally ready to start using it. Unfortunately, Microsoft didn't format it 100% correct. There's some discussion on the topic over at the MSDN forums. The WSDL being provided by Exchange is missing a wsdl:service element. If you tried to add a Web Service Client pointing at this WSDL you'd get the error.
Web Service Client can not be created by JAXWS:wsimport utility.
Reason: Could not find wsdl:service in the provide WSDL(s):
...
You need to provide at least one WSDL with at least one service definition.To get around this error, download the file at https://mail.example.com/ews/Services.wsdl and save a copy locally in your project's web folder, eg. [NetBeans Project Folder]/web/exchange.wsdl. If you tried to create a Web Service Client from this WSDL you'll see that the relative references to messages.xsd and types.xsd are broken. So you also need to download copies of https://mail.example.com/ews/messages.xsd and https://mail.example.com/ews/types.xsd and save them in the same local folder as the WSDL.
So now that we have all the files necessary, let's edit that WSDL to be valid. Open it up in NetBeans from your 'Web Pages' folder. At the second to last line, before the final tag place the following XML code:
<wsdl:service name="ExchangeWebService">
<wsdl:port name="ExchangeWebPort" binding="tns:ExchangeServiceBinding">
<soap:address location="https://mail.example.com/EWS/exchange.asmx"></soap:address>
</wsdl:port>
</wsdl:service>Microsoft's provided XML is still not ready for parsing. If you tried to read the file now, you'd get the error:
Web Service Client can not be created by JAXWS:wsimport utility.
Reason: Undefined Attribute 'xml:lang'
There might be a problem during java artifacts creation: for example a name conflict in generated classes.The offending line is around line 3370 of types.xsd. It reads <xs:attribute ref="xml:lang" use="optional"></xs:attribute>. Someone please tell me how to get around this error if you have a better solution. For the time being I just commented the line out like <!-- <xs:attribute ref="xml:lang" use="optional"></xs:attribute> -->.
Generating the Java code
Finally! We're done fixing up the WSDL's and XSD files that Microsoft has presented. Let's generate some code. In NetBeans, right click on the project and select New → Web Service Client.
In the dialogs that come up:
Local File: [NetBeans Project Folder]/web/exchange.wsdl
Client Style: JAX-WSl
Click 'Finish' and you'll start the generation of your web services client from the WSDL file. You should see a bunch of build script output and compiling going on below in the NetBeans output area. If it's successful, it will end with something like:
wsimport-client-generate:
Created dir: /home/[your username]/ExchangeWebServices/build/web/WEB-INF/classes
wsimport-client-compile:
Compiling 409 source files to /home/[your username]/ExchangeWebServices/build/web/WEB-INF/classes
BUILD SUCCESSFUL (total time: 19 seconds)Now, to develop code using these web services, the NetBeans documentation recommends using their "Web Service Client Resources → Call Web Service Operation" context menus and code generation. I find this terribly annoying and would rather just copy the generated Java files into the src folder of my project:
- Open up your operating system's file manager.
- Browse to
[NetBeans Project Folder]/build/generated/wsimport/client - You'll see one folder in here named 'com'. This is the start of the
com.microsoft.schemas.exchange.services._2006packages. So copy the 'com' folder. - Navigate back to
[NetBeans Project Folder]/src/javaand paste the 'com' folder in here.
Now open up NetBeans again and you should see all the 409 generated Exchange Web Service files in your source package split into two package groups. Congratulations! The toughest part of this entire tutorial series is over.

Conclusion
The frustrations I went through figuring all this out is 50% of what inspired this tutorial series you're reading now :) I felt there were no good Java/Exchange Web Service guides out there, esp. tailored to Metro/NetBeans. In my next article, I will go over authenticating through web services and returning a successfully authenticated ExchangeServicePortType.
Note: Please, if you have suggested improvements to this article, or any other comments I encourage you to leave me feedback. I'd love to get some constructive criticism, or hear back if the guide helped you.
Revisions
I've updated this article a few times as I receive user comments and look into questions further:
- Jan 15, 2009: Updated the "Generating the Java code" section, and included a link to the NetBeans documentation for how they recommend invoking web service operations, and how I think their way is annoying.





I still think it's a pipe dream. It can be done. It's just so time consuming I don't see it being worth the effort.
Hi Reid,
To work around Undefined Attribute 'xml:lang' issue you can replace
<xs:import namespace="http://www.w3.org/XML/1998/namespace"/>
with
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
at the beginning of types.xsd.
For explanation see:
http://social.technet.microsoft.com/forums/en-US/exchangesvrdevelopment/...
Thanks for this excellent guide.
I am using JDeveloper 11g to generate the EWS java classes. It generated
101 java files under: com\microsoft\schemas\exchange\services\_2006\messages, plus ExchangeServices.jaxrpc
and 307 java files under: com\microsoft\schemas\exchange\services\_2006\types
so total 408 files, instead of 409 files as you mentioned.
When I tried to follow your 2nd topic, Using ExchangeServicePortType with Authentication Credentials, it refers to ExchangeServicePortType class which I don't see under com\microsoft\schemas\exchange\services\_2006\messages.
To generate the java files, on JDeveloper I did:
- File > New > (New GAllery) dialog > + Business Tier > Web Services > Java Web Services from WSDL
Some one suggested to do: Web Services > Web Service Proxy.
But while doing that (during 'Binding Model' progress dialog) it shows
Validation Failed
oracle.jdeveloper.websercie.model.WebServiceException:
The WSDL document is invalide for the following reason: (null)
oracle.jdeveloper.webservices.model.WebServiceException: The WSDL document is invalid for the following reason:
(null)
at oracle.jdeveloper.webservices.model.CoreHashStructureModel.validate(CoreHashStructureModel.java:226)
at oracle.jdeveloper.webservices.model.CoreHashStructureModel.validate(CoreHashStructureModel.java:153)
at oracle.jdevimpl.webservices.wizard.jaxrpc.proxy.ProxyJaxWsSpecifyWSDLPanel.validate(ProxyJaxWsSpecifyWSDLPanel.java:250)
at oracle.jdevimpl.webservices.wizard.jaxrpc.common.SpecifyWsdlPanel.buildModel(SpecifyWsdlPanel.java:1086)
at oracle.jdevimpl.webservices.wizard.jaxrpc.common.SpecifyWsdlPanel$6.run(SpecifyWsdlPanel.java:644)
at oracle.ide.dialogs.ProgressBar.run(ProgressBar.java:643)
at java.lang.Thread.run(Thread.java:619)
The Services.wsdl (types.xsd) file(s) are modified according to your guide, successfully generated java classes by:
Web Services > Java Web Services from WSDL
but did not create the ExchangeServicePort.java file.
I will appreciate if anyone can help me with the fix for this.
Thanks
Missing ExchangeServicePort.java
Comment out the
<!-- --> and it's end tag -->
<!--
This will cause the generator to generate the 409 files instead of the 407 files.
those two lines kept the binding and the ports hidden from the service stanza.
I am using Netbeans 6.7.1 and was having the same problem but when those lines were commented out, it took care of the issue and I was even able to run the testdemo that was created by Reid by just changing the URL, the domain and user credentials.
Hope it helps
the tags were removed on rendering by the site
it should be this
"< wsdl:types>" and "" in the wsdl file (exchange.wsdl or services.wsdl)
Sorry for the confusion
Thanks for this excellent guide.
I am using JDeveloper 11g to generate the EWS java classes. It generated
101 java files under: com\microsoft\schemas\exchange\services\_2006\messages, plus ExchangeServices.jaxrpc
and 307 java files under: com\microsoft\schemas\exchange\services\_2006\types
so total 408 files, instead of 409 files as you mentioned.
When I tried to follow your 2nd topic, Using ExchangeServicePortType with Authentication Credentials, it refers to ExchangeServicePortType class which I don't see under com\microsoft\schemas\exchange\services\_2006\messages.
To generate the java files, on JDeveloper I did:
- File > New > (New GAllery) dialog > + Business Tier > Web Services > Java Web Services from WSDL
Some one suggested to do: Web Services > Web Service Proxy.
But while doing that (during 'Binding Model' progress dialog) it shows
Validation Failed
oracle.jdeveloper.websercie.model.WebServiceException:
The WSDL document is invalide for the following reason: (null)
oracle.jdeveloper.webservices.model.WebServiceException: The WSDL document is invalid for the following reason:
(null)
at oracle.jdeveloper.webservices.model.CoreHashStructureModel.validate(CoreHashStructureModel.java:226)
at oracle.jdeveloper.webservices.model.CoreHashStructureModel.validate(CoreHashStructureModel.java:153)
at oracle.jdevimpl.webservices.wizard.jaxrpc.proxy.ProxyJaxWsSpecifyWSDLPanel.validate(ProxyJaxWsSpecifyWSDLPanel.java:250)
at oracle.jdevimpl.webservices.wizard.jaxrpc.common.SpecifyWsdlPanel.buildModel(SpecifyWsdlPanel.java:1086)
at oracle.jdevimpl.webservices.wizard.jaxrpc.common.SpecifyWsdlPanel$6.run(SpecifyWsdlPanel.java:644)
at oracle.ide.dialogs.ProgressBar.run(ProgressBar.java:643)
at java.lang.Thread.run(Thread.java:619)
The Services.wsdl (types.xsd) file(s) are modified according to your guide, successfully generated java classes by:
Web Services > Java Web Services from WSDL
but did not create the ExchangeServicePort.java file.
I will appreciate if anyone can help me with the fix for this.
Thanks
After I copy in the 'com' folder some of the files are failing e.g., package-info.java is fine built package-info_1.java "error parsing file". This is the same error for are the troubled files. It looks as if the files are duplicated all through the packages but some are fine in others give the ‘noted above’ error message.
Thoughts?
Thanks, Eric
Thank you for the guide. You saved me alot of time.
Thanks.
I am developing an email connector that synchronizes PIM data (email, contact, calendar, tasks) with wireless devices. I am looking for captures of Exchange web services application protocol XML between the endpoints (WS client and server). In particular, I would like to see how updateItem is applied to contact item?
You can avoid the 'lang-error': Download xml.xsd from http://www.w3.org/2001/03/xml.xsd in the same directory as the wsdl and the other xsd-files.
Mike
...and include
< xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd" />
in types.xsd
There is no need to make a local copy of the xml.xsd file, just make this modification to types.xsd, and the xml:lang error should be resolved.
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
Thanks a lot for this guide! I was searching for something like this for two days. I still can't believe how incredibly complicated or wrong all other guides on this subject were!
Kudos!