Portability and Performance Improvements in JAX-WS Clients Created in NetBeans IDE 6.7

In NetBeans IDE 6.7, JAX-WS web service clients are both faster and portable out-of-the-box, because the client no longer has to find and parse a remote WSDL file. When you create a client from a WSDL, the IDE generates a copy of this WSDL and saves it in your project. What's more, if the WSDL references any schema files or recursively references other WSDL files, the IDE generates copies of these files as well. The IDE also generates a jax-ws-catalog.xml file that maps the remote system references to local paths.

Before the client can call a web service operation, it has to parse the service WSDL to get information such as the endpoint URL. Thanks to local WSDL copies and catalog mapping, the remote WSDL does not have to be available for the client to run. (Even if the remote WSDL is available, the client runs more quickly without having to look up the WSDL on the Internet.) This means that you can distribute the .war or .jar file built from your client project. As long as the service is running, the client will work on other machines.

To see how portable are JAX-WS clients created in NetBeans 6.7, create a simple client from a WSDL file you have on your machine. The real-world scenario would use the URL of a WSDL on the Internet. For convenience, download the WSDL onto your machine instead of using its URL.

To generate and test the client:

  1. In a browser, go to webservicex.net and download the WSDL file for their Currency Convertor [sic] service. The WSDL is located at http://www.webservicex.net/CurrencyConvertor.asmx?wsdl.

  2. Open NetBeans IDE 6.7 and create a new Java Application project. Name the project CurrencyConvertorClient.
  3.  
  4. In the Projects window, right-click the project node of CurrencyConvertorClient. Select New > Other > Web Services > Web Service Client. The New Web Service Client wizard opens.
  5.  
  6. In the WSDL and Client Location screen, select Local File and browse to the location of the downloaded CurrencyConvertor.asmx.wsdl file:

  7.  
  8. Click Finish. The wizard closes, and the IDE creates the following contents in the project tree:

  9.  
  10. Open the Main.java file in your CurrencyConvertorClient project. Drag the CurrencyConvertorSoap ConversionRate operation from the Projects window into the method body of the main method, where the comment says //TODO code application logic here. The IDE inserts the following try block into the main method:
    try { // Call Web Service Operation
    net.webservicex.CurrencyConvertor service = new net.webservicex.CurrencyConvertor();
    net.webservicex.CurrencyConvertorSoap port = service.getCurrencyConvertorSoap();
    // TODO initialize WS operation arguments here
    net.webservicex.Currency fromCurrency = null;
    net.webservicex.Currency toCurrency = null;
    // TODO process result here
    double result = port.conversionRate(fromCurrency, toCurrency);
    System.out.println("Result = "+result);
    } catch (Exception ex) {
    // TODO handle custom exceptions here
    }
  11.  
  12. In order to get output, replace the following two lines:
    net.webservicex.Currency fromCurrency = null;
    net.webservicex.Currency toCurrency = null;

    ...with the following lines, which hard code the client to return the exchange rate from US dollars to Euros.

    net.webservicex.Currency fromCurrency = net.webservicex.Currency.USD;
    net.webservicex.Currency toCurrency = net.webservicex.Currency.EUR;
  13.  
  14. Run the project. The output window in the IDE shows the following. (Your paths will probably be different, and the exchange rate may be different, too!)
    wsimport-client-generate:
    Created dir: G:\NetBeansProjects\67M2\CurrencyConvertorClient\build\classes
    Compiling 10 source files to G:\NetBeansProjects\67M2\CurrencyConvertorClient\build\classes
    Copying 2 files to G:\NetBeansProjects\67M2\CurrencyConvertorClient\build\classes
    compile:
    run:
    Result = 0.7544
    BUILD SUCCESSFUL (total time: 18 seconds)
  15.  
  16. Go to the Projects window and find the project's META-INF folder, under Source Packages. In this folder, open jax-ws-catalog.xml. It maps the original WSDL file references to the copy of the WSDL in your project, in META-INF.wsdl. Note that the client looks for the resource in the uri attribute first, and then looks for the original WSDL file.
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system">
    <system systemId="file:/G:/installation_files/CurrencyConvertor.asmx.wsdl"
    uri="wsdl/CurrencyConvertor.asmx.wsdl"/>
    </catalog>
  17.  
  18. Change the path in the uri attribute to something invalid. Clean and build your project and run it again. The project builds and runs successfully. Although the client could not find the local resource, it could find the resource in systemId.
  19.  
  20. Move or rename the WSDL you downloaded, which is named in the systemId attribute. Run the project again. The project compiles, because you have a copy of all necessary Java files under Generated Sources. However, the IDE does not display any result, because no WSDL, and therefore no service endpoint, could be found.
  21.  
  22. Change the value of the uri attribute back to the correct path, wsdl/CurrencyConvertor.asmx.wsdl. Run the project again. Now the result displays correctly, because the compiler can find the local copy of the WSDL in the project files.


You now have a JAX-WS client that can run on any machine connected to the Internet. Clean and build the project. The CurrencyConverterClient.jar file is in the project's dist directory. You can find it in the Files window. You can copy the jar file and port it to any machine with Java, connected to the Internet.

0

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

ismail9000 replied on Thu, 2009/05/07 - 11:32am

I hope that it is ok with you guys but I like read these tutorials. I try to preform the exercises and also get all of the plugins for Netbeans so that I can continue learning

liluqun replied on Mon, 2009/05/11 - 4:08am

I did the work following the instructions above only to find the errors:

Compiling 1 source file to D:\home\li\My Documents\NetBeansProjects\JavaApplication7\build\classes
D:\home\li\My Documents\NetBeansProjects\JavaApplication7\src\javaapplication7\Main.java:19: package net.webservicex does not exist
            net.webservicex.CurrencyConvertor service = new net.webservicex.CurrencyConvertor();
D:\home\li\My Documents\NetBeansProjects\JavaApplication7\src\javaapplication7\Main.java:19: package net.webservicex does not exist
            net.webservicex.CurrencyConvertor service = new net.webservicex.CurrencyConvertor();
D:\home\li\My Documents\NetBeansProjects\JavaApplication7\src\javaapplication7\Main.java:20: package net.webservicex does not exist
            net.webservicex.CurrencyConvertorSoap port = service.getCurrencyConvertorSoap();
D:\home\li\My Documents\NetBeansProjects\JavaApplication7\src\javaapplication7\Main.java:22: package net.webservicex does not exist
            net.webservicex.Currency fromCurrency = net.webservicex.Currency.USD;
D:\home\li\My Documents\NetBeansProjects\JavaApplication7\src\javaapplication7\Main.java:22: package net.webservicex does not exist
            net.webservicex.Currency fromCurrency = net.webservicex.Currency.USD;
D:\home\li\My Documents\NetBeansProjects\JavaApplication7\src\javaapplication7\Main.java:23: package net.webservicex does not exist
            net.webservicex.Currency toCurrency = net.webservicex.Currency.EUR;
D:\home\li\My Documents\NetBeansProjects\JavaApplication7\src\javaapplication7\Main.java:23: package net.webservicex does not exist
            net.webservicex.Currency toCurrency = net.webservicex.Currency.EUR;
7 errors
D:\home\li\My Documents\NetBeansProjects\JavaApplication7\nbproject\build-impl.xml:379: The following error occurred while executing this line:
D:\home\li\My Documents\NetBeansProjects\JavaApplication7\nbproject\build-impl.xml:167: Compile failed; see the compiler error output for details.
BUILD FAILED (total time: 0 seconds)

 javax.xml.ws.WebServiceException: class net.webservicex.ConversionRate do not have a property of the name {http://www.webserviceX.NET/}FromCurrency
        at com.sun.xml.internal.ws.client.sei.BodyBuilder$DocLit.<init>(BodyBuilder.java:188)
        at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.<init>(SyncMethodHandler.java:120)
        at com.sun.xml.internal.ws.client.sei.SEIStub.<init>(SEIStub.java:67)
        at com.sun.xml.internal.ws.client.WSServiceDelegate.createEndpointIFBaseProxy(WSServiceDelegate.java:544)
        at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:292)
        at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:274)
        at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:267)
        at javax.xml.ws.Service.getPort(Service.java:92)
        at net.webservicex.CurrencyConvertor.getCurrencyConvertorSoap(CurrencyConvertor.java:56)
        at javaapplication7.Main.main(Main.java:20)
Caused by: javax.xml.bind.JAXBException: {http://www.webserviceX.NET/}FromCurrency is not a valid property on class net.webservicex.ConversionRate
        at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getElementPropertyAccessor(JAXBContextImpl.java:910)
        at com.sun.xml.internal.ws.client.sei.BodyBuilder$DocLit.<init>(BodyBuilder.java:185)
        ... 9 more
BUILD SUCCESSFUL (total time: 2 seconds)

 

Why......................................................why

pbelb replied on Mon, 2009/05/11 - 12:03pm

Was this an april fools day post?

that's really nice, but: don't you think we should be able to achieve the same thing, but without having to do all that messing around manually?

eg:

when you supply to NB the WSDL URL, the ide captures all the WSDL and related schemas. why not just have an option to capture it as a static definition, so that it's only ever done once, and for ever after, it uses that captured data, and, modifies the target URI for you?

well, I have been using NB 6.5 with jax-ws, with this alternative way to create the client proxy so that it does not try to connect with the URI that's in the wsdl.

at runtime, you do need to know the URL of the web service endpoint (but you should know that really, unless you're using UDDI - which finds it for you), but here is how to connect without the code trying to use the URI that's been captured in the WSDL during compile/development:

import javax.xml.namespace.QName;
import javax.xml.ws.WebServiceClient;

URL url = new URL("http://test.webservice.com/service/MyService");
WebServiceClient ann = YourService.class.getAnnotation(WebServiceClient.class);
QName qname = new QName(ann.targetNamespace(), ann.name());
YourService service = new YourService(url,qname);
binding = service.getYourPort();

I suppose, the only bit that's not already there is that of having the default template that gets used when you drag a web service reference to your java code updated. If it were updated so that the above code were used (and the URI from the wsdl pulled in as the source for the URL to be created, we could avoid all the nastiness of the client trying to access the web service that was available at build time, without perhaps having to do all the manual stuff that you're suggesting too!, and, it works with NB 6.5!!

michaljohn replied on Thu, 2009/06/11 - 11:44pm

To see how portable are JAX-WS clients created in NetBeans 6.7, create a simple client from a WSDL file you have on your machine. Nation High School

eric_guy77 replied on Tue, 2009/08/18 - 1:30pm

Hi, this is a good topic to have discussion on as I have go though all the posts replies there is not much to talk about every most of the replies have been written what I wanted to share…

Thanks and Regards

Eric from home tuition kuala lumpur | home tuition malaysia

Chirrindulari replied on Fri, 2009/10/16 - 4:11am

I've followed the tutorial and all is fine on the machine where I have developed it (ADSL connection to internet).

I found the app interesting to distribute between colleagues, but when I tried to use the JAR on other machines, it does not work. It seems to be because there is a proxy. Do you know of a tutorial where proxies are involved?

 

Thanks for the tutorial, Jeff. It's very useful for me.

 

KevinE replied on Thu, 2009/10/29 - 12:49pm in response to: Chirrindulari

Hi. I'm having the exact same problem. I'm importing a wsdl from my local c drive. It runs great on my machine. But when I deploy to dev it's still looking for the wsdl on the c drive and not the catalog mapping uri as described here. I've been fighting this for about a week. This tutorial doesn't seem to work as advertised. I wonder if it really is an April Fool's issue.

Chirrindulari replied on Fri, 2009/10/30 - 2:31am

Kevin,

I'm sorry, but my problem isn't the same. I followed the tutorial and it has worked exactly as described. At the beggining, the program asked for the WSDL via an HTTP GET command, just in the creation of "port" or "service", I don't remember now. But after following the steps of the tutorial, this step was avoided, and the only request was the SOAP message on port.conversionRate. This behavior can be observed using a home ADSL connection.

My problem is that, when I use the corporate proxy to access HTTP, it doesn't work, because this program doesn't send the proxy user and password to the proxy server. To provide theproxy's credentials, I run the program with these arguments:

-Dhttp.proxyHost=PROXY_ADDRESS  -Dhttp.proxyPort=8080 -Dhttp.proxyUser="WIN_DOMAIN\USER" -Dhttp.proxyPassword="PASSWORD"

The program tries to send to the proxy server on "PROXY_ADDRESS" the SOAP message, the proxy server do not accept the transaction because user/password is required, but the program doesn't send them.

Has anybody experience comunicating through HTTP proxy servers?

KevinE replied on Wed, 2009/11/04 - 9:28am in response to: Chirrindulari

I don't have a lot of experience with proxy, although I'm gaining some here at my current place of employment. One thing I noticed is that vmOptions are inserted upon project creation depending on how you have set your proxy settings. to see your proxy settings in netbeans, go to tools/options. (I'm using netbeans 6.7.1) Set your proxy settings to either "use system proxy settings" or set them manually (if you know them) by clicking "manual proxy settings". try creating a java application with proxy settings on (either system or manual) and creating another one with no proxy settings. then to see the the vm options, right click the project node and select properties then select run in the catagories box. You should see some vm options set for the project you created using the manual or system proxy setting. But you may alread know all about this. So, have you really got the local mapping to work when deploying to another server? I never could figure it out so I just uploaded the wsdl to another server where my app can always get it. The local mapping for me never kicked in. Kevin.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.