On 15.09.2014 15:32, rony g. flatscher wrote:
> On 15.09.2014 15:16, Rick Hillegas wrote:
>> 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.
> Thank you for this hint.
>
> The problem is that the scripting library is in java.ext.dirs (to be 
> available to all Java apps),
> hence its classes are loaded with the extension class loader. At runtime of 
> the scripts the script
> library classes will interface with the JVM (e.g. loading classes, finding 
> and invoking methods,
> etc.), hence it is always the case that the calling class is from the script 
> library and was loaded
> with the extension class loader.
>
> If the DriverManager would use the current thread's context class loader, 
> then it should work, but
> this seems to not be the case. It seems to be the case that it only uses the 
> calling class class
> loader“and if that is the case (and not regarded as an error), then one would 
> be forced to move
> 'derby.jar' to java.ext.dirs, which for the very reasons you communicated 
> would not be desired.
>
> ---rony

In the meantime I experimented with the class 
"org.apache.derby.jdbc.EmbeddedDataSource". This
works, i.e. having the script library in java.ext.dirs and derby.jar on 
classpath!

Nevertheless, DriverManager should behave the same, so I will try to file a bug 
pointing out at the
use case and regarding it a bug that the thread's context class loader seems to 
be not invoked in
this setup.

---rony

Reply via email to