Return-Path: X-Original-To: apmail-db-derby-commits-archive@www.apache.org Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 91F104C50 for ; Wed, 13 Jul 2011 12:29:02 +0000 (UTC) Received: (qmail 61389 invoked by uid 500); 13 Jul 2011 12:29:02 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 61320 invoked by uid 500); 13 Jul 2011 12:29:01 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 61313 invoked by uid 99); 13 Jul 2011 12:29:01 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Jul 2011 12:29:01 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Jul 2011 12:29:00 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id E6F9A23889BB; Wed, 13 Jul 2011 12:28:39 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1145973 - /db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/PhaseChanger.java Date: Wed, 13 Jul 2011 12:28:39 -0000 To: derby-commits@db.apache.org From: kahatlen@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110713122839.E6F9A23889BB@eris.apache.org> Author: kahatlen Date: Wed Jul 13 12:28:39 2011 New Revision: 1145973 URL: http://svn.apache.org/viewvc?rev=1145973&view=rev Log: DERBY-5316: Unload old JDBC drivers when done with them in the upgrade tests Added a workaround for DERBY-23. Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/PhaseChanger.java Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/PhaseChanger.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/PhaseChanger.java?rev=1145973&r1=1145972&r2=1145973&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/PhaseChanger.java (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/PhaseChanger.java Wed Jul 13 12:28:39 2011 @@ -124,6 +124,13 @@ final class PhaseChanger extends BaseTes protected void tearDown() throws Exception { if ( trace ) BaseTestCase.traceit(" Test upgrade done."); + + // Get a handle to the old engine's ContextService if this version is + // affected by DERBY-23. The actual workaround for DERBY-23 must be + // done after the engine has been shut down, but we fetch the handle + // to the service before shutdown, while it's still easily available. + Object contextService = getDerby23ContextService(); + DataSource ds = JDBCDataSource.getDataSource(); JDBCDataSource.shutEngine(ds); @@ -140,6 +147,11 @@ final class PhaseChanger extends BaseTes clearDerby4895ThreadLocal(); } + // Workaround for DERBY-23, continued. If this is one of the affected + // versions, clear the fields that prevent the engine from being + // garbage collected. + clearDerby23ThreadLocals(contextService); + if (loader != null) UpgradeClassLoader.setThreadLoader(previousLoader); loader = null; @@ -198,8 +210,59 @@ final class PhaseChanger extends BaseTes Class td = Class.forName( "org.apache.derby.iapi.sql.dictionary.TableDescriptor", true, loader); - Field f = td.getDeclaredField("referencedColumnMap"); + clearField(td, "referencedColumnMap", null); + } + + /** + * Clear a field that is possibly private or final. + * + * @param cls the class in which the field lives + * @param name the name of the field to clear + * @param instance the instance whose field should be cleared, + * or null if the field is static + */ + private static void clearField(Class cls, String name, Object instance) + throws Exception { + Field f = cls.getDeclaredField(name); f.setAccessible(true); - f.set(null, null); + f.set(instance, null); + } + + /** + * Get a handle to the ContextService in the old engine if the version + * is affected by DERBY-23. + * + * @return the ContextService, if this version is affected by DERBY-23, + * or null otherwise + */ + private Object getDerby23ContextService() throws Exception { + if (loader != null && + UpgradeRun.lessThan(version, new int[] {10,2,1,6})) { + Class cls = Class.forName( + "org.apache.derby.iapi.services.context.ContextService", + true, loader); + Field f = cls.getDeclaredField("factory"); + f.setAccessible(true); + return f.get(null); + } + + return null; + } + + /** + * Clear some fields in ContextService to allow the engine to be garbage + * collected. This is a workaround for DERBY-23. + * + * @param contextService the context service for an engine that has been + * shut down, or null if this version of the engine doesn't suffer from + * DERBY-23 + */ + private void clearDerby23ThreadLocals(Object contextService) + throws Exception { + if (contextService != null) { + Class cls = contextService.getClass(); + clearField(cls, "threadContextList", contextService); + clearField(cls, "allContexts", contextService); + } } }