Hi Chris,
This can be a little tricky and I may not understand your experiments.
However, it seems to me that you still have only once instance of the
Derby engine running. That instance is being wrapped by a Derby network
server which you have brought up in the same VM and also by your own,
home-grown application code. The Derby network server and your
application are both talking to a single embedded Derby engine in that VM.
Dual booting is generally a problem if you are trying to do one of the
following:
o Boot a database from two different embedded engines in two different VMs
o Boot a database from two versions of the Derby engine running in
different classloaders. This latter case can arise if, for instance, you
are running two different applications in the same VM and each of those
applications requires a different rev level of Derby (e.g., one needs
10.2 and the other needs 10.5).
Hope this helps,
-Rick
Chris Goodacre wrote:
I am seeing some behavior from Derby that suggests that (a) I have
misunderstood the double-booting prohibitions (b) I do not understand the Derby
nomenclature (c) the default configuration of NetworkServer(ControlImpl) is not
the same as the embedded server (d) there is some odd behavior by Derby or (e)
??? Other ???
Obviously, the odds are 3:1 that I've got something messed up in my head. :-)
Here is what I did (before I knew better):
Created a Java application using Derby as an embedded db server. Worked nicely.
Class.forName(DRIVER_NAME); // org.apache.derby.jdbc.EmbeddedDriver
StringBuilder urlBuilder = new StringBuilder(CONNECTION_URL_BASE);
urlBuilder.append(databaseName).append(";");
urlBuilder.append("user=").append(username).append(";");
urlBuilder.append("password=").append(password).append(";");
Connection conn = DriverManager.getConnection( urlBuilder.toString() );
// use conn for the regular JDBC stuff
Thought to myself, "hey, I could let people connect to this application using crystal (or something) so theat they could design and execute reports against it".
Added a Network Server to my application (which was already booting Derby in
embedded mode) in its own thread:
// this now occurs *before* the code above, if that is important
server = new NetworkServerControlImpl();
int command = server.parseArgs(dbargs); // dbargs {"start","-h","127.0.0.1",
"-p", "1527"}
server.executeWork(command);
Later, reviewing the Derby Developer's Guide, I found this under the section "One
Derby instance for each Java Virtual Machine":
"You could potentially have two instances of a Derby system (JVM) running on the same machine at the same time. Each instance must run in a different JVM. Two separate instances of Derby must not access the same database. For example, in an embedded environment, an application that accesses Derby
databases starts up the local JDBC driver, which starts up an instance of Derby. If you start another application, such as ij, and connect to the same database, severe database corruption can result. See Double-booting system behavior. "
and this under "Double-booting system behavior":
"Derby attempts to prevent two instances of Derby from booting the same database by using a file called db.lck inside the database directory.
On all platforms running with a JDK of 1.4 or higher, Derby can successfully prevent a second instance of Derby from booting the database and thus prevents corruption. On some platforms running with a JDK lower than 1.4, Derby may prevent a second instance of Derby from booting the database (previous to JDK 1.4 the ability to do this was OS dependent).
If this is the case, you will see an SQLException like the following:
ERROR XJ040: Failed to start database 'sample', see the next exception for details.
ERROR XSDB6: Another instance of Derby might have already booted the databaseC:\databases\sample."
But I do not see this error, and my application appears to "work". So, what
am I missing?
- Is this not two derby instances in the same VM?
- Is this working (but still dangerous) because the
NetworkServerControlImpl doesn't create a db.lck file (I cannot find one)
- Is this not working, but not generating an error message?
- ???? Other ????
Can someone help me understand what I'm doing here? Does this qualify as double-booting? Should I always being using a regular JDBC driver from within my app to connect to the NetworkServerControlImpl I create (just any other out-of-process client would do)?
-chris