OpenJPA
  1. OpenJPA
  2. OPENJPA-758

OpenJPA doesn't find ValueHandlers with an applicable class loader

    Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Blocker Blocker
    • Resolution: Fixed
    • Affects Version/s: 1.0.3, 1.2.2, 2.0.0, 2.1.1, 2.2.0
    • Fix Version/s: 1.0.5, 1.2.3, 2.0.3, 2.1.2, 2.2.0
    • Component/s: None
    • Labels:
      None
    • Environment:
      WebSphere 6.1, any other, 1.0.3 and probably all existing others

      Description

      We are working with ValueHandlers for enterprise applications that
      will be deployed on WebSphere, currently 6.1.0.19. We believe that the
      current OpenJPA implementation has made a less than stellar choice in
      how to load value handlers, and suggest a change

      ValueHandlers are naturally (or so we find) specific for certain value
      types, that are often dependent on the semantics of your business, and
      thus are part of the application, in some way bundled in the ear you
      are deploying. We do unit testing out of the container with OpenJPA
      1.0.3, and everything works like a charm.

      When we deploy on WebSphere however, nothing works. OpenJPA does not
      find our value handlers.
      Luckily OpenJPA is open source , so we found with certainty that
      the reason is that OpenJPA tries to load the value handler with the
      class loader that loaded the meta information for the property. The
      class of that object is part of OpenJPA, and inside WebSphere, OpenJPA
      is loaded with a class loader that has no access to the application
      code, the code in the ear. So, ClassNotFoundException. Bummer.

      The long term solution, we believe, is not to use the classloader
      associated with the meta information for the property (i.e., the
      OpenJPA class loader), but instead the class loader of the entity for
      which we are working (which is also reachable via the parameters of
      the method that does the loading). Using the class loader of the
      actual value we want to handle is not an option, since the value can
      be null. The entity however is normally also part of the application,
      the ear, and cannot be null.

        Issue Links

          Activity

          Transition Time In Source Status Execution Times Last Executer Last Execution Date
          Open Open Resolved Resolved
          1202d 46m 1 Heath Thomann 15/Feb/12 15:54
          Heath Thomann made changes -
          Link This issue relates to OPENJPA-2133 [ OPENJPA-2133 ]
          Hide
          garpinc added a comment -

          I still have this issue in 2.2.0 using the following code path:

          JavaTypes.classForName(String, ClassMetaData, Class<?>, ValueMetaData, ClassLoader, boolean) line: 272
          JavaTypes.classForName(String, ClassMetaData, Class<?>, ValueMetaData, ClassLoader) line: 231
          JavaTypes.classForName(String, ValueMetaData, ClassLoader) line: 203
          MappingRepository.namedStrategy(FieldMapping, boolean) line: 580

          I think this mustExist should always be false

          Show
          garpinc added a comment - I still have this issue in 2.2.0 using the following code path: JavaTypes.classForName(String, ClassMetaData, Class<?>, ValueMetaData, ClassLoader, boolean) line: 272 JavaTypes.classForName(String, ClassMetaData, Class<?>, ValueMetaData, ClassLoader) line: 231 JavaTypes.classForName(String, ValueMetaData, ClassLoader) line: 203 MappingRepository.namedStrategy(FieldMapping, boolean) line: 580 I think this mustExist should always be false
          Hide
          Francois added a comment -

          Hi, I wrote a custom Strategy and ran into this class loading issue.

          I checked out version 2.2.0.

          I found that by adding ‘false’ to the call to getClassLoaderAction inside method:
          protected FieldStrategy namedStrategy(FieldMapping field, boolean installHandlers)
          of class:
          org.apache.openjpa.jdbc.meta.MappingRepository
          my class was able to be loaded:

          Class<?> c = JavaTypes.classForName(name, field,
          AccessController.doPrivileged(
          J2DoPrivHelper.getClassLoaderAction(FieldStrategy.class)), false);

          The boolean parameter for ‘mustExist’ should be false in order for issue OpenJPA 758 to get taken into consideration and find the correct class loader in JavaTypes.classForName method .
          I would have saved a lot of time if I found this post sooner though...

          Show
          Francois added a comment - Hi, I wrote a custom Strategy and ran into this class loading issue. I checked out version 2.2.0. I found that by adding ‘false’ to the call to getClassLoaderAction inside method: protected FieldStrategy namedStrategy(FieldMapping field, boolean installHandlers) of class: org.apache.openjpa.jdbc.meta.MappingRepository my class was able to be loaded: Class<?> c = JavaTypes.classForName(name, field, AccessController.doPrivileged( J2DoPrivHelper.getClassLoaderAction(FieldStrategy.class)), false); The boolean parameter for ‘mustExist’ should be false in order for issue OpenJPA 758 to get taken into consideration and find the correct class loader in JavaTypes.classForName method . I would have saved a lot of time if I found this post sooner though...
          Heath Thomann made changes -
          Status Open [ 1 ] Resolved [ 5 ]
          Resolution Fixed [ 1 ]
          Heath Thomann made changes -
          Fix Version/s 1.0.5 [ 12313777 ]
          Fix Version/s 1.2.3 [ 12314517 ]
          Fix Version/s 2.0.3 [ 12317143 ]
          Fix Version/s 2.1.2 [ 12317142 ]
          Fix Version/s 2.2.0 [ 12315910 ]
          Affects Version/s 2.1.1 [ 12316191 ]
          Affects Version/s 2.0.0 [ 12314019 ]
          Affects Version/s 1.2.2 [ 12313681 ]
          Affects Version/s 2.2.0 [ 12315910 ]
          Hide
          Harald Wellmann added a comment -

          I ran into the same issue working with OpenJPA 2.1.0 on OSGi, using Aries JPA 0.3 and Equinox 3.7.0. OpenJPA has to use the persistence bundle classloader instead of its own bundle classloader to load ValueHandlers. Looking at the attached patch and comparing it to the code in MetaDataRepository.loadPersistentTypesInternal for loading entity classes from user bundles, I believe this patch would also solve the problem for OSGi.

          Show
          Harald Wellmann added a comment - I ran into the same issue working with OpenJPA 2.1.0 on OSGi, using Aries JPA 0.3 and Equinox 3.7.0. OpenJPA has to use the persistence bundle classloader instead of its own bundle classloader to load ValueHandlers. Looking at the attached patch and comparing it to the code in MetaDataRepository.loadPersistentTypesInternal for loading entity classes from user bundles, I believe this patch would also solve the problem for OSGi.
          Heath Thomann made changes -
          Attachment OPENJPA-758-1.2.x.patch [ 12486632 ]
          Heath Thomann made changes -
          Field Original Value New Value
          Assignee Heath Thomann [ jpaheath ]
          Hide
          Kevin Sutter added a comment -

          Just to add another Nabble reference for this same problem.

          http://n2.nabble.com/Using-custom-ValueHandler-td210193.html

          Looks to be the same problem, but Catalina has proposed a change in slightly different area of the code. Maybe these are in the same callstack when this problem occurs. But, we should ensure that both cases are covered when this Issue gets resolved.

          Show
          Kevin Sutter added a comment - Just to add another Nabble reference for this same problem. http://n2.nabble.com/Using-custom-ValueHandler-td210193.html Looks to be the same problem, but Catalina has proposed a change in slightly different area of the code. Maybe these are in the same callstack when this problem occurs. But, we should ensure that both cases are covered when this Issue gets resolved.
          Hide
          Kevin Sutter added a comment -

          Hi,
          Just to ensure that I have discovered the same situation that you experienced, could you validate the following?

          During my recent experimentation with ValueHandlers and FieldStrategies [1], I came across the situation that you describe in this JIRA. The classloading in question is in the namedHandler method on the MappingRepository class:

          name = Configurations.getClassName(name);
          try {
          Class c = JavaTypes.classForName(name, val,
          (ClassLoader) AccessController.doPrivileged(
          J2DoPrivHelper.getClassLoaderAction(ValueHandler.class)));

          I agree that a user-supplied class, such as a ValueHandler, should not depend on the classloader of the ValueHandler class. But, I wanted to verify that we're talking about the same area of the code.

          Thanks,
          Kevin

          [1] http://n2.nabble.com/ValueHandlers-vs-FieldStrategies-td1573427.html

          Show
          Kevin Sutter added a comment - Hi, Just to ensure that I have discovered the same situation that you experienced, could you validate the following? During my recent experimentation with ValueHandlers and FieldStrategies [1] , I came across the situation that you describe in this JIRA. The classloading in question is in the namedHandler method on the MappingRepository class: name = Configurations.getClassName(name); try { Class c = JavaTypes.classForName(name, val, (ClassLoader) AccessController.doPrivileged( J2DoPrivHelper.getClassLoaderAction(ValueHandler.class))); I agree that a user-supplied class, such as a ValueHandler, should not depend on the classloader of the ValueHandler class. But, I wanted to verify that we're talking about the same area of the code. Thanks, Kevin [1] http://n2.nabble.com/ValueHandlers-vs-FieldStrategies-td1573427.html
          Jan Dockx created issue -

            People

            • Assignee:
              Heath Thomann
              Reporter:
              Jan Dockx
            • Votes:
              1 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

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

                  Development