On 9/12/14 3:37 AM, Rony G. Flatscher (Apache) wrote:
Hi there,
tried to find this information on the Internet, but also in the derby
wiki, but was not successful so far, hence posting this question here
where hopefully those in the know can help out.
Using derby from Oracle's JDK 7 distribution I encountered a problem
and after a loong time of research, testing, trials and errors I came
up with a solution, but still do not understand the reason for the
problem!
Here is the problem:
* having a class from a jar that is placed in one of the
java.ext.dirs loading the derby JDBC (to be precise:
'org.apache.derby.jdbc.EmbeddedDriver' and then issuing a
newInstance()) from the classpath works, but the subsequent
java.sql.DriverManager.getConnection('jdbc:derby:derbyDB;create=true',props)
where 'props' is a java.util.Properties with "user1/user1" and
"password/user1", yields:
getCause(): [java.sql.SQLException: No suitable driver found for
jdbc:derby:derbyDB;create=true]
The same program works without any changes,
* if the jar-file loading the derby JDBC is not in java.ext.dirs
but on the classpath then it works
* if the jar-file and derby.jar are both in java.ext.dirs then it
works
My question is, why is this so?
(It seems to be the case that both, the Java class that loads the
derby JDBC driver and the derby JDBC driver, must use the same class
loader, either a sun.misc.Launcher$AppClassLoader or a
sun.misc.Launcher$ExtClassLoader, which is very strange as I have not
encountered a similar requirement/behaviour in any other use case in
the past years. The thread context class loader is the application
class loader which, if used, would have found derby.jar given on the
classpath.)
Is there any documentation that leads to an explanation about this
behaviour somewhere? Are there other Java infrastructures that have
such a restriction that anyone is aware of?
---
Background: I am authoring a scripting language binding for Java
(BSF4ooRexx) and moving the BSF4ooRexx jar to a Java extension
directory makes it available to all Java applications including the
JavaPlugins for browsers. All test and sample programs work in this
setup, except for the sample program that demonstrates how easy it is
to use derby via JDBC! :(
---
Thankful for any pointer, hints, links, explanations that shed some
light into this corner!
---rony
Hi Rony,
I have not been through this code recently. Maybe someone who has
studied it in detail can give you more information.
I believe that putting Derby in lib/ext will make it impossible to
unload the Derby classes when you de-register the Derby driver. This is
a feature of Derby which allows Derby-powered components (including
their class definitions) to be removed from memory when they are not
needed. If you put Derby in lib/ext, then the Derby class definitions
will be loaded by the extension class loader. Those definitions will
remain loaded until the extension class loader is garbage collected. I
don't think there is a way to remove all references to the extension
class loader and so allow it to be garbage collected.
It makes sense that Derby class loading won't work in a situation which
would prevent components from being removed.
Note that the security implications of putting Derby in lib/ext are also
serious. By default, classes loaded by the extension class loader enjoy
all permissions. You would not want a browser plugin to be able to
elevate its privileges by using Derby.
Hope this helps,
-Rick