On 9/12/14 7:29 AM, Rony G. Flatscher (Apache) wrote:
On 12.09.2014 15:29, Rick Hillegas wrote:
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,
Hi Rick,
thank you!
Actually, what I would be after is the following scenario: have the scirpting
language binding in
lib/ext, but derby on classpath, and everything works.
Having the scripting language binding and derby.jar on classpath works.
Having the scripting language binding in lib/ext causes classes from that jar
to load derby.jar,
then, when using DriveManager to get a connection to derby fails in this
scenario, unfortunately.
(It is in this step attempting to get a connection, where the exception is
thrown.) As a result it
is currently not possible to successfully use derby.jar (on classpath) in this
desired scenario.
I would go any length of miles to become able to do this successfully, rather
then forcing the users
of the script programs to put derby.jar in lib/ext (or have to use
-Djava.ext.dirs="..."), so would
be thankful for any insights and ideas.
---rony
P.S.: Having both, the scripting language binding and derby.jar in lib/ext
works too, but this is
not desired at all.
Hi Rony,
Can the scripting library get its hands on the class which is calling
into it? Maybe it could do something like the following to try to get
the VM to load Derby with the caller's ClassLoader:
Class.forName( "org.apache.derby.jdbc.EmbeddedDriver", true,
callingClass.getClassLoader() );
Haven't tried this. Might be a waste of your time.
Regards,
-Rick