OpenJPA
  1. OpenJPA
  2. OPENJPA-401

UnsatisfiedLinkError in MappingToolTask when using DB2 JDBC driver

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 1.0.0
    • Fix Version/s: 1.0.1, 1.0.2, 1.1.0
    • Component/s: None
    • Labels:
      None

      Description

      The MappingToolTask's class resolver loads classes from a temporary classloader before loading them in the "normal" classloader. This can cause problems if the JDBC driver requires access to native libraries (which can only be loaded once).

      I've seen errors like this when using the DB2 JCC driver and the IBM JDK :

      [mapping] 608 persistence-tests INFO [main] openjpa.Tool - Recording mapping and schema changes.
      [mapping] java.lang.UnsatisfiedLinkError: com/ibm/jvm/Trace.initTrace([Ljava/lang/String;[Ljava/lang/String;)V
      [mapping] at com.ibm.jvm.Trace.initializeTrace(Trace.java:96)
      [mapping] at com.ibm.jvm.Trace.<clinit>(Trace.java:61)
      [mapping] at java.lang.J9VMInternals.initializeImpl(Native Method)
      [mapping] at java.lang.J9VMInternals.initialize(J9VMInternals.java:192)
      [mapping] at java.lang.Class.forNameImpl(Native Method)
      [mapping] at java.lang.Class.forName(Class.java:130)
      [mapping] at com.ibm.db2.jcc.c.o.q(o.java:550)
      [mapping] at com.ibm.db2.jcc.c.o.<clinit>(o.java:319)
      [mapping] at java.lang.J9VMInternals.initializeImpl(Native Method)
      [mapping] at java.lang.J9VMInternals.initialize(J9VMInternals.java:192)
      [mapping] at java.lang.Class.forNameImpl(Native Method)
      [mapping] at java.lang.Class.forName(Class.java:130)
      [mapping] at com.ibm.db2.jcc.DB2Driver.class$(DB2Driver.java:48)
      [mapping] at com.ibm.db2.jcc.DB2Driver.<clinit>(DB2Driver.java:51)
      [mapping] at java.lang.J9VMInternals.initializeImpl(Native Method)
      [mapping] at java.lang.J9VMInternals.initialize(J9VMInternals.java:192)
      [mapping] at java.lang.Class.forNameImpl(Native Method)
      [mapping] at java.lang.Class.forName(Class.java:163)
      [mapping] at org.apache.openjpa.jdbc.schema.DataSourceFactory.newDataSource(DataSourceFactory.java:82)

      <snip>

      Note that this does not occur with the Sun JDK (or at least I haven't hit the problem.

      A potential solution is to change the order of the classloaders used in MappingToolTask.

        Activity

        Hide
        Marc Prud'hommeaux added a comment -

        I'm reopening this because the fix was causing intermittent failures in loading metadata. E.g.:

        [mappingtool] <openjpa-1.1.0-SNAPSHOT-r420667:598829 fatal user error> org.apache.openjpa.util.MetaDataException: Type "class kodo.performance.PerfMultiA" does not have persistence metadata.
        [mappingtool] at org.apache.openjpa.jdbc.meta.MappingTool.getMapping(MappingTool.java:679)
        [mappingtool] at org.apache.openjpa.jdbc.meta.MappingTool.refresh(MappingTool.java:716)
        [mappingtool] at org.apache.openjpa.jdbc.meta.MappingTool.run(MappingTool.java:641)
        [mappingtool] at org.apache.openjpa.jdbc.meta.MappingTool.run(MappingTool.java:1072)
        [mappingtool] at org.apache.openjpa.jdbc.ant.MappingToolTask.executeOn(MappingToolTask.java:197)
        [mappingtool] at org.apache.openjpa.lib.ant.AbstractTask.execute(AbstractTask.java:172)

        I've committed revision #599178 which swaps the order in which the child loaders are added to the MultiLoaderClassResolver, which seems to fix the problem, but I don't know if it will re-introduce the original symptoms reported in the bug. Michael, can you check with this new revision to see if it still works with your DB2 native driver?

        Show
        Marc Prud'hommeaux added a comment - I'm reopening this because the fix was causing intermittent failures in loading metadata. E.g.: [mappingtool] <openjpa-1.1.0-SNAPSHOT-r420667:598829 fatal user error> org.apache.openjpa.util.MetaDataException: Type "class kodo.performance.PerfMultiA" does not have persistence metadata. [mappingtool] at org.apache.openjpa.jdbc.meta.MappingTool.getMapping(MappingTool.java:679) [mappingtool] at org.apache.openjpa.jdbc.meta.MappingTool.refresh(MappingTool.java:716) [mappingtool] at org.apache.openjpa.jdbc.meta.MappingTool.run(MappingTool.java:641) [mappingtool] at org.apache.openjpa.jdbc.meta.MappingTool.run(MappingTool.java:1072) [mappingtool] at org.apache.openjpa.jdbc.ant.MappingToolTask.executeOn(MappingToolTask.java:197) [mappingtool] at org.apache.openjpa.lib.ant.AbstractTask.execute(AbstractTask.java:172) I've committed revision #599178 which swaps the order in which the child loaders are added to the MultiLoaderClassResolver, which seems to fix the problem, but I don't know if it will re-introduce the original symptoms reported in the bug. Michael, can you check with this new revision to see if it still works with your DB2 native driver?
        Hide
        Michael Dick added a comment -

        Unfortunately I do still see the problem. I haven't re-verified that it only occurs with the IBM JDK though (I'll try that later).

        In the mean time I wrote a quick patch which adds a configuration option to disable the temporary classloader for the mappingToolTask - which might be a palatable interim solution.

        Show
        Michael Dick added a comment - Unfortunately I do still see the problem. I haven't re-verified that it only occurs with the IBM JDK though (I'll try that later). In the mean time I wrote a quick patch which adds a configuration option to disable the temporary classloader for the mappingToolTask - which might be a palatable interim solution.
        Hide
        Patrick Linskey added a comment -

        What's the status of this issue?

        Show
        Patrick Linskey added a comment - What's the status of this issue?
        Hide
        Michael Dick added a comment -

        The MappingToolTask now includes a flag which can be used to disable the temporary classloader, similarly to the PCEnhancerTask. If the flag is not specified then we'll use the temporary classloader (original behavior).

        Show
        Michael Dick added a comment - The MappingToolTask now includes a flag which can be used to disable the temporary classloader, similarly to the PCEnhancerTask. If the flag is not specified then we'll use the temporary classloader (original behavior).

          People

          • Assignee:
            Michael Dick
            Reporter:
            Michael Dick
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development