db-derby-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Johnny Kewl" <j...@kewlstuff.co.za>
Subject Re: [nbusers] Issues with Derby in customer classloader using Java 6
Date Mon, 14 Jan 2008 22:32:14 GMT

----- Original Message ----- 
From: "David Van Couvering" <david@vancouvering.com>
To: <john@kewlstuff.co.za>; "Derby Discussion" <derby-user@db.apache.org>
Sent: Monday, January 14, 2008 10:12 PM
Subject: Fwd: [nbusers] Issues with Derby in customer classloader using Java 

> Hi, Derby folks.  John is having trouble using Derby in a custom
> classloader when running in Java 6.  See the thread below.  Is this a
> known issue?  Any ideas why this might be happening?
> Thanks,
> David
> ---------- Forwarded message ----------
> From: David Van Couvering <david@vancouvering.com>
> Date: Jan 14, 2008 12:08 PM
> Subject: Re: [nbusers] == I got issues with JavaDB on 6 ==
> To: nbusers@netbeans.org
> Wow, a lot happens when you go away for the weekend :)
> it's really hard to track down what this issue is, and it looks like
> you may not be motivated to help us, Johnny,  since you already moved
> to H2 :)
> I do want to clarify a few things though, just so there is no confusion:
> - Java DB that is embedded in JDK 6 is not used automatically when you
> use the Java 6 VM.  It must be explicitly included in your classpath.

Yes tried it both ways... I mean I really tried, even tried building derby 
with different package names ;)

I was absolutely convinced that Sun broke derby... ha ha

> - When using Java DB embedded, you can't run into incompatibilities
> because derby.jar is a single jar file that contains everything you
> need, from the JDBC driver to the full runtime of the database

Yes one would think so...

> Finally, I have a question: you mention that it works fine "outside of
> a classloader" - I am having trouble picturing how a Java application
> can run outside of a classloader.  Do you mean that it's using the
> default system classloader?  What do you mean when it's running in a
> customer classloader?

Yes... runiing as a normal app as apposed to say inside Tomcat...

> Does this problem happen outside of NetBeans or only inside NetBeans?
> If it happens outside, then this is a generic Derby/Java DB issue and
> we should report the bug with the Apache Derby community.

Both.... but only on Java 6

> Thanks for any time you can spend on this Johnny, I know you've
> already moved on :)

Damn you nice... piss off traitor would have been my choice of words... ha 
Only because I was deperate for a fast solution....

This is my gut instincts talking....
I dont think the code in Derby is broken.... but I do think its picking up 
on some kind of extra "sensitivity" between Java5 and Java6
I tried to figure out how to build a Connection Listener, because I think 
one of those will demonstrate the difference.

Let me show you some actual code from this little app

         String sSqlTable = "CREATE TABLE visitor" +
                      "(" +
                      "id integer NOT NULL," +
                      "name varchar(50)," +
                      "time_stamp timestamp DEFAULT CURRENT_TIMESTAMP," +
                      "CONSTRAINT visitor_pkey PRIMARY KEY (id)" +

            dbPersistEngine.doActionQuery(sSqlTable); //If table exists will 
not insert new table
            dbPersistEngine.doActionQuery("CREATE INDEX visitor_id ON 
visitor (id)"); //index to make dB faster
            dbPersistEngine.doActionQuery("CREATE INDEX visitor_name ON 
visitor (name)");

Now that is very very lazy code... its running a query and ignoring 
exceptions.... just trapping them in the wrapper methods...

On Java 5 it works.... on Java 6 it works under the mother ship....
.... on Java 6 in a classloader
.... on the -> dbPersistEngine.doActionQuery("CREATE INDEX visitor_id ON 
visitor (id)"); //index to make dB faster
line.... the exception will be the normal " Idiot the Index is already there 
".... but if you dig deeper with

                                              SQLException tmp = e;
                                              do {//Ever since Derby stuck 
in Java 6 extra issues
                                                //This just to see what the 
hell is going on
Errors: " + e.toString());
                                                tmp = 
                                              } while (tmp != null);

The exception will be....  java.sql.SQLTransientConnectionException: No 
current connection.
So that means everything that comes after this gets that same underlying 
error..... the connection is gone.

Now if I write slightly better code like

        try {
            dbPersistEngine.doActionQueryWithException(sSqlTable); //If 
table exists will not insert new table
            dbPersistEngine.doActionQuery("CREATE INDEX visitor_id ON 
visitor (id)"); //index to make dB faster
            dbPersistEngine.doActionQuery("CREATE INDEX visitor_name ON 
visitor (name)");
        } catch (SQLException ex) {
            System.out.println("Table Exists "  + ex.getMessage());

Then.... after that first exception it jumps over the others and it still 
has a connection....
but some lazy code somewhere else... like the user forgets to enter data and 
a prepared statement tries to set this.... bang! the underlying connection 
is gone.

As you can imagine what happens then is the dB pool has actually lost a 
connection and doesnt know it... so the program is really screwed.

And thats all I can tell you.... why extra "sensitivity creeps in I dont 
know".... but it does mean good or bad code that traps one too many 
exceptions for
Java6... are going to make others also think Derby is screwed.
I dont know too much about the details of Java... but I have a sneaky 
suspicion that if one could drop back a driver version JDBC 4 to 3 or 2 or 
whatever, the sensitivity will dissapear.

Guessing that something fancy in new error checking, automatic driver 
starting, connection listening, internal pooling.... something is making 
Derby tooooo sensitive.
What changed in Java6... thats the clue.

Why this sensitivity shows itself in a custom class loader makes no sense... 
unless something like a connection listener is expecting to find that info 
in its classloader... and because classloaders cant look down... on the 
exception, or successive exceptions it assumes the connection is gone...

I use my own connection pools which probably makes it worse... the 
connections are not sitting in a higher class loader like JNDI... they way 
down in the web app class loader... if that is the case... I'm probably a 
tiny tiny minority... so forget about me... ha ha

Hope that helps....  anyway if it crops up again.... its the combination of 
Derby AND Java6.... on Java 5 lazy code banging away at exceptions does not 
lose the connection.... but that also could be a beeeeeg future headache.

... nice guy, this David chap ;)

>> Mayuresh Nirhali
>> Hi there... I did end up spending an enormous amount of time on it and
>> unfortunately I cant figure out exactly what the problem is... I will 
>> gladly
>> post you the test code if you wish to examine, I could well be making a
>> mistake somewhere. It also may not be related directly to JavaDB, it may
>> well be coming from the JDBC archetecture, in Java6.
>> But here are the symptoms
>> + Running outside classloader... Derby Embedded works.
>> + Running inside another classloader... Derby Embedded is very sensitive 
>> to
>> any exception... if that happens, the underlying dB connection is gone.
>> In the identical application, if I run the H2 embedded dB or the 
>> HSQLdB...
>> it works!
>> This problem does not show on Java5, only on Java6
>> Thats all I can tell you... something weird is happening and it happens 
>> on
>> other machines as well.
>> Its damn difficult to test because you need to build a custom class 
>> loader
>> to see it happening.
>> and its intermittant... it sometimes gets through and works.
>> Yes I know they the same... thats the problem, because the characteristic
>> has changed on Java6, and even if I go load Apache Derby, compile it on 
>> Java
>> 5... it STILL does this on Java6... so that means working apps are 
>> breaking.
>> My immediate problem is solved, I moved to H2, but maybe Sun want to just
>> think about this... why would identicle software behave differently under 
>> a
>> new JRE... so if JDBC has changed... the problem may be there, but I cant
>> figure it out because other embedded dB's work, but then they still maybe
>> under a slightly older JDBC version... even though I am using the latest
>> third party software.... mystery! and probably not that serious to 95% of
>> Derby users.
>> It points at Derby on Java6... but nothing makes sense to me. If I could 
>> get
>> another embedded java dB to do this... then it would suggest a my coding
>> problem.... it doesnt ;)
>> Anyway dont worry, just make a note of it... it will probably crop up 
>> again
>> as app move to Java6

View raw message