Maven + JUnit + ClassFormatError: Absent Code attribute in method that is not native or abstract in class file

11 May
2010

Once in a while one stumbles upon an error message like this

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

This happens if your code compiles against incomplete classes, like the JavaEE6 Api and your Unit tests try to access code thats not there. JUnit will simply fail and mark the test as error, printing something like this

Tests in error: 
  initializationError(com.dominikdorn.dc.passwordReset.SimplePasswordResetServiceTest)

and the corresponding surefire text file starts like this:

-------------------------------------------------------------------------------
Test set: com.dominikdorn.dc.passwordReset.SimplePasswordResetServiceTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.022 sec <<< FAILURE!
initializationError(com.dominikdorn.dc.passwordReset.SimplePasswordResetServiceTest)  Time elapsed: 0.005 sec  <<< ERROR!
java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/mail/Session
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
....

The Solution
You have to compile against real-implementations of the classes. You do that by adding those dependencies before the most generic dependency in your pom.xml

As example, we add javax.mail BEFORE javaee6-api like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<project ...>
...
    <dependencies>
 
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
</project>

If you are deploying your App on an Appserver like Glassfish or JBoss AS, leave the scope of javax.mail:mail as provided to prevent the inclusion of the jar in the final webapp.

I now list required dependencies for various Absent Code Errors I've encountered and still encountering. This post will be updated every time I solve another of these problems.

JavaMail: javax/mail/Session

1
2
3
4
5
6
7
8
9
10
11
<project ...>
...
    <dependencies>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

Servlet 3.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<project ...>
...
    <dependencies>
               <dependency>
                       <groupId>org.glassfish</groupId>
                       <artifactId>javax.servlet</artifactId>
                       <version>3.0</version>
                       <scope>provided</scope>
               </dependency>
...
    </dependencies>
....   
    <repositories>
               <!-- Required until the Servlet 3.0 API can be resolved in Central -->     
               <repository>
                       <id>Glassfish</id>
                       <name>Glassfish Maven2 Repository</name>
                       <url>http://download.java.net/maven/glassfish/</url>
               </repository>
    </repositories>
 </project>

JPA2: javax/persistence/PersistenceException

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<dependencies>...
        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>javax.persistence</artifactId>
            <version>2.0.0</version>
            <scope>provided</scope>
        </dependency>
...</dependencies>
..
<repositories>
...
    <repositories>
...
        <repository>
            <id>eclipse</id>
            <name>Eclipse Maven Repository</name>
            <url>http://www.eclipse.org/downloads/download.php?r=1&amp;nf=1&amp;file=/rt/eclipselink/maven.repo</url>
        </repository>
    </repositories>

JAX-RS: javax/ws/rs/core/UriBuilder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-core</artifactId>
            <version>1.1.5</version>
            <scope>provided</scope>
        </dependency>
<!-- for json support -->
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-json</artifactId>
            <version>1.1.5</version>
            <scope>provided</scope>
        </dependency>
<!-- for testing --> 
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-test-framework</artifactId>
            <version>1.1.5.1</version>
            <scope>test</scope>
        </dependency>

more to come soon!

4 Responses to Maven + JUnit + ClassFormatError: Absent Code attribute in method that is not native or abstract in class file

Avatar

Bartek Zdanowski

July 13th, 2010 at 14:50

Thank you for submitting the solution.
Best regards,
Bartek

Avatar

Sergio Oliveira Jr.

August 17th, 2010 at 23:14

Maven is so intuitive. Anyone could have figured out the solution to this problem. Everything just works with Maven. Great!

Avatar

Hannibal Ryon

October 22nd, 2010 at 11:29

Did you encounter this one ?

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

my dependencies are :

javax
javaee-api
jar
compile
6.0

org.glassfish.appclient
gf-client
3.0
runtime

com.sun.corba
glassfish-corba-orb
3.0.1-b002
runtime

I “need to” reference GF Client, because I’m writing a java.main() that reach glasshfish and query an EJB.
InitialContext jndiContext = new InitialContext(getJndiConfig());

JNDI config being :
env.put(Context.INITIAL_CONTEXT_FACTORY, “com.sun.enterprise.naming.impl.SerialInitContextFactory”);
env.put(“org.omg.CORBA.ORBInitialHost”, “localhost”);
env.put(“org.omg.CORBA.ORBInitialPort”, “3700”);

I “need” gf client at runtime so that SerialInitContextFactory (and callees) is found.

I tried to find a javax.ejb to place first, but haven’t.
If you have any idea, I take gladly 🙂

Thanks in advance.

Avatar

An Ha Thien Nguyen

November 2nd, 2010 at 15:43

If you cope this problem with JUnit + Eclispe, just simple re-order the library “javaee-api” to make sure that it is the last library in the classpath. The reason of this is that this library contains some interfaces that need to be implemented by some other library like Glassfish App Server, or Java Persistent API, … More details could be found here: http://forum.springsource.org/showthread.php?t=57108

Comment Form

top