How to make GlassFish's embedded Derby listen on a socket
The convenience of having instant access to an embedded production-quality database was one of the reasons why I found GlassFish interesting. However, even an embedded database must at times be accessible from other clients than the main client, for purposes such as installation, maintenance, debugging, etc. There are embedded databases such as Berkeley DB and SQLite that solve this with filesystem locks. Derby has another option: the embedded Derby can start a server thread that listens on a network socket. The GlassFish documentation recommends that you start a separate JVM process for the database server in order to run client applications that use network JDBC-urls, but this complicates the GlassFish service management in a way that isn't really necessary. After all, the GlassFish server process contains an embedded Derby which already has the capability to listen on sockets.
But I found no obvious way to turn on this feature in the GlassFish admin console. After wading through huge amounts of documentation, I finally found a simple solution: by setting the following system properties, GlassFish will start a Derby network server on localhost, which goes away when GlassFish is stopped.
To turn this on in GlassFish, add these properties to the first domain configuration. Insert these lines somewhere among the <jvm-options> under <java-config> in "domains/domain1/config/domain.xml":
Addendum: a few weeks after writing this, I found out that in a freshly installed GlassFish, the Derby network server isn't started at boot, because the embedded-Derby driver doesn't get loaded until the first time it is used. One way to force this to happen is by accessing the built-in connection pool
[Update: I have since found that doing it like this is not a good approach. See "Embedded Derby on a socket, revisited"]
But I found no obvious way to turn on this feature in the GlassFish admin console. After wading through huge amounts of documentation, I finally found a simple solution: by setting the following system properties, GlassFish will start a Derby network server on localhost, which goes away when GlassFish is stopped.
derby.system.home=/opt/glassfish/databasesThe above assumes that "/opt/glassfish" is the installation directory. The "asadmin start-database" command will then use "/opt/glassfish/databases" for network clients, so that's what we want for the embedded derby listener as well in order to be compatible. The last two properties are only needed if you want something other than the default values of localhost and 1527.
derby.drda.startNetworkServer=true
derby.drda.host=localhost
derby.drda.portNumber=1527
To turn this on in GlassFish, add these properties to the first domain configuration. Insert these lines somewhere among the <jvm-options> under <java-config> in "domains/domain1/config/domain.xml":
<jvm-options>-Dderby.system.home=${com.sun.aas.installRoot}/databases</jvm-options>First stop glassfish and any standalone derby server that might be running, then apply this patch and then start glassfish again, and voila! You can now use the Derby JDBC network client without starting a separate Derby server.
<jvm-options>-Dderby.drda.startNetworkServer=true</jvm-options>
Addendum: a few weeks after writing this, I found out that in a freshly installed GlassFish, the Derby network server isn't started at boot, because the embedded-Derby driver doesn't get loaded until the first time it is used. One way to force this to happen is by accessing the built-in connection pool
__TimerPool
. This can be done from the command line:asadmin ping-connection-pool __TimerPoolOr you can deploy an application that creates a
javax.ejb.Timer
. This seems to have the permanent effect that __TimerPool
is accessed automatically at boot time, causing the Derby embedded driver to load and start the network server.[Update: I have since found that doing it like this is not a good approach. See "Embedded Derby on a socket, revisited"]
Java Enterprise Edition 5
About a month ago, I was finally persuaded to step up from plain Tomcat to a full Java EE application server. I have previously avoided J2EE except for the servlet and mail functionality, due to the rather high initial effort involved and the large footprint (real or just perceived) of the enterprise-class platforms. But things have changed a lot since 2003, and EJBs are not as frightening as they were back in the old days. In order to get started quickly, the platform choices were initially narrowed down to Geronimo and GlassFish, since these two were EE5-certified, free software, and had everything bundled. I immediately felt more comfortable using GlassFish: the command-line tools were easier to use, deployment and redeployment of all but the most trivial things was easier and more intuitive, and it was easier to figure out how to add third-party drivers (e.g. MySQL). Geronimo was a little bit easier to install and faster to start, but the differences were nothing to get excited about. Just for the record: the versions I tried were GlassFish-v2ur2-b04 and Geronimo-tomcat6-javaee5-2.1.3.
I know there are other open-source options such as JBoss, JOnAS, and Resin, but of these only JBoss is EE5-certified at this time, and JBoss failed the initial selection only because the installation bundle contains the Hypersonic SQL database instead of Derby, and I wanted a server with a built-in database that scales well, and Hypersonic doesn't scale as well as Derby. But I'll take a look at JBoss with Derby or MySQL or PostgreSQL later, and write about my impressions in a separate post. This isn't a fair review of all existing application servers anyway, it's just me thinking aloud. So don't hold your breath.
The choice of GlassFish isn't hurt by the fact that GlassFish is the EE5 reference implementation, or that clustering features are supported out of the box. This is important for anyone who can see high volume or high availability as future requirements, because such environments can be simulated easily during the development phase, using GlassFish (or JBoss) on multiple virtual machines running on one or more physical machines using qemu or some other virtualization software. That's a part of my plan anyway. I'll get back to this in a future post.
I know there are other open-source options such as JBoss, JOnAS, and Resin, but of these only JBoss is EE5-certified at this time, and JBoss failed the initial selection only because the installation bundle contains the Hypersonic SQL database instead of Derby, and I wanted a server with a built-in database that scales well, and Hypersonic doesn't scale as well as Derby. But I'll take a look at JBoss with Derby or MySQL or PostgreSQL later, and write about my impressions in a separate post. This isn't a fair review of all existing application servers anyway, it's just me thinking aloud. So don't hold your breath.
The choice of GlassFish isn't hurt by the fact that GlassFish is the EE5 reference implementation, or that clustering features are supported out of the box. This is important for anyone who can see high volume or high availability as future requirements, because such environments can be simulated easily during the development phase, using GlassFish (or JBoss) on multiple virtual machines running on one or more physical machines using qemu or some other virtualization software. That's a part of my plan anyway. I'll get back to this in a future post.