db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Olav Sandstaa <Olav.Sands...@Sun.COM>
Subject Re: jdk16 and suite derbyall - 128 failures
Date Fri, 26 May 2006 22:34:51 GMT
Daniel John Debrunner wrote:
> Olav Sandstaa wrote:
>   
>> I think I have found what causes the Nist tests to fail when running
>> derbyall with jdk16. The Nist tests started to fail after DERBY-930
>> (Add support for autoloading of Derby client drivers) was check in.
>>
>>     
> [snipped - good investigation work]
>
>   
>> When the Class.forName("com.ibm.db2.jcc.DB2Driver") is executed (and
>> the DB2 driver is actually in the class path) it seems to call some
>> methods that happens to be defined by any JDBC driver (see also the
>> comment in the code). The class loader seems to touch derby.jar to try
>> to find these methods, and this makes the embedded driver to
>> "automagically" be loaded. And loading the embedded driver also
>> "automagically" attempts to boot an embedded Derby. Unfortunately (or
>> fortunately?) at this time the Derby properties has not been set for
>> defining an embedded Derby and the booting of Derby fails (silently).
>>     
>
> I'm a little lost as to what you are describing here. What do you mean
> when you say "attempts to boot an embedded Derby"? Loading the embedded
> driver will always loaded the emebdded derby engine, unless it's already
> booted. That's the function of the driver.
>
> Then why does the driver boot fail? No properties are required to boot
> the derby engine so maybe the auto-loading is broken in some way?
>   

It seems like I was a bit lost here too :-( . After having looked a bit 
more into the code for booting the engine it seems like I followed a 
null pointer and ended up with a wrong conclusion. In the FileMonitor 
class there is a variable named home of type File. When the Nist tests 
runs correctly the home variable contains the directory for where the 
tests should be running. In the case where the Nist tests fails the 
FileMonitor's home is a null pointer, and since this caused the loading 
of the StorageFactoryService to end up with a security exception I 
wrongly assumed the cause for the security exception being this null 
pointer. After having studied the code more carefully it is a legal 
situation for this variable to be null. All it means is that the current 
directory will be used for creating database in - I wrongly saw this as 
an indication of the engine not properly being started.

>> About an hour or two later when the first Nist test starts it also
>> requests the embedded driver to be loaded into the same VM. In the
>> code for loading the driver and booting the database the following
>> check is done (see JDBCBoot.boot()):
>>
>>     if (org.apache.derby.jdbc.InternalDriver.activeDriver() == null)
>>        {
>>            // request that the InternalDriver (JDBC) service and the
>>            // authentication service be started.
>>            //
>>            addProperty("derby.service.jdbc",
>> "org.apache.derby.jdbc.InternalDriver");
>>            addProperty("derby.service.authentication",
>> AuthenticationService.MODULE);
>>            Monitor.startMonitor(bootProperties, logging);
>>
>> The test for checking if the driver has been loaded returns a pointer
>> to the embedded driver loaded during starting of derbyall. Based on
>> this no Derby database is created (since it based on having the
>> embedded driver expect that it also must have an embedded
>> database). So the Nist tests are run with the embedded driver but no
>> embedded database. No surprise that this make the tests fail
>> eventually (with an security exception seen by the test).
>>     
>
> Loading the driver is separate from creating databases so again I'm
> confused as to what you are describing here. Does the nist suite or some
>  part of the test harness set some properties that are only used at boot
> time to create a database? Which properties are these?
>   
The property that is causing the difference in behavior depending on 
when the embedded driver is loaded is derby.system.home. There is no 
error in the driver or engine with the regards to this, it is just that 
with autoloading of the driver the value of the derby.system.home on the 
time when the driver and engine is loaded influence on whether the Nist 
tests succeeds or fails.

When the Nist tests succeeds, derby.system.home contains the name of the 
directory where the test should be run (e.g. 
/export/home/tmp/derbysuite/nist in my case). I think derby.system.home 
is set by the test harness when it starts each individual test suite.

When the Nist tests fails the embedded driver and the Derby engine is 
loaded as part of startup of derbyall (actually as part of loading the 
DB2 driver). At this time  the derby.system.home property is not set. It 
think this leads to the following happening during autoloading of the 
embedded Driver:

   * The FileMonitor's home variable gets the value null based on 
reading derby.system.home.

When the Nist tests start an hour later and they requests to get a 
database created, the initialization of the StorageFactory fails with 
the security exception since it uses the FileMonitor's home variable 
(which is null) as the directory of where to create the database. 
Without the security manager this would have succeeded, but with the 
security manager, a security exception is raised when trying to get the 
canonical path from the file system when only having the name of the 
database directory (i.e. just having "wombat" instead of 
"/export/....../wombat").

The exception raised is (see also earlier email in this thread):

java.security.AccessControlException: access denied 
(java.util.PropertyPermission user.dir read)
        at 
java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
        at 
java.security.AccessController.checkPermission(AccessController.java:546)
        at 
java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
        at 
java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1285)
        at java.lang.System.getProperty(System.java:652)
        at java.io.UnixFileSystem.resolve(UnixFileSystem.java:118)
        at java.io.File.getCanonicalPath(File.java:559)
        at 
org.apache.derby.impl.io.DirStorageFactory.doInit(DirStorageFactory.java:194)
        at 
org.apache.derby.impl.io.BaseStorageFactory.init(BaseStorageFactory.java:90)
        at 
org.apache.derby.impl.services.monitor.StorageFactoryService.privGetStorageFactoryInstance(StorageFactoryService.java:240)
        at 
org.apache.derby.impl.services.monitor.StorageFactoryService.access$400(StorageFactoryService.java:64)
        at 
org.apache.derby.impl.services.monitor.StorageFactoryService$11.run(StorageFactoryService.java:813)
        at java.security.AccessController.doPrivileged(Native Method)
        at 
org.apache.derby.impl.services.monitor.StorageFactoryService.getCanonicalServiceName(StorageFactoryService.java:807)
        at 
org.apache.derby.impl.services.monitor.BaseMonitor.findProviderAndStartService(BaseMonitor.java:1572)
        at 
org.apache.derby.impl.services.monitor.BaseMonitor.startPersistentService(BaseMonitor.java:1025)
        at 
org.apache.derby.iapi.services.monitor.Monitor.startPersistentService(Monitor.java:543)
        at 
org.apache.derby.impl.jdbc.EmbedConnection.bootDatabase(EmbedConnection.java:1591)
        at 
org.apache.derby.impl.jdbc.EmbedConnection.<init>(EmbedConnection.java:216)
        at 
org.apache.derby.impl.jdbc.EmbedConnection30.<init>(EmbedConnection30.java:72)
        at 
org.apache.derby.impl.jdbc.EmbedConnection40.<init>(EmbedConnection40.java:47)
        at 
org.apache.derby.jdbc.Driver40.getNewEmbedConnection(Driver40.java:64)
        at 
org.apache.derby.jdbc.InternalDriver.connect(InternalDriver.java:215)        
at java.sql.DriverManager.getConnection(DriverManager.java:548)
        at java.sql.DriverManager.getConnection(DriverManager.java:148)
        at org.apache.derby.impl.tools.ij.util.startJBMS(util.java:518)
        at org.apache.derby.impl.tools.ij.util.startJBMS(util.java:618)
        at 
org.apache.derby.impl.tools.ij.ConnectionEnv.init(ConnectionEnv.java:64)
        at org.apache.derby.impl.tools.ij.utilMain.<init>(utilMain.java:176)
        at 
org.apache.derby.impl.tools.ij.utilMain14.<init>(utilMain14.java:51)
        at 
org.apache.derby.impl.tools.ij.Main14.getutilMain(Main14.java:102)
        at org.apache.derby.impl.tools.ij.Main.<init>(Main.java:265)
        at org.apache.derby.impl.tools.ij.Main14.<init>(Main14.java:68)
        at org.apache.derby.impl.tools.ij.Main14.getMain(Main14.java:91)
        at org.apache.derby.impl.tools.ij.Main.mainCore(Main.java:189)
        at org.apache.derby.impl.tools.ij.Main14.main(Main14.java:55)
        at org.apache.derby.tools.ij.main(ij.java:60)
        at java.lang.Thread.run(Thread.java:619)

So basically the Nist tests fail due to the embedded driver is loaded 
before derby.system.home is set to the value that it should have for the 
test.  And this leads to the security exception when the VM trying to 
get the canonical path name for the current directory.

> Seems like we are close to solving this with your work, but maybe
> missing some information still.
>   
I hope this made a more correct explanation of why the Nist tests fails.

So how should we fix this? Any suggestions? Some ideas:

* Remove the support for autoloading of the embedded driver (Yes, Rick 
and the JDBC4 expert group have already said no to this, but I still 
think there are situations where automagic loading of the drivers is a 
bad idea)

* Change the test harness so that derby.system.home is set to a value 
that is OK for all tests suites (running with useprocess=false) early 
during initialization (before touching any JDBC driver code)

* Change the  RunSuite(?) code so that it unloads the embedded driver 
and the engine as part of the start  up  (to get rid of the autoloaded 
embedded driver)

* Change the "security manager" properties for  the  Nist tests to avoid 
the security exception when the VM tries to get the canonical path for 
the working directory.

Any preferences or suggestions for better ideas?

Thanks,
Olav

Mime
View raw message