db-derby-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Katherine Marsden <kmarsdende...@sbcglobal.net>
Subject Re: Is it expected that each class loader context gets its own in memory database
Date Mon, 22 Oct 2012 14:20:24 GMT
On 10/22/2012 6:44 AM, Katherine Marsden wrote:
>
> I have some code that shows the behavior
>

Here is the program showing the behavior:

import java.io.*;
import java.net.*;
import java.sql.*;
import javax.sql.*;
import javax.transaction.xa.*;

public class TestDerbyInMemoryDatabase
{
     private final static String DB_NAME = "memory:testdb";
     private final static String 
JAR_LOCATION="file:///C:/cygwin/svnreleases/jars/10.8.2.2/derby.jar";

     private static void insert(int value, ClassLoader loader) throws 
Exception
     {
         @SuppressWarnings("unchecked")
         Class<DataSource> dsClass = (Class<DataSource>) 
loader.loadClass("org.apache.derby.jdbc.EmbeddedDataSource40");
         DataSource ds = dsClass.newInstance();
         dsClass.getMethod("setDatabaseName", String.class).invoke(ds, 
DB_NAME);
         dsClass.getMethod("setCreateDatabase", String.class).invoke(ds, 
"create");

         Connection con = ds.getConnection();
         Statement stmt = con.createStatement();

         try {
             stmt.executeUpdate("create table tbl1 (col1 int not null 
primary key)");
             System.out.println("created new table");
         } catch (SQLException x) {
             System.out.println(x.getMessage());
         }

         stmt.executeUpdate("insert into tbl1 values (" + value + ")");
         System.out.println("inserted " + value);

         ResultSet result = stmt.executeQuery("select * from tbl1");
         System.out.print("contents of table: ");
         while (result.next())
             System.out.print(result.getInt(1) + " ");
         System.out.println();

         con.close();
     }

     private static void shutdown(ClassLoader loader) throws Exception {
         @SuppressWarnings("unchecked")
         Class<DataSource> dsClass = (Class<DataSource>) 
loader.loadClass("org.apache.derby.jdbc.EmbeddedDataSource40");

         DataSource ds = dsClass.newInstance();
         dsClass.getMethod("setDatabaseName", String.class).invoke(ds, 
DB_NAME);
         dsClass.getMethod("setShutdownDatabase", 
String.class).invoke(ds, "shutdown");
         try {
             ds.getConnection();
             throw new Exception();
         } catch (SQLException x) {
             if (45000 == x.getErrorCode())
                 System.out.println(x.getMessage());
             else
                 throw x;
         }

         ds = dsClass.newInstance();
         dsClass.getMethod("setShutdownDatabase", 
String.class).invoke(ds, "shutdown");
         try {
             ds.getConnection();
             throw new Exception();
         } catch (SQLException x) {
             if ("XJ015".equals(x.getSQLState()))
                 System.out.println(x.getMessage());
             else
                 throw x;
         }
     }

     public static void main(String[] args) throws Throwable
     {
         URL[] urls = new URL[] { new URL(JAR_LOCATION) };
         ClassLoader derbyLoader1 = new URLClassLoader(urls);

         insert(1, derbyLoader1);
         shutdown(derbyLoader1);

         ClassLoader derbyLoader2 = new URLClassLoader(urls);
         insert(2, derbyLoader2);
         shutdown(derbyLoader2);

         insert(3, derbyLoader1);
         shutdown(derbyLoader1);
     }
}

The program creates a table and inserts  an entry (1), then shuts  down 
the derby database and derby system.  Then, with a different 
classloader, attempts to create the table if it doesn't exist, and 
inserts and entry (2), then shuts down the derby database and derby 
system. Then, as an additional experiment,  it goes back to original 
classloader,  attempts  to create the table if it doesn't exist, and 
inserts and entry (3), then shut down the derby database and derby system.

Below is the output:

C:\tests>java TestDerbyInMemoryDatabase created new table inserted 1 
contents of table: 1
Database 'memory:testdb' shutdown. Derby system shutdown.
created new table inserted 2 contents of table: 2
Database 'memory:testdb' shutdown. Derby system shutdown.
Table/View 'TBL1' already exists in Schema 'APP'. inserted 3 contents of 
table: 1 3
Database 'memory:testdb' shutdown. Derby system shutdown. T

The output seems to indicate that the in-memory database is tied in some 
way to the classloader from which the data source is loaded, as it 
appears that the classloaders each have their own memory:testdb 
database, each of which actually does survive the shutdown but is 
inaccessible to the data source loaded from the other class loader.



Mime
View raw message