OpenJPA
  1. OpenJPA
  2. OPENJPA-1410

Class linkage exception when creating an EMF with OpenJPA M3

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 2.0.0-M3, 2.0.0-beta, 2.0.0-beta2
    • Fix Version/s: 2.0.0-beta3
    • Component/s: validation
    • Labels:
      None
    • Environment:
      Tomcat and Glassfish, OpenJPA M3

      Description

      Posted by Seth Jackson on the user forum[1].

      It appears something was modified in OpenJPA 2.0 M3 from M2 that causes a
      LinkageError.

      In my current environment, I've tested both Glassfish and Tomcat using M2
      and M3. M2 runs without problems, but M3 throws a linkage error as follows:

      Caused by: java.lang.LinkageError: loader constraint violation: loader
      (instance of sun/misc/Launcher$AppClassLoader) previously initiated loading
      for a different type with name
      "org/apache/openjpa/conf/OpenJPAConfiguration"
      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)
      at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
      at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
      at
      org.apache.openjpa.persistence.validation.ValidationUtils.setupValidation(ValidationUtils.java:53)
      at
      org.apache.openjpa.persistence.PersistenceProviderImpl.loadValidator(PersistenceProviderImpl.java:290)
      at
      org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:97)
      at
      org.apache.openjpa.persistence.OpenJPAPersistence.createEntityManagerFactory(OpenJPAPersistence.java:128)
      at
      org.apache.openjpa.persistence.OpenJPAPersistence.createEntityManagerFactory(OpenJPAPersistence.java:111)
      at test_test.user.UserAction.execute(UserAction.java:39)

      I've already confirmed that the OpenJPA classes in question do NOT exist in
      any other JARs in the path.

      ValidationUtils.setupValidation(ValidationUtils.java:53) calls the
      OpenJPAConfiguration.getConfigurationLog(). The object being referenced is
      JDBCConfigurationImpl, which in other classes retrieves the log reference
      perfectly fine, before it gets to the offending line.

      Seth's follow up[2]:

      After further review, using Glassfish 2.1.1 I received this error message in
      the server log:

      Caused by: java.lang.LinkageError: loader constraint violation: when
      resolving method
      "org.apache.openjpa.persistence.validation.ValidationUtils.setupValidation(Lorg/apache/openjpa/conf/OpenJPAConfiguration;)Z"
      the class loader (instance of org/apache/catalina/loader/WebappClassLoader)
      of the current class,
      org/apache/openjpa/persistence/PersistenceProviderImpl, and the class loader
      (instance of sun/misc/Launcher$AppClassLoader) for resolved class,
      org/apache/openjpa/persistence/validation/ValidationUtils, have different
      Class objects for the type org/apache/openjpa/conf/OpenJPAConfiguration used
      in the signature

      So it appears to be the WebappClassLoader and the AppClassLoader are both
      loading the OpenJPAConfiguration from the same JAR file, causing the error
      when the class is trying to be resolved in this particular method.

      [1] http://n2.nabble.com/Struts-2x-OpenJPA-2-0-M3-Tomcat-or-Glassfish-tp4087312p4087312.html
      [2] http://n2.nabble.com/Struts-2x-OpenJPA-2-0-M3-Tomcat-or-Glassfish-tp4087312p4093228.html

        Issue Links

          Activity

          Hide
          Pinaki Poddar added a comment -

          Hi Jeremy,
          You write in Nabble post
          "The code in PersistenceProviderImpl that sets up validation looks like it might be suspect to classloading issues. "

          Here is the code in PersistenceProviderImpl.createEntityManagerFactory()
          // TODO - Can this be moved back to BrokerImpl.initialize()?
          // Create appropriate LifecycleEventManager
          loadValidator(_log, conf);

          Can you please describe why at the first place, we went to this unusual path for initializing/loading Validation-aware lifecycle manager plugin? This may help understanding possible resolution as per initialization of any other plugins.

          Show
          Pinaki Poddar added a comment - Hi Jeremy, You write in Nabble post "The code in PersistenceProviderImpl that sets up validation looks like it might be suspect to classloading issues. " Here is the code in PersistenceProviderImpl.createEntityManagerFactory() // TODO - Can this be moved back to BrokerImpl.initialize()? // Create appropriate LifecycleEventManager loadValidator(_log, conf); Can you please describe why at the first place, we went to this unusual path for initializing/loading Validation-aware lifecycle manager plugin? This may help understanding possible resolution as per initialization of any other plugins.
          Hide
          Nicolas Modrzyk added a comment -

          As a note I can only reproduce this on Windows, OSX and Linux are working fine.

          Show
          Nicolas Modrzyk added a comment - As a note I can only reproduce this on Windows, OSX and Linux are working fine.
          Hide
          Seth Jackson added a comment -

          I will confirm that I was encountering this on Windows XP and was not running on any other platform. Thanks.

          Show
          Seth Jackson added a comment - I will confirm that I was encountering this on Windows XP and was not running on any other platform. Thanks.
          Hide
          Mark Struberg added a comment -

          this also happens to me on Linux (Fedora 11 x86_64) if running on tomcat-6 (tried 6.0.18 and 6.0.20) but not on jetty-6!

          I'm using the openjpa-all-2.0.0-M3 package dependency.

          Caused by: java.lang.LinkageError: loader constraint violation: loader (instance of sun/misc/Launcher$AppClassLoader) previously initiated loading for a different type with name "org/apache/openjpa/conf/OpenJPAConfiguration"
          at java.lang.ClassLoader.defineClass1(Native Method)
          at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
          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:303)
          at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
          at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
          at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:316)
          at org.apache.openjpa.persistence.validation.ValidationUtils.setupValidation(ValidationUtils.java:53)
          at org.apache.openjpa.persistence.PersistenceProviderImpl.loadValidator(PersistenceProviderImpl.java:290)
          at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:97)
          at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:151)
          at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:59)
          at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:159)
          at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:71)
          at org.apache.webbeans.resource.spi.se.ResourceServiceImpl.getPersistenceUnit(ResourceServiceImpl.java:111)
          at org.apache.webbeans.resource.spi.se.ResourceServiceImpl.getPersistenceContext(ResourceServiceImpl.java:125)
          at org.apache.webbeans.resource.spi.se.ResourceServiceImpl.getResource(ResourceServiceImpl.java:59)
          at org.apache.webbeans.resource.OpenWebBeansResourcePlugin.injectResources(OpenWebBeansResourcePlugin.java:61)

          Show
          Mark Struberg added a comment - this also happens to me on Linux (Fedora 11 x86_64) if running on tomcat-6 (tried 6.0.18 and 6.0.20) but not on jetty-6! I'm using the openjpa-all-2.0.0-M3 package dependency. Caused by: java.lang.LinkageError: loader constraint violation: loader (instance of sun/misc/Launcher$AppClassLoader) previously initiated loading for a different type with name "org/apache/openjpa/conf/OpenJPAConfiguration" at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:616) 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:303) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:248) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:316) at org.apache.openjpa.persistence.validation.ValidationUtils.setupValidation(ValidationUtils.java:53) at org.apache.openjpa.persistence.PersistenceProviderImpl.loadValidator(PersistenceProviderImpl.java:290) at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:97) at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:151) at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:59) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:159) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:71) at org.apache.webbeans.resource.spi.se.ResourceServiceImpl.getPersistenceUnit(ResourceServiceImpl.java:111) at org.apache.webbeans.resource.spi.se.ResourceServiceImpl.getPersistenceContext(ResourceServiceImpl.java:125) at org.apache.webbeans.resource.spi.se.ResourceServiceImpl.getResource(ResourceServiceImpl.java:59) at org.apache.webbeans.resource.OpenWebBeansResourcePlugin.injectResources(OpenWebBeansResourcePlugin.java:61)
          Hide
          Nicolas Modrzyk added a comment - - edited

          So I removed validation since it is optional, and tried to move on.
          But stumbled against a very similar Linkage error.

          Caused by: java.lang.LinkageError: loader constraint violation: loader (instance of sun/misc/Launcher$AppClassLoader)
          previously initiated loading for a different type with name "org/apache/openjpa/kernel/BrokerFactory"
          at java.lang.ClassLoader.defineClass1(Native Method)
          at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
          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:306)
          at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
          at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
          at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
          at org.apache.openjpa.persistence.JPAFacadeHelper.toEntityManagerFactory(JPAFacadeHelper.java:70)
          at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:111)
          at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:153)
          at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:64)
          at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:150)

          Show
          Nicolas Modrzyk added a comment - - edited So I removed validation since it is optional, and tried to move on. But stumbled against a very similar Linkage error. Caused by: java.lang.LinkageError: loader constraint violation: loader (instance of sun/misc/Launcher$AppClassLoader) previously initiated loading for a different type with name "org/apache/openjpa/kernel/BrokerFactory" at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:620) 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:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276) at java.lang.ClassLoader.loadClass(ClassLoader.java:251) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319) at org.apache.openjpa.persistence.JPAFacadeHelper.toEntityManagerFactory(JPAFacadeHelper.java:70) at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:111) at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:153) at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:64) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:150)
          Hide
          Nicolas Modrzyk added a comment -

          For those of use that do not need an agent and a validator, commenting out those two lines in PersistenceProviderImpl:
          //loadAgent(factory);
          //loadValidator(factory);

          fixes the bad behavior.
          It looks like the factory is loaded in some different classloader and then clashes only when calling a method on it.

          Making a working jar file available using only the svn rev and the fix above, to people who needs it:
          http://www.intalio.org/public/maven2/org/apache/openjpa/openjpa-all/2.0.0-svn-910423/openjpa-all-2.0.0-svn-910423.jar

          Show
          Nicolas Modrzyk added a comment - For those of use that do not need an agent and a validator, commenting out those two lines in PersistenceProviderImpl: //loadAgent(factory); //loadValidator(factory); fixes the bad behavior. It looks like the factory is loaded in some different classloader and then clashes only when calling a method on it. Making a working jar file available using only the svn rev and the fix above, to people who needs it: http://www.intalio.org/public/maven2/org/apache/openjpa/openjpa-all/2.0.0-svn-910423/openjpa-all-2.0.0-svn-910423.jar
          Hide
          Christopher Davies added a comment -

          I tried this new Jar by Nicolas but I get the same issue, I have no other JPA API in my path and I went so far as to reboot my machine. I was using OpenJPA 1.2.1 and now trying to switch to 2.0.0Beta.

          Using Win7. Here is my stack trace.

          20/02/2010 9:19:26 PM org.apache.catalina.core.StandardContext listenerStart
          SEVERE: Exception sending context initialized event to listener instance of class com.trm.app.listeners.StartupServletListener
          java.lang.LinkageError: loader constraint violation: loader (instance of sun/misc/Launcher$AppClassLoader) previously initiated loading for a different type with name "org/apache/openjpa/conf/OpenJPAConfiguration"
          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)
          at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
          at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
          at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
          at org.apache.openjpa.persistence.validation.ValidationUtils.setupValidation(ValidationUtils.java:53)
          at org.apache.openjpa.persistence.PersistenceProviderImpl.loadValidator(PersistenceProviderImpl.java:316)
          at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:100)
          at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:151)
          at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:62)
          at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:150)
          at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:70)

          Show
          Christopher Davies added a comment - I tried this new Jar by Nicolas but I get the same issue, I have no other JPA API in my path and I went so far as to reboot my machine. I was using OpenJPA 1.2.1 and now trying to switch to 2.0.0Beta. Using Win7. Here is my stack trace. 20/02/2010 9:19:26 PM org.apache.catalina.core.StandardContext listenerStart SEVERE: Exception sending context initialized event to listener instance of class com.trm.app.listeners.StartupServletListener java.lang.LinkageError: loader constraint violation: loader (instance of sun/misc/Launcher$AppClassLoader) previously initiated loading for a different type with name "org/apache/openjpa/conf/OpenJPAConfiguration" 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) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) at org.apache.openjpa.persistence.validation.ValidationUtils.setupValidation(ValidationUtils.java:53) at org.apache.openjpa.persistence.PersistenceProviderImpl.loadValidator(PersistenceProviderImpl.java:316) at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:100) at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:151) at org.apache.openjpa.persistence.PersistenceProviderImpl.createEntityManagerFactory(PersistenceProviderImpl.java:62) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:150) at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:70)
          Hide
          Jose Lucea added a comment -

          Hi. I also tried the jar getting the same problem. Christophe, eventually,
          did you make it work?

          Show
          Jose Lucea added a comment - Hi. I also tried the jar getting the same problem. Christophe, eventually, did you make it work?
          Hide
          Jeremy Bauer added a comment -

          I was able to reproduce this problem on Tomcat 6.0.20, but not Glassfish 3. I don't know if OpenJPA 2.0 can be made to work with Glassfish 2.x since that level of server is Java EE 5 and OpenJPA 2.0 is uses the JPA 2.0 API, which is Java EE 6 technology. Glassfish provides its own JPA 1.0 persistence library and it may collide with the JPA 2.0 persistence library required for OpenJPA 2.0. The exception doesn't point to that type of issue though. And the app looks to be application managed so the 2.0 library may be overriding the 1.0 library without ill effects to the container.

          Tomcat 6 also includes JPA 1.0 persistence API classes, but only a small subset. That could causing the same type of API collision issue on that platform. But, again, the failure doesn't indicate this to be the problem. I'll continue to debug the issue further and provide a fix, if possible.

          Show
          Jeremy Bauer added a comment - I was able to reproduce this problem on Tomcat 6.0.20, but not Glassfish 3. I don't know if OpenJPA 2.0 can be made to work with Glassfish 2.x since that level of server is Java EE 5 and OpenJPA 2.0 is uses the JPA 2.0 API, which is Java EE 6 technology. Glassfish provides its own JPA 1.0 persistence library and it may collide with the JPA 2.0 persistence library required for OpenJPA 2.0. The exception doesn't point to that type of issue though. And the app looks to be application managed so the 2.0 library may be overriding the 1.0 library without ill effects to the container. Tomcat 6 also includes JPA 1.0 persistence API classes, but only a small subset. That could causing the same type of API collision issue on that platform. But, again, the failure doesn't indicate this to be the problem. I'll continue to debug the issue further and provide a fix, if possible.
          Hide
          Donald Woods added a comment -

          In Catalina -
          src/main/java/org/apache/catalina/core/DefaultInstanceManager.processAnnotations()
          ...
          } else if (field.isAnnotationPresent(PersistenceContext.class))

          { PersistenceContext annotation = field.getAnnotation(PersistenceContext.class); lookupFieldResource(context, instance, field, annotation.name()); }

          else if (field.isAnnotationPresent(PersistenceUnit.class))

          { PersistenceUnit annotation = field.getAnnotation(PersistenceUnit.class); lookupFieldResource(context, instance, field, annotation.name()); }

          ...

          Show
          Donald Woods added a comment - In Catalina - src/main/java/org/apache/catalina/core/DefaultInstanceManager.processAnnotations() ... } else if (field.isAnnotationPresent(PersistenceContext.class)) { PersistenceContext annotation = field.getAnnotation(PersistenceContext.class); lookupFieldResource(context, instance, field, annotation.name()); } else if (field.isAnnotationPresent(PersistenceUnit.class)) { PersistenceUnit annotation = field.getAnnotation(PersistenceUnit.class); lookupFieldResource(context, instance, field, annotation.name()); } ...
          Hide
          Jeremy Bauer added a comment -

          Thanks, Donald. ..nothing there that should cause breakage. Another concern is that Catalina includes lib/annotations-api.jar. That jar contains a few javax.persistence classes:

          javax/persistence/PersistenceContext.class
          javax/persistence/PersistenceContextType.class
          javax/persistence/PersistenceContexts.class
          javax/persistence/PersistenceProperty.class
          javax/persistence/PersistenceUnit.class
          javax/persistence/PersistenceUnits.class

          Depending on the classloader configuration, adding the JPA 2.0 spec API to the application may foul up the environment. I'm guessing not though, since the server should break even when a complete JPA 1.0 API is added to the classpath. TBD...

          Show
          Jeremy Bauer added a comment - Thanks, Donald. ..nothing there that should cause breakage. Another concern is that Catalina includes lib/annotations-api.jar. That jar contains a few javax.persistence classes: javax/persistence/PersistenceContext.class javax/persistence/PersistenceContextType.class javax/persistence/PersistenceContexts.class javax/persistence/PersistenceProperty.class javax/persistence/PersistenceUnit.class javax/persistence/PersistenceUnits.class Depending on the classloader configuration, adding the JPA 2.0 spec API to the application may foul up the environment. I'm guessing not though, since the server should break even when a complete JPA 1.0 API is added to the classpath. TBD...
          Hide
          Jean-Baptiste BRIAUD - Novlog added a comment -

          I can still reproduce it using 2.0.0 beta 2 on Linux. On MacOSX it is OK.
          Using Tomcat 6.0.24 under Linux Ubuntu, JDK 1.6.0_18

          If I remove annotations-api.jar from tomcat/lib, nothing works, it explode before the servlet init().

          Show
          Jean-Baptiste BRIAUD - Novlog added a comment - I can still reproduce it using 2.0.0 beta 2 on Linux. On MacOSX it is OK. Using Tomcat 6.0.24 under Linux Ubuntu, JDK 1.6.0_18 If I remove annotations-api.jar from tomcat/lib, nothing works, it explode before the servlet init().
          Hide
          Jean-Baptiste BRIAUD - Novlog added a comment - - edited

          Found a workaround :

          0. rename tomcat/lib/annotations-api.jar to tomcat/lib/annotations-api.jar.original
          1. repackage the tomcat/lib/annotations-api.jar file by removing javax/persistence folder
          (use to rebuild jar file : jar cvfm annotations-api.jar META-INF/MANIFEST.MF -C annotation-api .)
          2. Add the following files to the tomcat/lib :
          geronimo-jpa_2.0_spec-1.0.jar
          geronimo-jta_1.1_spec-1.1.1.jar

          This will force JVM classloader to use JPA 2.0 files

          Show
          Jean-Baptiste BRIAUD - Novlog added a comment - - edited Found a workaround : 0. rename tomcat/lib/annotations-api.jar to tomcat/lib/annotations-api.jar.original 1. repackage the tomcat/lib/annotations-api.jar file by removing javax/persistence folder (use to rebuild jar file : jar cvfm annotations-api.jar META-INF/MANIFEST.MF -C annotation-api .) 2. Add the following files to the tomcat/lib : geronimo-jpa_2.0_spec-1.0.jar geronimo-jta_1.1_spec-1.1.1.jar This will force JVM classloader to use JPA 2.0 files
          Hide
          Jean-Baptiste BRIAUD - Novlog added a comment - - edited

          I'm sorry, this was not a workaround : the error is still there ...

          Show
          Jean-Baptiste BRIAUD - Novlog added a comment - - edited I'm sorry, this was not a workaround : the error is still there ...
          Hide
          Jean-Baptiste BRIAUD - Novlog added a comment -

          I tested with Tomcat via our IDE but also directly with Tomcat, deloying by hand to ensure the IDE classpath will not interfere.
          It is confirmed : it doesn't work.

          Show
          Jean-Baptiste BRIAUD - Novlog added a comment - I tested with Tomcat via our IDE but also directly with Tomcat, deloying by hand to ensure the IDE classpath will not interfere. It is confirmed : it doesn't work.
          Hide
          Jeremy Bauer added a comment -

          I found that this problem is not related to loading bean validation. Instead, it is a problem with the OpenJPA enhancer. When running with Sun JDK, OpenJPA's dynamic enhancer kicks in by default. This is flubbing up the classloader. A simple workaround is to do the enhancement at build time and add this property to your persistence.xml to shut off the dynamic enhancer:

          <property name="openjpa.DynamicEnhancementAgent" value="false"/>

          I also tried OpenJPA's runtime enhancer (now turned off by default in OpenJPA 2.0) and hit the same problem. So it looks to be a general classloader-related problem when using OpenJPA's runtime enhancer running under Catalina (Tomcat & Glassfish). I have dug into the problem yet, though.

          FYI - To simplify usage of OpenJPA 2.0 you can simply include openjpa-all-2.0.0-beta2.jar in the WEB-APP/lib directory of your application. That jar contains all the dependencies necessary to use OpenJPA 2.0.

          I have not tried to configure Tomcat to use the agent-based enhancer. I'll give that a try and post the result. I suspect that I'll see the same problem though. Please let me know if the workaround above gets you around the exception.

          Show
          Jeremy Bauer added a comment - I found that this problem is not related to loading bean validation. Instead, it is a problem with the OpenJPA enhancer. When running with Sun JDK, OpenJPA's dynamic enhancer kicks in by default. This is flubbing up the classloader. A simple workaround is to do the enhancement at build time and add this property to your persistence.xml to shut off the dynamic enhancer: <property name="openjpa.DynamicEnhancementAgent" value="false"/> I also tried OpenJPA's runtime enhancer (now turned off by default in OpenJPA 2.0) and hit the same problem. So it looks to be a general classloader-related problem when using OpenJPA's runtime enhancer running under Catalina (Tomcat & Glassfish). I have dug into the problem yet, though. FYI - To simplify usage of OpenJPA 2.0 you can simply include openjpa-all-2.0.0-beta2.jar in the WEB-APP/lib directory of your application. That jar contains all the dependencies necessary to use OpenJPA 2.0. I have not tried to configure Tomcat to use the agent-based enhancer. I'll give that a try and post the result. I suspect that I'll see the same problem though. Please let me know if the workaround above gets you around the exception.
          Hide
          Jeremy Bauer added a comment -

          Oddly, I'm also seeing the "fallback" runtime enhancer start up. That is causing the same types of classloading type exceptions as the dynamic enhancer. I could swear that it was disabled in 2.0. You may also need to add this property as well to disable that enhancer:

          <property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/>

          With both of these enhancers disabled, you'll get a reasonable exception/error message if your classes were not build time enhanced. Something to the tune of...

          org.apache.openjpa.persistence.ArgumentException: This configuration disallows runtime optimization, but the following listed types were not enhanced at build time or at class load time with a javaagent: "[class my.Class]".

          Show
          Jeremy Bauer added a comment - Oddly, I'm also seeing the "fallback" runtime enhancer start up. That is causing the same types of classloading type exceptions as the dynamic enhancer. I could swear that it was disabled in 2.0. You may also need to add this property as well to disable that enhancer: <property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/> With both of these enhancers disabled, you'll get a reasonable exception/error message if your classes were not build time enhanced. Something to the tune of... org.apache.openjpa.persistence.ArgumentException: This configuration disallows runtime optimization, but the following listed types were not enhanced at build time or at class load time with a javaagent: " [class my.Class] ".
          Hide
          Jeremy Bauer added a comment -

          This can of worms is still open... getting closer though. I do not see the same classloading failures when running Tomcat with the agent-based enhancer. However, the entity classes in my web app are not being enhanced by the enhancer. If I flip on the runtime enhancer with this configuration via:

          <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>

          the subclassing runtime enhancer now works. (go figure)

          Similar to the agent-based enhancer, the dynamic enhancer gets loaded by the system classloader. This is problematic under a normal Tomcat config since the OpenJPA library has already been loaded by the web app classloader or the common classloader (if OpenJPA is provided as a common/shared lib). After the dynamic agent loads OpenJPA into the system classloader, class redefinition/linkage exceptions arise.

          Show
          Jeremy Bauer added a comment - This can of worms is still open... getting closer though. I do not see the same classloading failures when running Tomcat with the agent-based enhancer. However, the entity classes in my web app are not being enhanced by the enhancer. If I flip on the runtime enhancer with this configuration via: <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/> the subclassing runtime enhancer now works. (go figure) Similar to the agent-based enhancer, the dynamic enhancer gets loaded by the system classloader. This is problematic under a normal Tomcat config since the OpenJPA library has already been loaded by the web app classloader or the common classloader (if OpenJPA is provided as a common/shared lib). After the dynamic agent loads OpenJPA into the system classloader, class redefinition/linkage exceptions arise.
          Hide
          Jeremy Bauer added a comment -

          I committed a change under rev 924395 that disables the dynamic enhancer if the OpenJPA instrumentation factory is not loaded by the system classloader. In a multi-tier classloader environment (Tomcat, JEE app server, etc.) the OpenJPA jar was being loaded by the container classloader and then loaded a second time into the system classloader (as an agent). This lead to linkage issues since OpenJPA classes were loaded from multiple loaders and there ended up being a mix of classes in the execution path.

          After correcting this issue, the subclassing enhancer is working again (but that has its own set of deficiencies and is not recommended) - but agent-based enhancement (-javaagent:...) is not. This is not a result of my change, there is some other issue. I plan on looking into that next.

          As of rev 924395 the openjpa.DynamicEnhancementAgent=false property should no longer be required, but build time enhancement of entities may still be necessary.

          Show
          Jeremy Bauer added a comment - I committed a change under rev 924395 that disables the dynamic enhancer if the OpenJPA instrumentation factory is not loaded by the system classloader. In a multi-tier classloader environment (Tomcat, JEE app server, etc.) the OpenJPA jar was being loaded by the container classloader and then loaded a second time into the system classloader (as an agent). This lead to linkage issues since OpenJPA classes were loaded from multiple loaders and there ended up being a mix of classes in the execution path. After correcting this issue, the subclassing enhancer is working again (but that has its own set of deficiencies and is not recommended) - but agent-based enhancement (-javaagent:...) is not. This is not a result of my change, there is some other issue. I plan on looking into that next. As of rev 924395 the openjpa.DynamicEnhancementAgent=false property should no longer be required, but build time enhancement of entities may still be necessary.
          Hide
          Jeremy Bauer added a comment -

          Experimentation and a quick search for similar issues is showing that use of the OpenJPA's agent enhancer with Tomcat never worked?!? The agent gets tied to the base class loader and enhances classes available to that loader at startup. Each app has their own lazily instantiated class loader. Enhancement has already taken place by the time those loaders get instantiated. This looked like a regression, but it it is actually a separate and much larger issue than the one raised in this JIRA. I will not pursue that issue at this time.

          Please verify that you no longer see the original problem/exception with latest 2.0 build. If you were relying on runtime enhancement you will need to re-enable it by specifying:

          <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>

          A more recommended solution is to enhance your entities and build time.

          Show
          Jeremy Bauer added a comment - Experimentation and a quick search for similar issues is showing that use of the OpenJPA's agent enhancer with Tomcat never worked?!? The agent gets tied to the base class loader and enhances classes available to that loader at startup. Each app has their own lazily instantiated class loader. Enhancement has already taken place by the time those loaders get instantiated. This looked like a regression, but it it is actually a separate and much larger issue than the one raised in this JIRA. I will not pursue that issue at this time. Please verify that you no longer see the original problem/exception with latest 2.0 build. If you were relying on runtime enhancement you will need to re-enable it by specifying: <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/> A more recommended solution is to enhance your entities and build time.
          Hide
          Jean-Baptiste BRIAUD - Novlog added a comment - - edited

          I confirm the problem is solved by adding that 2 properties.
          By the way, we were enhancing at build-time.

          <property name="openjpa.DynamicEnhancementAgent" value="false"/>
          <property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/>

          I still don't understand how it worked on Mac plateform and not on Linux...

          Show
          Jean-Baptiste BRIAUD - Novlog added a comment - - edited I confirm the problem is solved by adding that 2 properties. By the way, we were enhancing at build-time. <property name="openjpa.DynamicEnhancementAgent" value="false"/> <property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/> I still don't understand how it worked on Mac plateform and not on Linux...
          Hide
          Donald Woods added a comment -

          Jean-Baptiste BRIAUD confirmed the patch works and allows built time enhanced entities to work on Tomcat, since the agent enhancer is not being incorrectly loaded.

          Opened OPENJPA-1590 to track the remaining issue of the agent enhancer not working with Tomcat.

          Show
          Donald Woods added a comment - Jean-Baptiste BRIAUD confirmed the patch works and allows built time enhanced entities to work on Tomcat, since the agent enhancer is not being incorrectly loaded. Opened OPENJPA-1590 to track the remaining issue of the agent enhancer not working with Tomcat.
          Hide
          Seth Jackson added a comment -

          Using the latest available OpenJPA 2.0.0 Beta 2, Tomcat 6, Java 1.5, and Windows XP:

          Persistence.XML:
          <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>

          Using ANT to run PCEnhancerTask at build time:

          <taskdef name="openjac" classname="org.apache.openjpa.ant.PCEnhancerTask">
          <classpath refid="classpath"/>
          </taskdef>
          <openjac>
          <classpath refid="classpath"/>
          <config propertiesfile="./src/META-INF/persistence.xml"/>
          </openjac>

          Upon building, I receiving the message: "No targets given. Running on all classes in your persistence classes list..."

          Confirmed all entities are in the persistence XML.

          Deploy WAR to Tomcat. Started Tomcat and navigated to web page. Clicked button that attempted to retrieve an entity from the database and the following exception occurred:

          c:\tomcat\temp\org.apache.openjpa.enhance.InstrumentationFactory3419745326061675422.jar was created and it may not get cleaned up properly.
          java.lang.ClassNotFoundException: org.apache.openjpa.enhance.InstrumentationFactory
          at java.net .URLClassLoader$1.run(URLClassLoader.java:200)
          at java.security.AccessController.doPrivileged(Natuve Method)
          at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
          at java.lang.ClassLoader.loadClass(ClassLoader.java:303)
          at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
          ...SNIP
          at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:348)

          After this, all OpenJPA queries immediately throw QueryTimeoutException, even though I have javax.persistence.query.timeout set to 0 in the persistence.XML.

          Still unable to use OpenJPA 2.0 on Tomcat.

          I apologize ahead of time, I had to hand type this out as the error in on a separate PC.

          Show
          Seth Jackson added a comment - Using the latest available OpenJPA 2.0.0 Beta 2, Tomcat 6, Java 1.5, and Windows XP: Persistence.XML: <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/> Using ANT to run PCEnhancerTask at build time: <taskdef name="openjac" classname="org.apache.openjpa.ant.PCEnhancerTask"> <classpath refid="classpath"/> </taskdef> <openjac> <classpath refid="classpath"/> <config propertiesfile="./src/META-INF/persistence.xml"/> </openjac> Upon building, I receiving the message: "No targets given. Running on all classes in your persistence classes list..." Confirmed all entities are in the persistence XML. Deploy WAR to Tomcat. Started Tomcat and navigated to web page. Clicked button that attempted to retrieve an entity from the database and the following exception occurred: c:\tomcat\temp\org.apache.openjpa.enhance.InstrumentationFactory3419745326061675422.jar was created and it may not get cleaned up properly. java.lang.ClassNotFoundException: org.apache.openjpa.enhance.InstrumentationFactory at java.net .URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Natuve Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:303) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) ... SNIP at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:348) After this, all OpenJPA queries immediately throw QueryTimeoutException, even though I have javax.persistence.query.timeout set to 0 in the persistence.XML. Still unable to use OpenJPA 2.0 on Tomcat. I apologize ahead of time, I had to hand type this out as the error in on a separate PC.
          Hide
          Jeremy Bauer added a comment -

          The code change was checked into trunk after beta2 was released. For beta2, with compile-time enhanced entities, you'll need to add these properties to your persistence.xml:

          <property name="openjpa.DynamicEnhancementAgent" value="false"/>
          <property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/>

          Show
          Jeremy Bauer added a comment - The code change was checked into trunk after beta2 was released. For beta2, with compile-time enhanced entities, you'll need to add these properties to your persistence.xml: <property name="openjpa.DynamicEnhancementAgent" value="false"/> <property name="openjpa.RuntimeUnenhancedClasses" value="unsupported"/>
          Hide
          Seth Jackson added a comment -

          Confirmed. Modified persistence XML properties and my previous error is gone. Thank you and good work!

          Show
          Seth Jackson added a comment - Confirmed. Modified persistence XML properties and my previous error is gone. Thank you and good work!
          Hide
          Jeremy Bauer added a comment -

          That is great news. Thanks for verifying!

          Show
          Jeremy Bauer added a comment - That is great news. Thanks for verifying!

            People

            • Assignee:
              Jeremy Bauer
              Reporter:
              Jeremy Bauer
            • Votes:
              2 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development