OpenJPA
  1. OpenJPA
  2. OPENJPA-2342

Consider modifying PCEnhancer.run to use serp.bytecode.BCClass.getDeclaredInterfaceNames instead of getDeclaredInterfaceTypes.

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.2.2
    • Fix Version/s: 2.3.0
    • Component/s: Enhance
    • Labels:
      None

      Description

      Caused by: <openjpa-2.2.2-SNAPSHOT-r422266:1446295 nonfatal general error> org.apache.openjpa.util.GeneralException: An error occurred while enhancing itemjpa.ItemJPA. Exception message: java.lang.ClassNotFoundException: org.apache.aries.proxy.weaving.WovenProxy
          at org.apache.openjpa.enhance.PCEnhancer.run(PCEnhancer.java:578)
          at org.apache.openjpa.enhance.PCClassFileTransformer.transform0(PCClassFileTransformer.java:153)
          at org.apache.openjpa.enhance.PCClassFileTransformer.transform(PCClassFileTransformer.java:126)
          at org.apache.openjpa.persistence.PersistenceProviderImpl$ClassTransformerImpl.transform(PersistenceProviderImpl.java:290)
          at org.apache.aries.jpa.container.weaving.impl.WrappingTransformer.transform(WrappingTransformer.java:80)
          at org.apache.aries.jpa.container.weaving.impl.JPAWeavingHook.weave(JPAWeavingHook.java:71)
          ... 48 more
      Caused by: java.lang.IllegalArgumentException: java.lang.ClassNotFoundException: org.apache.aries.proxy.weaving.WovenProxy
          at serp.util.Strings.toClass(Strings.java:164)
          at serp.util.Strings.toClass(Strings.java:108)
          at serp.bytecode.BCClass.getDeclaredInterfaceTypes(BCClass.java:740)
          at org.apache.openjpa.enhance.PCEnhancer.run(PCEnhancer.java:537)
          ... 53 more

      This issue occurs when the Apache Aries Proxy weaving hook gets called before the Apache Aries JPA weaving hook. Proxy weaves the class with the WovenProxy interface and adds the necessary dynamic package imports. JPA then gets called and uses PCEnhancer which, in turn, calls BCClass.getDeclaredInterfaceTypes, which ultimately calls Class.forName using the woven interface's name. The class loader is from the bundle whose class is being woven. Per the OSGi spec, dynamic imports do not take effect until after the entire weaving process is complete. Consequently, the bundle's class loader does not yet have visibility to the class.

      One solution to this, at least in the Aries case, is to order the weaving hook calls using the osgi service ranking property. However, all weaving hook services with potential conflicts may not be under the control of the same entity.

      Basically, PCEnhancer.run is using the information from BCClass to determine whether or not the class has already been woven. It's only interested in knowing if the PersistenceCapable interface is there. It seems that BCClass.getDeclaredInterfaceNames avoids the Class.forName call and could be used instead, particularly considering that only the class names are compared.

      1. openjpa-2342.patch
        0.9 kB
        Kevin Sutter

        Activity

        Hide
        Kevin Sutter added a comment -

        Nice debugging effort on this JIRA. Thanks. The change you are suggesting sounds benign. The code in this area is a little confusing, since we get access to the ClassLoader, but then never seem to use it except as a parameter for Trace logging. Even the processing in the getDeclaredInterfaceTypes() when it does the classloading doesn't use the ClassLoader from the caller.

        Since none of us know the complete history of this part and what the original intent of this processing was, I'm a little hesitant on making this change without more testing. So far, the JUnit bucket is looking good. Let me think about it a bit more and get back with you.

        I would feel more comfortable with making this change in trunk (2.3.0-SNAPSHOT) and let it go through some cycles first. Would that work for you? Thanks.

        Show
        Kevin Sutter added a comment - Nice debugging effort on this JIRA. Thanks. The change you are suggesting sounds benign. The code in this area is a little confusing, since we get access to the ClassLoader, but then never seem to use it except as a parameter for Trace logging. Even the processing in the getDeclaredInterfaceTypes() when it does the classloading doesn't use the ClassLoader from the caller. Since none of us know the complete history of this part and what the original intent of this processing was, I'm a little hesitant on making this change without more testing. So far, the JUnit bucket is looking good. Let me think about it a bit more and get back with you. I would feel more comfortable with making this change in trunk (2.3.0-SNAPSHOT) and let it go through some cycles first. Would that work for you? Thanks.
        Hide
        John Ross added a comment -

        Yes, that's fine. Thank you.

        Show
        John Ross added a comment - Yes, that's fine. Thank you.
        Hide
        Mark Struberg added a comment -

        Another option would be to use build time enhancement with the openjpa-maven-plugin. At least until there is a final solution.

        I did some hacking on the SERP part in the past and I'd say we should (long term) completely drop it and use ASM instead.
        We know how the target classes shall look like (by using a java decompiler) and it's not that complex.

        Show
        Mark Struberg added a comment - Another option would be to use build time enhancement with the openjpa-maven-plugin. At least until there is a final solution. I did some hacking on the SERP part in the past and I'd say we should (long term) completely drop it and use ASM instead. We know how the target classes shall look like (by using a java decompiler) and it's not that complex.
        Hide
        ASF subversion and git services added a comment -

        Commit 1461751 from kwsutter
        [ https://svn.apache.org/r1461751 ]

        OPENJPA-2342. Changed to use the getDeclaredInterfaceNames instead of getDeclaredInterfaceTypes. All testing is looking good and should alleviate the problem of the classloading.

        Show
        ASF subversion and git services added a comment - Commit 1461751 from kwsutter [ https://svn.apache.org/r1461751 ] OPENJPA-2342 . Changed to use the getDeclaredInterfaceNames instead of getDeclaredInterfaceTypes. All testing is looking good and should alleviate the problem of the classloading.

          People

          • Assignee:
            Kevin Sutter
            Reporter:
            John Ross
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development