OpenJPA
  1. OpenJPA
  2. OPENJPA-1790

java.lang.VerifyError thrown when trying to commit entity.

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 2.0.1
    • Fix Version/s: 2.0.2, 2.1.0
    • Component/s: kernel
    • Labels:
      None
    • Environment:
      JDK1.6 u20, maven 2.2.1, Apache Shindig 2.0, OpenJPA 2.0.1

      Description

      Hi,

      Now I am working on OpenJPA support for Apache Shindig 2.0. There is a test case to insert some entity into backend derby database, but every time when running to commint(), there is such error thrown, unfortunately I am not to work it out, and ask here if this is a known issue? Thanks.

      I searched an issue past of: https://issues.apache.org/jira/browse/OPENJPA-91, and tried to put all openjpa related jars into jdk/jre/lib/ext, but it does not work for.

      In DOS cmd line or in eclipse IDE, I run the junit test case with jdk 1.6, both returning same error:

      -------------------------------------------------------------------------------
      Test set: org.apache.shindig.social.opensocial.jpa.spi.PersonServiceDbTest
      -------------------------------------------------------------------------------
      Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.391 sec <<< FAILURE!
      org.apache.shindig.social.opensocial.jpa.spi.PersonServiceDbTest Time elapsed: 0.438 sec <<< ERROR!
      java.lang.VerifyError: (class: org/apache/openjpa/util/java$util$concurrent$ConcurrentHashMap$11$proxy, method: remove signature: (Ljava/lang/Object;Ljava/lang/Object;)Z) Expecting to find integer on stack
      at java.lang.Class.forName0(Native Method)
      at java.lang.Class.forName(Class.java:247)
      at org.apache.openjpa.util.GeneratedClasses.loadBCClass(GeneratedClasses.java:67)
      at org.apache.openjpa.util.ProxyManagerImpl.getFactoryProxyMap(ProxyManagerImpl.java:382)
      at org.apache.openjpa.util.ProxyManagerImpl.newMapProxy(ProxyManagerImpl.java:207)
      at org.apache.openjpa.kernel.StateManagerImpl.newFieldProxy(StateManagerImpl.java:1829)
      at org.apache.openjpa.kernel.SingleFieldManager.proxy(SingleFieldManager.java:117)
      at org.apache.openjpa.kernel.StateManagerImpl.proxyFields(StateManagerImpl.java:2896)
      at org.apache.openjpa.kernel.PNonTransState.initialize(PNonTransState.java:45)
      at org.apache.openjpa.kernel.StateManagerImpl.setPCState(StateManagerImpl.java:287)
      at org.apache.openjpa.kernel.StateManagerImpl.commit(StateManagerImpl.java:1128)
      at org.apache.openjpa.kernel.BrokerImpl.endTransaction(BrokerImpl.java:2383)
      at org.apache.openjpa.kernel.BrokerImpl.afterCompletion(BrokerImpl.java:1975)
      at org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:94)
      at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1479)
      at org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:925)
      at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:560)
      at org.apache.shindig.social.opensocial.jpa.spi.SpiDatabaseBootstrap.bootstrapDatabase(SpiDatabaseBootstrap.java:186)
      at org.apache.shindig.social.opensocial.jpa.spi.SpiDatabaseBootstrap.init(SpiDatabaseBootstrap.java:85)
      at org.apache.shindig.social.opensocial.jpa.spi.PersonServiceDbTest.setup(PersonServiceDbTest.java:71)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
      at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
      at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
      at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
      at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
      at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
      at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345)
      at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009)

      1. pom.xml
        7 kB
        Kai Feng Zhang
      2. PersonServiceDbTest.java
        5 kB
        Kai Feng Zhang
      3. SpiDatabaseBootstrap.java
        27 kB
        Kai Feng Zhang
      4. persistence.xml
        6 kB
        Kai Feng Zhang
      5. concurrent_junit.patch
        6 kB
        Jody Grassel
      6. openjpa-1790.patch
        10 kB
        Jody Grassel
      7. OPENJPA-1790-2.0.x.patch
        10 kB
        Heath Thomann

        Activity

        Hide
        Kai Feng Zhang added a comment -

        I pasted the pom.xml here, would you pls check if I used the maven plugin of openjpa and dependency correctly?

        What I am running on is simple environment, just from cmd line of IDE, to run a junit test.

        And just let me know if I missed anything. Thanks.

        Show
        Kai Feng Zhang added a comment - I pasted the pom.xml here, would you pls check if I used the maven plugin of openjpa and dependency correctly? What I am running on is simple environment, just from cmd line of IDE, to run a junit test. And just let me know if I missed anything. Thanks.
        Hide
        Donald Woods added a comment -

        Try removing these 2 depends -
        <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>1.0</version>
        </dependency>
        <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.2.2</version>
        </dependency>
        And replacing this OpenJPA depend -
        <dependency>
        <groupId>org.apache.openjpa</groupId>
        <artifactId>openjpa-persistence-jdbc</artifactId>
        <version>2.0.1</version>
        </dependency>
        with the following -
        <dependency>
        <groupId>org.apache.openjpa</groupId>
        <artifactId>openjpa-all</artifactId>
        <version>2.0.1</version>
        </dependency>

        Also, can you attach your persistence.xml and/or point me to a svn location of the SPI code that you are testing, so we can look at the entities?

        Show
        Donald Woods added a comment - Try removing these 2 depends - <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.2.2</version> </dependency> And replacing this OpenJPA depend - <dependency> <groupId>org.apache.openjpa</groupId> <artifactId>openjpa-persistence-jdbc</artifactId> <version>2.0.1</version> </dependency> with the following - <dependency> <groupId>org.apache.openjpa</groupId> <artifactId>openjpa-all</artifactId> <version>2.0.1</version> </dependency> Also, can you attach your persistence.xml and/or point me to a svn location of the SPI code that you are testing, so we can look at the entities?
        Hide
        Kai Feng Zhang added a comment -

        Hi Donald,

        Thanks for so quick response. I attached files. I modified the pom.xml and changed according to your comment, but I still can see the error.

        The files are from http://svn.apache.org/repos/asf/shindig/trunk/java/samples/src/test/java/org/apache/shindig/social/opensocial/jpa/spi/, but I made some changes locally to make sure openjpa work.

        What I am testing is PersonServiceDBTest.java, but in its setup() method before running own test methods, it will call init() method on SpiDatabaseBootstrap. In this init() method, VerifyError was thrown when commit() called, in the last line of init() method.

        If I comment out lines from "entityManager.persist(buildCanonicalActivity("canonical", "1"));" to "entityManager.persist(applicationDataMap5);" in method bootstrapDatabase() in SpiDatabaseBootstrap, there will be no such VerifyError then.

        Thanks a lot for helping to look at this, and please let me know if I need provide more details.

        Show
        Kai Feng Zhang added a comment - Hi Donald, Thanks for so quick response. I attached files. I modified the pom.xml and changed according to your comment, but I still can see the error. The files are from http://svn.apache.org/repos/asf/shindig/trunk/java/samples/src/test/java/org/apache/shindig/social/opensocial/jpa/spi/ , but I made some changes locally to make sure openjpa work. What I am testing is PersonServiceDBTest.java, but in its setup() method before running own test methods, it will call init() method on SpiDatabaseBootstrap. In this init() method, VerifyError was thrown when commit() called, in the last line of init() method. If I comment out lines from "entityManager.persist(buildCanonicalActivity("canonical", "1"));" to "entityManager.persist(applicationDataMap5);" in method bootstrapDatabase() in SpiDatabaseBootstrap, there will be no such VerifyError then. Thanks a lot for helping to look at this, and please let me know if I need provide more details.
        Hide
        Kai Feng Zhang added a comment -

        Could anybody please check this problem, such as ideas of under what situation this type of error would be thrown?

        Show
        Kai Feng Zhang added a comment - Could anybody please check this problem, such as ideas of under what situation this type of error would be thrown?
        Hide
        Jody Grassel added a comment -

        Junit that reproduces the reported failure, commentary to follow.

        Show
        Jody Grassel added a comment - Junit that reproduces the reported failure, commentary to follow.
        Hide
        Jody Grassel added a comment -

        It turns out that the problem is with the way OpenJPA extends a Map type to implement Proxy and ProxyMap during runtime with the ProxyManagerImpl when the type of the map is a ConcurrentMap type, in Kai's case it is ConcurrentHashMap. ConcurrentMap defines a method "boolean replace(Object, Object)" – the very method that is in the reported Exception:

        java.lang.VerifyError: (class: org/apache/openjpa/util/java$util$concurrent$ConcurrentHashMap$11$proxy, method: remove signature: (Ljava/lang/Object;Ljava/lang/Object;)Z) Expecting to find integer on stack

        After researching more on the VerifyError, it looks like the version of remove (remove methods are considered to be setter methods by ProxyManagerImpl.isSetter()) is wrappered by ProxyManagerImpl.proxySetter(). And while it looks like proxySetter() is taking care to ensure the return type is preserved, the VerifyError suggests the bytecode is trying to return an object of type integer instead.

        I've reproduced this problem with a junit test, all that needed to be done was to initialize a relationship field of type Map with a ConcurrentHashMap, and the Exception surfaced during transaction commit:

        <testcase time="0.158" classname="org.apache.openjpa.persistence.relations.TestConcurrentMap" name="testConcurrentMap001">
        <error message="(class: org/apache/openjpa/util/java$util$concurrent$ConcurrentHashMap$1$proxy, method: remove signature: (Ljava/lang/Object;Ljava/lang/Object;)Z) Expecting to find integer on stack" type="java.lang.VerifyError">java.lang.VerifyError: (class: org/apache/openjpa/util/java$util$concurrent$ConcurrentHashMap$1$proxy, method: remove signature: (Ljava/lang/Object;Ljava/lang/Object;)Z) Expecting to find integer on stack
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:247)
        at org.apache.openjpa.util.GeneratedClasses.loadBCClass(GeneratedClasses.java:71)
        at org.apache.openjpa.util.ProxyManagerImpl.getFactoryProxyMap(ProxyManagerImpl.java:382)
        at org.apache.openjpa.util.ProxyManagerImpl.newMapProxy(ProxyManagerImpl.java:207)
        at org.apache.openjpa.kernel.StateManagerImpl.newFieldProxy(StateManagerImpl.java:1829)
        at org.apache.openjpa.kernel.SingleFieldManager.proxy(SingleFieldManager.java:117)
        at org.apache.openjpa.kernel.StateManagerImpl.proxyFields(StateManagerImpl.java:2896)
        at org.apache.openjpa.kernel.PNonTransState.initialize(PNonTransState.java:45)
        at org.apache.openjpa.kernel.StateManagerImpl.setPCState(StateManagerImpl.java:287)
        at org.apache.openjpa.kernel.StateManagerImpl.commit(StateManagerImpl.java:1128)
        at org.apache.openjpa.kernel.BrokerImpl.endTransaction(BrokerImpl.java:2383)
        at org.apache.openjpa.kernel.BrokerImpl.afterCompletion(BrokerImpl.java:1975)
        at org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:94)
        at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1479)
        at org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:925)
        at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:560)
        at org.apache.openjpa.persistence.relations.TestConcurrentMap.testConcurrentMap001(TestConcurrentMap.java:46)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at junit.framework.TestCase.runTest(TestCase.java:154)
        at org.apache.openjpa.persistence.test.AbstractPersistenceTestCase.runTest(AbstractPersistenceTestCase.java:516)

        This junit should provide a baseline with developing a fix for this problem.

        Show
        Jody Grassel added a comment - It turns out that the problem is with the way OpenJPA extends a Map type to implement Proxy and ProxyMap during runtime with the ProxyManagerImpl when the type of the map is a ConcurrentMap type, in Kai's case it is ConcurrentHashMap. ConcurrentMap defines a method "boolean replace(Object, Object)" – the very method that is in the reported Exception: java.lang.VerifyError: (class: org/apache/openjpa/util/java$util$concurrent$ConcurrentHashMap$11$proxy, method: remove signature: (Ljava/lang/Object;Ljava/lang/Object;)Z) Expecting to find integer on stack After researching more on the VerifyError, it looks like the version of remove (remove methods are considered to be setter methods by ProxyManagerImpl.isSetter()) is wrappered by ProxyManagerImpl.proxySetter(). And while it looks like proxySetter() is taking care to ensure the return type is preserved, the VerifyError suggests the bytecode is trying to return an object of type integer instead. I've reproduced this problem with a junit test, all that needed to be done was to initialize a relationship field of type Map with a ConcurrentHashMap, and the Exception surfaced during transaction commit: <testcase time="0.158" classname="org.apache.openjpa.persistence.relations.TestConcurrentMap" name="testConcurrentMap001"> <error message="(class: org/apache/openjpa/util/java$util$concurrent$ConcurrentHashMap$1$proxy, method: remove signature: (Ljava/lang/Object;Ljava/lang/Object;)Z) Expecting to find integer on stack" type="java.lang.VerifyError">java.lang.VerifyError: (class: org/apache/openjpa/util/java$util$concurrent$ConcurrentHashMap$1$proxy, method: remove signature: (Ljava/lang/Object;Ljava/lang/Object;)Z) Expecting to find integer on stack at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) at org.apache.openjpa.util.GeneratedClasses.loadBCClass(GeneratedClasses.java:71) at org.apache.openjpa.util.ProxyManagerImpl.getFactoryProxyMap(ProxyManagerImpl.java:382) at org.apache.openjpa.util.ProxyManagerImpl.newMapProxy(ProxyManagerImpl.java:207) at org.apache.openjpa.kernel.StateManagerImpl.newFieldProxy(StateManagerImpl.java:1829) at org.apache.openjpa.kernel.SingleFieldManager.proxy(SingleFieldManager.java:117) at org.apache.openjpa.kernel.StateManagerImpl.proxyFields(StateManagerImpl.java:2896) at org.apache.openjpa.kernel.PNonTransState.initialize(PNonTransState.java:45) at org.apache.openjpa.kernel.StateManagerImpl.setPCState(StateManagerImpl.java:287) at org.apache.openjpa.kernel.StateManagerImpl.commit(StateManagerImpl.java:1128) at org.apache.openjpa.kernel.BrokerImpl.endTransaction(BrokerImpl.java:2383) at org.apache.openjpa.kernel.BrokerImpl.afterCompletion(BrokerImpl.java:1975) at org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:94) at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1479) at org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:925) at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:560) at org.apache.openjpa.persistence.relations.TestConcurrentMap.testConcurrentMap001(TestConcurrentMap.java:46) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at junit.framework.TestCase.runTest(TestCase.java:154) at org.apache.openjpa.persistence.test.AbstractPersistenceTestCase.runTest(AbstractPersistenceTestCase.java:516) This junit should provide a baseline with developing a fix for this problem.
        Hide
        Jody Grassel added a comment -

        Proposed patch for OJ-1790.

        Show
        Jody Grassel added a comment - Proposed patch for OJ-1790.
        Hide
        Donald Woods added a comment -

        +1

        Show
        Donald Woods added a comment - +1
        Hide
        Michael Dick added a comment -

        Nice patch Joe, I've committed it to trunk (revision 1000292)

        Show
        Michael Dick added a comment - Nice patch Joe, I've committed it to trunk (revision 1000292)
        Hide
        Kai Feng Zhang added a comment -

        I tried the new jar with patch of Joe, it works for me, the VerifyError is gone.

        Thank you Joe and everyone.

        Show
        Kai Feng Zhang added a comment - I tried the new jar with patch of Joe, it works for me, the VerifyError is gone. Thank you Joe and everyone.
        Hide
        Heath Thomann added a comment -

        I'm providing a patch for 2.0.x which is basically a back port of the changes from trunk.

        Thanks,

        Heath

        Show
        Heath Thomann added a comment - I'm providing a patch for 2.0.x which is basically a back port of the changes from trunk. Thanks, Heath

          People

          • Assignee:
            Jody Grassel
            Reporter:
            Kai Feng Zhang
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Time Tracking

              Estimated:
              Original Estimate - 24h
              24h
              Remaining:
              Remaining Estimate - 24h
              24h
              Logged:
              Time Spent - Not Specified
              Not Specified

                Development