Java EE 6, Untestable?

Standard

Trying to work something out and it just doesn’t look possible right now.

Since Java EE 6 was officially released earlier this month, I’ve been pretty jazzed about it. It represents significant leaps forward in simplicity and developer productivity.

I was so encouraged, I started a couple projects to start experimenting with what I could do with the environment.

Unfortunately when it came time to integrate automated testing, I hit a large brick wall.

It’s all well and good to have these nice testable POJOs, but many of the bugs in a system are due to misinterpreting or misunderstanding of the underlying technologies by developers just getting started or not paying attention. If you use JPA2’s persist() on an object for example, can you be sure your configuration will conclusively save the linked objects as well? This is the kind of thing we build integration tests for.

I use Maven 2 for all of my Java / Groovy project builds, and it has also been enjoying much broader support in the industry. As a result, developers are now more cognizant than ever before of their underlying dependencies. This is a Good Thing™.

The typical Maven 2 dependency on the Java EE 6 web profile APIs would look like this:

<dependency>
  <groupId>javax</groupId>
  <artifactId>javaee-web-api</artifactId>
  <version>6.0</version>
  <scope>provided</scope>
</dependency>

The jar referred to here contains all of the annotations and APIs you should need, from JPA 2 to Servlet 3. Unfortunately I can’t find any implementations to play nicely with it.

So with the API included above, you’d think it would make sense to say find a JPA implementation like EclipseLink (the default JPA 2 implementation in Glassfish 3) and include it as an embedded implementation for your unit testing. However if you include a block like this:

<dependency>
 <groupId>org.eclipse.persistence</groupId>
 <artifactId>eclipselink</artifactId>
 <version>2.0.0</version>
 <scope>test</scope>
</dependency>

You end up with your tests failing with the following exception:

java.lang.ClassFormatError: Absent Code attribute in method that is not
 native or abstract in class file javax/persistence/Persistence

It appears that in some way the EclipseLink implementation is not completely filling in the blanks in the API.

I’ve dug through the Glassfish project (it too is a Maven 2 build) and don’t have enough familiarity to draw out a nice clean implementation jar to include in my own project’s test scope… despite several attempts.

I haven’t given up, but unfortunately this has blown a couple weeks of productivity and I’m going to have to abandon my current projects in order to have something to show for all this time I’ve been spending. <sigh>

Comments extremely welcome on this one, I’d love to get past this impasse.

Advertisements

7 thoughts on “Java EE 6, Untestable?

  1. Are you sure the dependancy javaee-web-api is proving all of the APIs that you need. I can assure you EclipseLink provides all of the spec functionality and more. Based on the exception it seems you may not be getting the correct implementation of javax.persistence.Persistence from the specification APIs.

    • Hi Gordon,

      This is an excellent point, and no, I’m not 100% sure it’s providing all the APIs I need 🙂

      I _do_ know that this dependency is provided both by Netbeans when creating a Maven EE 6 project as well as by the org.codehaus.mojo.archetypes / webapp-javaee6 Maven 2 archetype so I’ve been assuming (hoping) that it is the “sanctioned” dependency that I am looking for. This however is just an assumption.

      I _also_ know that this dependency is the only one I need to build an application that deploys cleanly in Glassfish 3 using EclipseLink as the persistence implementation – and works beautifully.

      From what I’ve found out there, the exception I see when running unit tests outside Glassfish is caused by an API jar on the classpath that has an incomplete implementation on the classpath. This is actually very far from – and I absolutely do not mean to imply – that EclipseLink is in any way a deficient implementation of JPA 2 – my testing thus far has been performant and wholly functional. I believe it means simply that there is some glue that I’m missing that a proper Java EE container would have that would provide a more complete execution environment.

      My only goal at this time is to provide what seems widely claimed, and seemingly obvious – a Java EE 6 project that does automated testing using embeddable technologies like EclipseLink and a single API jar dependency to use for deployable builds inside Glassfish as well as automated tests outside Glassfish.

      I believe that this is simply a matter of getting my dependency tree right, but damned if I can find the right mix 🙂

  2. I had the same problem, but I want to share that I cracked this nut after some investigation.

    Just replace:

    javax
    javaee-api
    6.0
    provided

    …with:

    org.apache.openjpa
    openjpa-all
    2.0.0-M3
    provided

    If you have a test JPA PU, use:

    org.apache.openjpa.persistence.PersistenceProviderImpl
    com.foobar.Class1
    com.foobar.Class2

    Hope this helps, or to use a famous phrase, “it works for me” 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s