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

Reply via email to