----- Original Message ----- From: "David Van Couvering" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>; "Derby Discussion" <[email protected]>
Sent: Monday, January 14, 2008 10:12 PM
Subject: Fwd: [nbusers] Issues with Derby in customer classloader using Java 6


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 <[EMAIL PROTECTED]>
Date: Jan 14, 2008 12:08 PM
Subject: Re: [nbusers] == I got issues with JavaDB on 6 ==
To: [EMAIL PROTECTED]


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 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
                                               System.out.println("====");
System.out.println("Deep Errors: " + e.toString());
                                               tmp.printStackTrace();
tmp = tmp.getNextException();
                                             } 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

Reply via email to