Return-Path: Delivered-To: apmail-db-derby-user-archive@www.apache.org Received: (qmail 35518 invoked from network); 13 Apr 2010 00:02:53 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 13 Apr 2010 00:02:53 -0000 Received: (qmail 21443 invoked by uid 500); 13 Apr 2010 00:02:53 -0000 Delivered-To: apmail-db-derby-user-archive@db.apache.org Received: (qmail 21313 invoked by uid 500); 13 Apr 2010 00:02:53 -0000 Mailing-List: contact derby-user-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: List-Id: Reply-To: "Derby Discussion" Delivered-To: mailing list derby-user@db.apache.org Received: (qmail 21306 invoked by uid 99); 13 Apr 2010 00:02:53 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 13 Apr 2010 00:02:53 +0000 X-ASF-Spam-Status: No, hits=2.9 required=10.0 tests=HTML_MESSAGE,SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (nike.apache.org: local policy) Received: from [74.125.83.44] (HELO mail-gw0-f44.google.com) (74.125.83.44) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 13 Apr 2010 00:02:45 +0000 Received: by gwb1 with SMTP id 1so1475451gwb.31 for ; Mon, 12 Apr 2010 17:02:24 -0700 (PDT) MIME-Version: 1.0 Received: by 10.150.51.1 with HTTP; Mon, 12 Apr 2010 17:02:23 -0700 (PDT) In-Reply-To: <4BC3AAB4.40400@sbcglobal.net> References: <4BC3AAB4.40400@sbcglobal.net> Date: Mon, 12 Apr 2010 17:02:23 -0700 Received: by 10.150.210.18 with SMTP id i18mr4359589ybg.84.1271116943900; Mon, 12 Apr 2010 17:02:23 -0700 (PDT) Message-ID: Subject: Re: Derby causing a classloader leak From: Jason von Nieda To: Derby Discussion Content-Type: multipart/alternative; boundary=000e0cd378a6e8c158048412f9f6 X-Virus-Checked: Checked by ClamAV on apache.org --000e0cd378a6e8c158048412f9f6 Content-Type: text/plain; charset=ISO-8859-1 Hi Kathey, Thanks for the code samples. Unfortunately this didn't do the trick. I am still getting the leaked classloader using the shutdown method you sent over. As before, if I comment just the two stmt.execute() lines the classloader unloads properly. It seems like something happens in the driver once the first statement is executed that causes it to hang on to the classloader. And to Alan, yes, I am closing the statement. I've also tried explicitly closing the statement and creating a new one for each command. That also fails. Jason On Mon, Apr 12, 2010 at 4:20 PM, Kathey Marsden wrote: > On 4/12/2010 1:29 PM, Jason von Nieda wrote: > >> Hi all, >> >> >> These actions, even after the proper Derby shutdown procedures cause the >> classloader to not be unloadable. Can someone take a look at the code below >> and tell me if I am missing something, or is this perhaps a known issue? >> > The important thing I think is to shutdown using the same class loader in > which Derby is booted. Below are some code snippets to do this. I > recently checked in a change to 10.6 that shows the class loader for boot > and shutdown. I'll be backporting that soon to 10.5. The problem I have > mostly seen with using the wrong class loader to shutdown is that a > subsequent boot attempt fails. > > > > > > If you don't have direct access to the class loader, you can get it from > the connection with getClassLoader() > > e.g. > > shutdownWithLoader(conn.getClass().getClassLoader()); > > > > private static void shutdownWithLoader(ClassLoader loader) throws > Exception { > DataSource ds = newDataSource(loader,""); > Class[] argType = {String.class}; > String[] args = new String[] {"shutdown"}; > Method sh = ds.getClass().getMethod("setShutdownDatabase", argType); > sh.invoke(ds, (Object[]) args); > > try { > ds.getConnection(); > }catch (SQLException se ) { > if (se.getSQLState().equals("XJ015")) { > System.out.println("Normal Shutdown"); > } > else > throw se; > } > > } > > > > private static DataSource newDataSource(ClassLoader loader, String > databaseName) throws Exception > { > DataSource ds = (DataSource) > loader.loadClass("org.apache.derby.jdbc.EmbeddedDataSource").newInstance(); > // setDatabaseName with reflection > Class[] argType = {String.class}; > String[] args = new String[] {databaseName}; > Method sh = ds.getClass().getMethod("setDatabaseName", argType); > sh.invoke(ds, (Object[]) args); > return ds; > > } > > > --000e0cd378a6e8c158048412f9f6 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Hi Kathey,

Thanks for the code samples. Unfortunately th= is didn't do the trick. I am still getting the leaked classloader using= the shutdown method you sent over. As before, if I comment just the two st= mt.execute() lines the classloader unloads properly. It seems like somethin= g happens in the driver once the first statement is executed that causes it= to hang on to the classloader.=A0

And to Alan, yes, I am closing the statement. I've = also tried explicitly closing the statement and creating a new one for each= command. That also fails.=A0

Jason


On Mon, Apr 12, 2010 at 4:20 PM, = Kathey Marsden <kmarsdenderby@sbcglobal.net> wrote:
On 4/12/2010 1:29 PM, Jason von Nieda wrote:
Hi all,


=A0These actions, even after the proper Derby shutdown procedures cause the= classloader to not be unloadable. Can someone take a look at the code belo= w and tell me if I am missing something, or is this perhaps a known issue?<= br>
The important thing I think is to shutdown using the same class loader in w= hich Derby is booted. =A0 Below are some code snippets to do this. =A0 I re= cently checked in a change to 10.6 that shows the class loader for boot and= shutdown. =A0I'll be backporting that soon to 10.5. =A0The problem I h= ave mostly seen with using the wrong class loader to shutdown is that a sub= sequent boot attempt fails.





If you don't have direct access to the class loader, you can get it fro= m the connection with getClassLoader()

e.g.

=A0 =A0shutdownWithLoader(conn.getClass().getClassLoader());



=A0private static void shutdownWithLoader(ClassLoader loader) throws Excep= tion {
=A0 =A0DataSource ds =3D newDataSource(loader,"");
=A0 =A0Class[] argType =3D {String.class};
=A0 =A0String[] args =3D new String[] {"shutdown"};
=A0 =A0Method sh =3D ds.getClass().getMethod("setShutdownDatabase&quo= t;, argType);
=A0 =A0sh.invoke(ds, (Object[]) args);

=A0 =A0try {
=A0 =A0 =A0 =A0ds.getConnection();
=A0 =A0}catch (SQLException se ) {
=A0 =A0 =A0 =A0if (se.getSQLState().equals("XJ015")) {
=A0 =A0 =A0 =A0System.out.println("Normal Shutdown");
=A0 =A0 =A0 =A0}
=A0 =A0 =A0 =A0else
=A0 =A0 =A0 =A0throw se;
=A0 =A0}

=A0 =A0}



=A0 =A0private static DataSource newDataSource(ClassLoader loader, String = databaseName) throws Exception
=A0 =A0{
=A0 =A0 =A0 =A0DataSource ds =3D (DataSource) loader.loadClass("org.a= pache.derby.jdbc.EmbeddedDataSource").newInstance();
=A0 =A0 =A0 =A0// setDatabaseName with reflection
=A0 =A0 =A0 =A0Class[] argType =3D {String.class};
=A0 =A0 =A0 =A0String[] args =3D new String[] {databaseName};
=A0 =A0 =A0 =A0Method sh =3D ds.getClass().getMethod("setDatabaseName= ", argType);
=A0 =A0 =A0 =A0sh.invoke(ds, (Object[]) args);
=A0 =A0 =A0 =A0return ds;

=A0 =A0}



--000e0cd378a6e8c158048412f9f6--