Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Trouble With Crippled Java EE 6 APIs in Maven Repository And The Solution

DZone's Guide to

Trouble With Crippled Java EE 6 APIs in Maven Repository And The Solution

· Java Zone
Free Resource

Learn how to troubleshoot and diagnose some of the most common performance issues in Java today. Brought to you in partnership with AppDynamics.

If you try to load the javax.persistence.EntityManager class coming from standard java.net Repository you will get the following Exception:

java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/persistence/LockModeType
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)

Loading a class is needed for mocking, so the following code will not run:

@Stateless
public class EJB3WithEntityManager {
    @PersistenceContext
    EntityManager em;
    
    public void save(AnEntity ae){
        em.persist(ae);
    }
}

public class EJB3WithEntityManagerTest {
    private EJB3WithEntityManager cut;
    @Before
    public void injectEntityManager(){
        this.cut = new EJB3WithEntityManager();
        this.cut.em = mock(EntityManager.class);
    }
    @Test
    public void testSomeMethod() {
        AnEntity ae = new AnEntity();
        this.cut.save(ae);
        verify(this.cut.em,times(1)).persist(ae);
    }
}

Instead of using

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

You should use alternative (geronimo, jboss etc.) dependencies:

<dependency>
       <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-ejb_3.1_spec</artifactId>
       <version>1.0</version>
       <scope>provided</scope>
   </dependency>
   <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-jpa_2.0_spec</artifactId>
       <version>1.0</version>
       <scope>provided</scope>
   </dependency>

I cannot imagine any reasonable motivation behind removing the implementation of API-classes before uploading them into central maven repository, except political or licensing issues. This approach, however, has one advantage. You can tell whether a project is actually unit tested, or not, just by looking at the POM :-).

The whole example with workaround was checked into http://kenai.com/projects/javaee-patterns The name of the project is: MavenUnitTestWithCrippledAPI.

From http://www.adam-bien.com/roller/abien/entry/trouble_with_crippled_java_ee

Understand the needs and benefits around implementing the right monitoring solution for a growing containerized market. Brought to you in partnership with AppDynamics.

Topics:

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}