A little tip: deploying a war file on different containers / application servers can lead to different results. Although their scope widely differs, Sun has 2 offerings when it comes to deploying a war file: Sun Java System Web Server (SJWS) and Glassfish.

Well, it turns out that Glassfish replaces the entire content of the directory where the application is deployed while Sun JSWS will simply overwrite the existing files, thus leaving all other files in place. In a recent case, I had copied some properties file in that directory (after a first deployment) and was surprised to find them there after a re-deploy.

Now, I know that I’m not really supposed to mess around with files of a deployed war but I find it to be a good reminder of the sometimes not so subtle differences between containers.

Advertisements

I had mentioned in a previous blog an issue I was seeing with my web application and its use of JPA. It turns out (thanks to people on the Glassfish users mailing list) that, after a refactoring, my JPQL query was rendered wrong up by using the name of the table instead of the name of the Java entity.
So
@NamedQueries(name = "Acctoken.findAll", query = "SELECT a FROM Acctoken a")
should have been:
@NamedQuery(name = "AccessToken.findAll", query = "SELECT a FROM AccessToken a")
Simple enough but, as I had written before, the fact that it somehow was working for subsequent calls remains a mystery to me…

JavaOne’09 is now over. Lots of interesting sessions & great discussions. I loved the demo Pat Patterson made using our OAuth implementation. Marc Hadley and I had our BOF session and were pleasantly surprised to see more people than expected since it was late and in direct competition with JavaOne’s big party. Here are the slides we presented – hopefully this will encourage people to participate and help us in our quest for the ultimate identity framework!

Here’s an interesting problem I’m facing.
I have been working on a web application that I’m deploying using Glassfish. The web app leverages the Jersey framework (I really recommend it to anyone interested in RESTful development in Java). I also use the Java Persistence API to store objects in a DB. For all this, I’m using NetBeans tools to create a Persistence Unit and the entities I have to manage (from a DB schema). NetBeans also creates the appropriate mapping of the entities and their Java classes. So far so good…
For each entity, I end up with java classes that look something like this:

@Entity
@Table(name = "ACCTOKEN")
@NamedQueries({@NamedQuery(name = "Acctoken.findAll", query = "SELECT a FROM Acctoken a"),
@NamedQuery(name = "Acctoken.findById", query = "SELECT a FROM Acctoken a WHERE a.id = :id"),
@NamedQuery(name = "Acctoken.findByAcctUri", query = "SELECT a FROM Acctoken a WHERE a.acctUri = :acctUri")
/... more queries .../ })

public class AccessToken implements Serializable { /.../ }

The code above compiles fine and I can deploy the generated war file with Glassfish. However, and this is where I could use suggestions from anyone, I see a weird behaviour upon hitting one of the exposed endpoints:
The very first time I do a POST (or GET), the web application throws an exception that looks like:

Exception [TOPLINK-8034] (Oracle TopLink Essentials - 2.0.1 (Build b04-fcs (04/11/2008))):
oracle.toplink.essentials.exceptions.EJBQLException Exception Description: Error compiling
the query [Acctoken.findByAcctVal: SELECT a FROM Acctoken a WHERE a.acctVal = :acctVal].
Unknown abstract schema type [Acctoken]. at oracle.toplink.essentials.exceptions.
EJBQLException.unknownAbstractSchemaType (EJBQLException.java:494)

What’s funny is that this does not happen in any subsequent access to those URLs, the web app behaves properly. Because subsequent calls are fine I know the mapping does happen and is correct. I thus don’t really have to explicitly list the classes in the persistence.xml file and instead I have the <exclude-unlisted-classes>false</exclude-unlisted-classes> tag. However listing the classes will not help. I have verified this in both Glassfish 2.2 and Glassfish 3: same behaviour.

It really looks like Glassfish (what else?) adopts a “lazy” approach for the mapping to happen and is basically not ready for the 1st call. I already have the <load-on-startup /> tag set in my web.xml and this didn’t help.

So there it is, anyone has an idea?

<Rant>

One of the things I dislike in the Java world is the number of moving parts I sometimes have to deal with in order to get things going. For instance, as mentioned in my previous post, I often work with XML schemas. To successfully use JAXB, you have to be aware of:

  1. The Java version you’re using (Java SE 6, or 5?)
  2. The version of JAXB (is it 2.0 or 2.1?)
  3. The version of NetBeans (try 7.0 it rocks!)
  4. The OS you’re running all the above on

Depending on the various combination you have, you may need to tune things differently…

For instance the build.xml file contains information that relates to XJC’s location. Up to recently, I was successfully using the following setting on my OS X based machines:

<taskdef name=”xjc” classname=”com.sun.tools.xjc.XJCTask”>

   <classpath>
       <fileset dir=”/Applications/NetBeans/NetBeans 6.5M1.app/Contents/Resources/NetBeans/java2/modules/ext/jaxws21″ includes=”**/*.jar”/>
   </classpath>
</taskdef>

Recently I upgraded to NetBeans 7.0 (which is great btw) and updated accordingly the build.xml for my project so that it matches the new location of jaxws21:

/Applications/NetBeans/NetBeans 7.0M1.app/Contents/Resources/NetBeans/java2/modules/ext/jaxws21

 Unfortunately, I got the following error message when building my project:

taskdef class com.sun.tools.xjc.XJCTask cannot be found

 

It turns out the proper directory is now:

/Applications/NetBeans/NetBeans 7.0M1.app/Contents/Resources/NetBeans/ide10/modules/ext/jaxb

Why the move to another location? Frankly I’m not sure but I bet it has to do with this. This site (named the unofficial JAXB guide) is a great source of information if you’re working with JAXB.

</Rant>

For most projects I’ve been working on lately, I have had to implement a library or an application starting from an XML schema file. There are several ways to generate Java classes from a schema (this process is called binding a schema to a Java representation). Of course, working at SUN, I naturally started with using JAXB

A key element of this binding process is the compiler that generates those Java classes. In JAXB, this task is dedicated to XJC. In order to call XJC you can either run it from the command line or, even better, invoke it directly from your NetBeans project. To do the latter, you will need to modify or add a few files to your project: the overall build.xml of the project and a catalog.xml and a binding.xml that relates directly to the schema(s) you have to start with.

First, you need to add a new target in your build.xml file to instruct NetBeans to generate the code and where to put those classes:

    <target name=”-pre-compile”>
        <echo message=”Compiling the schemas…”/>
        <mkdir dir=”build/gen-src”/>
        <xjc catalog=”Schemas/catalog.xml” binding=”Schemas/binding.xml” destDir=”build/gen-src”>
            <schema dir=”Schemas/”>
                <include name=”*.xsd”/>
            </schema>
            <produces dir=”build/gen-src/com/sun/myproject” includes=”**/*.java”/>
        </xjc>
    </target>

Don’t forget to explicitly declare where XJC can be found. On my Mac, it would look like:

    <taskdef name=”xjc” classname=”com.sun.tools.xjc.XJCTask”>
        <classpath>
            <fileset dir=”/Applications/NetBeans/…/ext/jaxws21″ includes=”**/*.jar”/>
        </classpath>
    </taskdef>

Once this is done, you’ll need to add a catalog.xml file in the schemas directory (or elsewhere). In a nutshell you declare where other resources (like schemas your own schema may depend upon) can be found (e.g. in a local directory or online). An example of such mapping would be:

<?xml version=”1.0″ envoding=”UTF-8″?>
<catalog xmlns=”urn:oasis:names:rc:entity:xmlns:xml:catalog” prefer=”system”>
   <system systemId=”http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/xenc-schema.xsd&#8221; uri=”w3-dsig/w3-2002-12-xenc-schema.xsd”/>
   <uri name=”http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/xenc-schema.xsd&#8221; uri=”w3-dsig/w3-2002-12-xenc-schema.xsd”/>
   <system systemId=”http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd&#8221; uri=”w3-dsig/w3-2000-09-xmldsig-core-schema.xsd”/>
   <uri name=”http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd&#8221; uri=”w3-dsig/w3-2000-09-xmldsig-core-schema.xsd”/>
</catalog>

You also need, and this is the 3rd file I mentioned, to have a binding.xml file which, among many other things, describes the mapping of the schemas to be compiled with your project structure/hierarchy. For instance, you can say that the Java classes created from the schema w3-2000-09-xmldsig-core-schema.xsd should be packaged as org.w3.xmldsig. An example of such file is below:

<jxb:bindings version=”2.1″
xmlns:jxb=”http://java.sun.com/xml/ns/jaxb&#8221;
xmlns:xs=”http://www.w3.org/2001/XMLSchema&#8221;
xmlns:xjc=”http://java.sun.com/xml/ns/jaxb/xjc”&gt;

    <jxb:bindings schemaLocation=”rest-ds.xsd” node=”//xs:schema”>
        <jxb:schemaBindings>
            <jxb:package name=”com.sun.silverlining.identity”/>
        </jxb:schemaBindings>
    </jxb:bindings>

    <jxb:bindings schemaLocation=”wssecurity-200401-secext-1.0.xsd” node=”//xs:schema”>
        <jxb:schemaBindings>
            <jxb:package name=”oasis.wss.secext”/>
        </jxb:schemaBindings>
    </jxb:bindings>

    <jxb:bindings schemaLocation=”wssecurity-200401-utility-1.0.xsd” node=”//xs:schema”>
        <jxb:schemaBindings>
            <jxb:package name=”oasis.wss.utility”/>
        </jxb:schemaBindings>
    </jxb:bindings>
 
    <jxb:bindings schemaLocation=”liberty-idwsf-utility-v2.0.xsd” node=”//xs:schema”>
        <jxb:schemaBindings>
            <jxb:package name=”liberty.util”/>
        </jxb:schemaBindings>
    </jxb:bindings>

</jxb:bindings>

Don’t forget to instruct NetBeans to look for those newly generated classes. for this, in NetBeans, go to the properties of your project and look at the Sources in the Categories tab. There you should add the folder you declared in the build.xml file (in the above example: build/gen-src).

That’s it!
Building your project should now automatically generate Java classes from the schema and then build the whole project.