Download NetBeans!

20060714 Friday July 14, 2006

JAX-WS, Applets, and Dilbert

Yesterday, I read Accessing JAX-WS endpoints from Applets in Sameer Tyagi's blog, about JAX-WS and applets. Of course, I wondered how to implement his scenario using NetBeans IDE. Thanks to Sameer's general guidelines, I managed to work through it all (in NetBeans IDE 5.5). The basic principle is similar to how it is described in NetBeans IDE 5.0 Tutorial for Applets. So, first you create a Java library that contains the applet and then you attach that Java library to a web application and refer to the applet from inside a JSP page or HTML file. The only points where things are different is that now you'll also need to implement a JAX-WS client in the Java library that contains the applet. Plus, you'll need to use the Keytool application and the Jarsigner application to sign the JAR file. This is because of the reasons described in a great (albeit very dated) article called Signed Applets, Browsers, and File Access. Both the Keytool application and the Jarsigner application are part of the JDK. And, thanks to Ant integration in the IDE, it is very easy to invoke these tools when needed, as will be seen later.

So, here are some detailed steps for implementing JAX-WS in an applet.

  1. Find a web service that interests you. Why not use the Asynchronous JAX-WS Web Service Client End-to-End Scenario to build this handy little application:

    I just typed in "dilbert", as you can see above, and a whole bunch of related web services were retrieved from the web. I ended up picking this one, which returns a daily Dilbert cartoon, in the form of a URL to a GIF file:

    http://www.esynaps.com/WebServices/DailyDilbert.asmx?WSDL

  2. Create an applet and make it a JAX-WS client. Use the NetBeans IDE 5.0 Tutorial for Applets to create a Java library that contains an applet. Drop a JEditorPane on the Applet Form and set its content type to text/html. Then use the Web Service Client wizard to create a client, using the WSDL mentioned in the previous step. Then drag (cool that you can drag operations, isn't it; that is new in NetBeans IDE 5.5) the DailyDilbertImagePath operation (the second of the two operations, the first one, i.e., the one that is highlighted below, we won't be using) into the applet's init() method:

    Now the init() method should look like this, after tweaking one line to prepare the JEditorPane, which you've already set to "text/html", so that you can add image tags around the URL that points to the Dilbert GIF file. Note that the line in bold is the only line of Java that you will need to type in this whole application:

    public void init() {
        try {
            java.awt.EventQueue.invokeAndWait(new Runnable() {
                public void run() {
                    initComponents();
    
                    try { // Call Web Service Operation
                        org.me.dilbert.DailyDilbert service = new org.me.dilbert.DailyDilbert();
                        org.me.dilbert.DailyDilbertSoap port = service.getDailyDilbertSoap();
                        // TODO process result here
                        java.lang.String result = port.dailyDilbertImagePath();
    
                        jEditorPane1.setText
                               ("<img src=\"" + result + "\" width=600 height=230>"+"</img>");
    
                    } catch (Exception ex) {
                        // TODO handle custom exceptions here
                    }
    
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

  3. Set dependencies. I had a lot of problems with the JAX-WS dependencies. When I added the JAX-WS library that is bundled with the IDE, I ended up with problems later (can't remember exactly what). So, eventually, although they've got the same content, I added the appserv-ws.jar and the javaee.jar from the Glassfish distribution. I also needed to add this target to build.xml (the -post-jar target runs automatically after a build, so is a really handy way of hooking additional tasks to your build process):

    <target name="-post-jar">
        <jar update="true" destfile="${dist.jar}">
            <zipfileset src="${libs.swing-layout.classpath}"/>
            <zipfileset src="${file.reference.appserv-ws.jar}"/>
            <zipfileset src="${file.reference.javaee.jar}"/>
        </jar>
    </target>

  4. Use Keytool and Jarsigner. If you were to use the Java library as it currently is, as I did, you'll encounter problems later because the Java library needs to be signed, as explained in the article referred to in this blog entry's introduction. So, add these targets to the build.xml file (note that the location of your JDK is probably different to mine, so you should change that in these targets):

    <target name="Keytool" description="keytool-generate">
        <exec executable="C:\Program Files\Java\jdk1.5.0_06\bin\keytool.exe">
            <arg value="-genkey" />
            <arg value="-alias" />
            <arg value="signFiles" />
            <arg value="-keystore" />
            <arg value="mystore" />
            <arg value="-keypass" />
            <arg value="mykeypass" />
            <arg value="-noprompt" />
            <arg value="-dname" />
            <arg value="cn=Sun" />
            <arg value="-storepass" />
            <arg value="mystorepass" />
        </exec>
    </target> 
    
    <target name="Jarsigner" description="jarsigner-generate">
        <exec executable="C:\Program Files\Java\jdk1.5.0_06\bin\jarsigner.exe">
            <arg value="-keystore" />
            <arg value="mystore" />
            <arg value="-storepass" />
            <arg value="mystorepass" />
            <arg value="-keypass" />
            <arg value="mykeypass" />
            <arg value="-signedjar" />
            <arg value="dist/SignedJar.jar" />
            <arg value="dist/HelloDilbert.jar" />
            <arg value="signFiles" />
        </exec>
    </target>

    Now, the second target will add a signed JAR file to the dist folder, where the original unsigned JAR file is found. (In addition to Sameer's blog entry, I found this really helpful when working on this part of the story.) Whenever you clean the project, the dist folder will be removed. So you need to set things up so that the signed JAR file will be recreated whenever you rebuild the project. Therefore, add the attribute that is highlighted below to the -post-jar target:

    <target name="-post-jar" depends="Jarsigner">
        <jar update="true" destfile="${dist.jar}">
            <zipfileset src="${libs.swing-layout.classpath}"/>
            <zipfileset src="${file.reference.appserv-ws.jar}"/>
            <zipfileset src="${file.reference.javaee.jar}"/>
        </jar>
    </target>

    Now, run the first of the two new targets above. This generates the keystore. Then, whenever you build the application, the signed JAR file is (re)generated, using the keystore.

  5. Run the applet. Before doing anything else, you can already try out the applet. Right-click the applet (and not the project) and choose Run File. You'll see a happy little Dilbert cartoon (whatever is current for the day, so probably not this one, which is fortunate because this one is pretty lame; in fact, I think all those weird Dilbertesque animals—cats, dogs, and so on—just aren't very funny and I hope Scott Adams, when googling his name, finds this comment because without all those dumb animals, Dilbert would be so much better than it already is, Scott Adams, Scott Adams, Scott Adams):

    If you don't like the size, you can tweak it in two places. Either in the HTML Launcher file that is created by the IDE for you, in the build folder. It is created after the first time that you run the applet. Go to the build folder and move (or copy) the HTML file to the exact same source folder where the applet is found. Notice that they're now in the same folder and that they have the same name. Now you can tweak the width and height. These are the width and height that will be used, and not the width and height provided by the HTML file that will be generated again in the build folder. The second place where you can tweak width and height is in the applet itself, in the line that defines the size of the image, which is the one line where you did some actual coding in an earlier step:

    jEditorPane1.setText("<img src=\"" + result + "\" width=600 height=230>"+"</img>");

    Once you're happy with the size of the applet, i.e., the Dilbert cartoon fits snugly, as in the screenshot above, you can move on to the next step.

  6. Create the web application. After you create the web application, go to the Project Properties dialog box and, in the Packaging panel, add the signed JAR file. You will not be needing that unsigned JAR file at all anymore. Just use the signed JAR file.

    Then add the applet tag to the index.jsp file, like this:

    <applet code="org.me.dilbert.MyDilbert" width=615 height=250 archive="SignedJar.jar"/> 

  7. Run the web application. Now run the web application. You'll see the circling applet thingy as well as this digital signature story (thanks to your keytool activities earlier on):

    Click Run, and then you'll get to see your Dilbert cartoon within a live, running applet. Here it is in FireFox:

    And this is what it looks like in Internet Explorer:

And that's all! You're done. You've turned your applet into a JAX-WS client and you've signed its JAR file. As you can see, these are the two preconditions for integrating applets into the world of JAX-WS.

Jul 14 2006, 12:20:31 AM PDT Permalink

Trackback URL: http://blogs.sun.com/geertjan/entry/jax_ws_applets_and_dilbert
Comments:

All this, just to read Dilbert!

Posted by Chunky Bacon on July 14, 2006 at 12:42 AM PDT #

Hmmm. I only needed to write ONE line of Java code and now I have a complete, functioning JAX-WS client applet that consumes a live web service. "All this" indeed.

Posted by Geertjan on July 14, 2006 at 04:13 AM PDT #

I'm sorry, this is very neat, but speaking as an young, to be final year developer, the fact that it even needs crypo signatures is very offputing.

Posted by paulo on July 15, 2006 at 03:57 PM PDT #

In your step 1 above you refer to another tutorial "Asynchronous JAX-WS Web Service Client End-to-End Scenario" I tried to build that app but in its step 6, Edit Web Service Attributes, I don't get that option in my version of NB. I'm using version 5, with 5.5 updates integrated. Is the option to edit WS attributes available only in a specific version? I can't find the option to enable the webservice as asynchronous. Thanks for these tutorials.

Posted by Bruce on July 18, 2006 at 12:32 AM PDT #

Hi Bruce, you'll need to install NetBeans IDE 5.5 (Beta or another build, but Beta is the best). The asynchronous client feature, and that whole Web Services Attributes editor, is only in 5.5.

Hi Paulo, yes you need to sign the applet. But it isn't very hard. Just copy the targets in this blog entry, put them in a build.xml file in your project inside the IDE, and then run them. That's all.

Posted by Geertjan on July 18, 2006 at 12:42 AM PDT #

ok

Posted by 222.18.191.8 on July 28, 2006 at 03:45 AM PDT #

I have been using Dilbert for over a year in teaching Web Services... Maybe you can use the Iceland TV guide as a web service.

Posted by Matt warman on August 16, 2006 at 12:21 PM PDT #

The Iceland TV Guide??? Where/why do I find that?

Posted by Geertjan on September 19, 2006 at 12:38 AM PDT #

go to http://www.xmethods.net they have everything!

Posted by Matt warman on September 20, 2006 at 08:43 AM PDT #

on step #4 im having problems with <target name="-post-jar" depends="Jarsigner"> <jar update="true" destfile="${dist.jar}"> <zipfileset src="${libs.swing-layout.classpath}"/> <zipfileset src="${file.reference.appserv-ws.jar}"/> <zipfileset src="${file.reference.javaee.jar}"/> </jar> </target> where are all the veriables being set ? why dont i get the file.reference work for me ? by the way im using the netbeans 5.5. everything works fine on the appletviewer - but not as a web page embbeded. thanks dovev

Posted by dovev on October 25, 2006 at 01:11 AM PDT #

Hi dovev, I just tried the whole story in this blog entry again. I used 5.5 RC 1. In step 4, I only needed this:

<target name="-post-jar">
    <jar update="true" destfile="${dist.jar}">
        <zipfileset src="${libs.swing-layout.classpath}"/>
</target>

In other, words, I didn't need those other two JAR files. If you add the above, you'll be bundling the group layout manager (Matisse) with the application, which is necessary because that's what you used when you designed the applet form. However, group layout is part of JDK 1.6, so if you're using that, then you don't need to include the group layout manager library in the build script as above. I deployed the application to GlassFish (Sun Java System Application Server), because that supports JAX-WS, while Tomcat doesn't.

Posted by Geertjan on October 25, 2006 at 02:34 AM PDT #

Obviously I’m doing something wrong. Can you post or send me the whole project? I get this at the http sniffer : - Process : iexplore.exe[3376] (COUNT=6) 12 13:01:33:769 0.075 s GET 404 4203 text/html http://127.0.0.1/EMA.API.WebService/javax/swing/LayoutStyle.class The structure of the jar file is different. Can I control that ?

Posted by dovev on October 25, 2006 at 04:12 AM PDT #

No, please send me your project, to geertjan DOT wielenga AT sun DOT com, and I will look at it.

Posted by Geertjan on October 25, 2006 at 05:30 AM PDT #

In answer to a comment you write that Tomcat does not support JAX-WS? In your article Web Services (JAX-WS) in Java EE 5 on netbeans.org, however, Tomcat is mentioned as a possibility; it depends on the (newer) version of Tomcat I guess? Anyway, based on your experiment, I did something similar with NetBeans 5.5.1 and JDK 1.6.0_02. I too had a lot of (class-loader) issues with JAX-WS, but finally got it running. Thanks! (Still a complete mystery to me is why I had to sign my applet to get it running, because I deployed both service and applet to the same web app on Tomcat.)

Posted by Carsten on September 27, 2007 at 02:00 AM PDT #

Hi Carsten, yes, JAX-WS is supported by Tomcat in the meantime, but not at the time when I wrote this blog entry (July 2006). About the signing of the applet -- yes, there's a couple of dialogs that are shown that seem pretty confusing to me too....

Posted by Geertjan on September 27, 2007 at 02:27 AM PDT #

Hi,
I am having problem related to applet embed in html.

My problem is , I am having applet application,
now Embedding an Applet in a Web Application ,It is giving problem while parsing xml file inside Applet that is embedded in a Web Application.but it works fine directly run as applet.I think it is path issue in a Web Application.

Posted by Vasu Reddy on December 04, 2008 at 01:41 AM PST #

Post a Comment:

Name:
E-Mail:
URL:

Your Comment:

HTML Syntax: NOT allowed