Derby
  1. Derby
  2. DERBY-4944

Embedded Derby does not start when derby.jar is dynamically uploaded / added to the classpath

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 10.6.2.1
    • Fix Version/s: 10.8.1.2
    • Component/s: Store
    • Labels:
      None
    • Environment:
      various windows versions, jdk1.6.0 and 1.5.0
    • Issue & fix info:
      Workaround attached
    • Bug behavior facts:
      Regression, Seen in production

      Description

      Hi,

      For our workflow-system, we can use a variety of DBMS as the store engine. Derby is one of them especially popular
      for test and development purposes. During setup of our system, we allow to upload a jar file with the JDBC-Driver for the DBMS.
      In case of derby, we use the embedded mode and upload derby.jar. After that we add the jar to the repositories of our class loader
      and call

      Class drc = Class.forName("org.apache.derby.jdbc.EmbeddedDriver", true, ourclassloader);
      Driver drv = (Driver)drc.newInstance();

      this worked perfectly for many years up to version 10.6.1.0, but ceased to work in 10.6.2.1;
      i assume the unreleased future versions are affected, too

      when derby.jar is placed in the classpath manually before starting our setup, everything works fine regardless of the derby version.

      investigations lead to the following conclusion:

      • since rev. 982370 this is broken, in the immediate predecessor rev. 980035 it worked.
      • rev. 982370 in the org.apache.derby.impl.store.raw.data.BaseDataFileFactory class introduced a new method
        private static String jarClassPath(final Class cls) which tries to find the jarfile from which derby was loaded.

      it contains the following lines:

      if ( cs == null )
      return null;
      URL result = cs.getLocation();
      return result.toString();

      but in the case, when we dynamically load derby,
      cs is not null but cs.getLocation() is null. so i propose to change the line with the if to:
      ...
      if ( cs == null || cs.getLocation()==null)
      return null;
      ...

      or maybe it would be better to surround the whole body of the method with a try catch, since it is not essential, and a null
      return value is also ok?

      thank you for your efforts concerning derby at large,

      Michael

      1. BDFF.diff
        0.6 kB
        Michael Dobrovnik

        Issue Links

          Activity

          Michael Dobrovnik created issue -
          Michael Dobrovnik made changes -
          Field Original Value New Value
          Attachment BDFF.diff [ 12466220 ]
          Michael Dobrovnik made changes -
          Affects Version/s 10.6.2.1 [ 12315343 ]
          Affects Version/s 11.0.0.0 [ 12312083 ]
          Hide
          Dag H. Wanvik added a comment -

          Thanks for tracking this down and the fix, Michael! It looks good to me.

          I'll commit it after running our regression suite and back-port it to the 10.7 branch, so it would be included in an update release of 10.7 if there will be one (likely). The initial release of 10.7 is going out the door as we speak, so it will not make it there, unfortunately.

          Show
          Dag H. Wanvik added a comment - Thanks for tracking this down and the fix, Michael! It looks good to me. I'll commit it after running our regression suite and back-port it to the 10.7 branch, so it would be included in an update release of 10.7 if there will be one (likely). The initial release of 10.7 is going out the door as we speak, so it will not make it there, unfortunately.
          Dag H. Wanvik made changes -
          Assignee Dag H. Wanvik [ dagw ]
          Hide
          Dag H. Wanvik added a comment -

          Trying to make a repro, this snippet did work for me, though. Could you help me determine how
          your setup differs?

          public class Foo {
          public static void main(String[] args) throws Exception {

          URL[] urls =

          {new URL("http://myhost/mydir/derby.jar")}

          ;
          ClassLoader mycl = URLClassLoader.newInstance(urls);

          Class drc = Class.forName("org.apache.derby.jdbc.EmbeddedDriver",
          true,
          mycl);
          Driver drv = (Driver)drc.newInstance();
          Properties cp = new Properties();
          cp.setProperty("create", "true");
          Connection c = drv.connect("jdbc:derby:wombat", cp);
          c.close();
          }
          }

          In derby.log I saw:

          Loaded from http://myhost/mydir/derby.jar

          Show
          Dag H. Wanvik added a comment - Trying to make a repro, this snippet did work for me, though. Could you help me determine how your setup differs? public class Foo { public static void main(String[] args) throws Exception { URL[] urls = {new URL("http://myhost/mydir/derby.jar")} ; ClassLoader mycl = URLClassLoader.newInstance(urls); Class drc = Class.forName("org.apache.derby.jdbc.EmbeddedDriver", true, mycl); Driver drv = (Driver)drc.newInstance(); Properties cp = new Properties(); cp.setProperty("create", "true"); Connection c = drv.connect("jdbc:derby:wombat", cp); c.close(); } } In derby.log I saw: Loaded from http://myhost/mydir/derby.jar
          Hide
          Dag H. Wanvik added a comment -

          The patch passed regression tests.

          Show
          Dag H. Wanvik added a comment - The patch passed regression tests.
          Hide
          Michael Dobrovnik added a comment -

          In the meantime, a co-worker of mine also did some "independent investigations" and came to additional insight:

          we added the derby.jar to our classloader with

          classLoader.addRepository(jarfile,null);

          Changing this to

          classLoader.addRepository(jarfile,new ProtectionDomain(new CodeSource(jarfile.toURL(), new Certificate[0]), null));

          also remedied the problem. so its not important that the patch barely did not make it into 10.7

          but since the apidoc of CodeSource implies that getLocation() can return null, i think it is still a relevant patch.

          thanks for your quick reaction.

          Show
          Michael Dobrovnik added a comment - In the meantime, a co-worker of mine also did some "independent investigations" and came to additional insight: we added the derby.jar to our classloader with classLoader.addRepository(jarfile,null); Changing this to classLoader.addRepository(jarfile,new ProtectionDomain(new CodeSource(jarfile.toURL(), new Certificate [0] ), null)); also remedied the problem. so its not important that the patch barely did not make it into 10.7 but since the apidoc of CodeSource implies that getLocation() can return null, i think it is still a relevant patch. thanks for your quick reaction.
          Kathey Marsden made changes -
          Link This issue is related to DERBY-4715 [ DERBY-4715 ]
          Hide
          Kathey Marsden added a comment -

          Regression related to DERBY-4715

          Show
          Kathey Marsden added a comment - Regression related to DERBY-4715
          Kathey Marsden made changes -
          Bug behavior facts [Seen in production] [Regression, Seen in production]
          Hide
          Kathey Marsden added a comment -

          Thank you Michael.

          I don't see addRepository method in the ClassLoader or URLClassLoader API, so assume it is a custom class loader subclass. Can you describe it in a bit more detail to help us modify Dag's attempt at a reproduction, so we can get a test case?

          I wonder too is it ever possible for cls.getProtectionDomain() to return Null which might cause an NPE further up at:
          cs = cls.getProtectionDomain().getCodeSource();

          Show
          Kathey Marsden added a comment - Thank you Michael. I don't see addRepository method in the ClassLoader or URLClassLoader API, so assume it is a custom class loader subclass. Can you describe it in a bit more detail to help us modify Dag's attempt at a reproduction, so we can get a test case? I wonder too is it ever possible for cls.getProtectionDomain() to return Null which might cause an NPE further up at: cs = cls.getProtectionDomain().getCodeSource();
          Hide
          Dag H. Wanvik added a comment -

          Hi Michael,

          what Javadoc are you looking at to arrive at that conclusion? ("the apidoc of CodeSource implies that getLocation() can return null")
          Looking at the Javadoc for Java 1.6[1], I see this:

          > CodeSource#getLocation:
          >
          > public final URL getLocation()
          >
          > Returns the location associated with this CodeSource.
          >
          > Returns:
          > the location (URL).

          It seems there is no indication that the returned value could be null?

          [1] http://download.oracle.com/javase/6/docs/api/

          Show
          Dag H. Wanvik added a comment - Hi Michael, what Javadoc are you looking at to arrive at that conclusion? ("the apidoc of CodeSource implies that getLocation() can return null") Looking at the Javadoc for Java 1.6 [1] , I see this: > CodeSource#getLocation: > > public final URL getLocation() > > Returns the location associated with this CodeSource. > > Returns: > the location (URL). It seems there is no indication that the returned value could be null? [1] http://download.oracle.com/javase/6/docs/api/
          Hide
          Knut Anders Hatlen added a comment -

          The javadoc for CodeSource#implies says:

          "3. If this object's location (getLocation()) is not null, (...)"

          "Note that if this CodeSource has a null location and a null certificate chain, then it implies every other CodeSource."

          That seems to indicate that null is a valid return value.

          Show
          Knut Anders Hatlen added a comment - The javadoc for CodeSource#implies says: "3. If this object's location (getLocation()) is not null, (...)" "Note that if this CodeSource has a null location and a null certificate chain, then it implies every other CodeSource." That seems to indicate that null is a valid return value.
          Hide
          Michael Dobrovnik added a comment -

          Hi Dag,

          sorry for not being clear enough, (obviously, the pun on "implies" did not work).

          I am looking at the official javadoc you cited, but as i said: "it implies, that...", not "it states that, .."

          the apidoc for

          boolean CodeSource.implies(CodeSource)

          says: "Note that if this CodeSource has a null location..."

          Furthermore, looking into the source of java.security.CodeSource or java.lang.ClassLoader
          reveals a couple of locations where location is checked if it is null.

          Show
          Michael Dobrovnik added a comment - Hi Dag, sorry for not being clear enough, (obviously, the pun on "implies" did not work). I am looking at the official javadoc you cited, but as i said: "it implies, that...", not "it states that, .." the apidoc for boolean CodeSource.implies(CodeSource) says: "Note that if this CodeSource has a null location..." Furthermore, looking into the source of java.security.CodeSource or java.lang.ClassLoader reveals a couple of locations where location is checked if it is null.
          Hide
          Dag H. Wanvik added a comment -

          Patch committed to trunk as svn 1050000, resolving.

          Show
          Dag H. Wanvik added a comment - Patch committed to trunk as svn 1050000, resolving.
          Dag H. Wanvik made changes -
          Status Open [ 1 ] Resolved [ 5 ]
          Issue & fix info [Workaround attached, Patch Available] [Workaround attached]
          Fix Version/s 10.8.0.0 [ 12315561 ]
          Resolution Fixed [ 1 ]
          Knut Anders Hatlen made changes -
          Link This issue is duplicated by DERBY-5178 [ DERBY-5178 ]
          Rick Hillegas made changes -
          Fix Version/s 10.8.1.1 [ 12316356 ]
          Fix Version/s 10.8.1.0 [ 12315561 ]
          Rick Hillegas made changes -
          Fix Version/s 10.8.1.2 [ 12316362 ]
          Fix Version/s 10.8.1.1 [ 12316356 ]
          Hide
          Knut Anders Hatlen added a comment -

          [bulk update] Close all resolved issues that haven't been updated for more than one year.

          Show
          Knut Anders Hatlen added a comment - [bulk update] Close all resolved issues that haven't been updated for more than one year.
          Knut Anders Hatlen made changes -
          Status Resolved [ 5 ] Closed [ 6 ]
          Gavin made changes -
          Workflow jira [ 12540096 ] Default workflow, editable Closed status [ 12802886 ]

            People

            • Assignee:
              Dag H. Wanvik
              Reporter:
              Michael Dobrovnik
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development