JavaDB and Glassfish v3 : to embed or not to embed

Posted by Dick on May 15, 2008

Since writing this, I’ve realised JavaDB is pretty crap. Do yourself a favour and try the decent PostgreSQL installer I found.

 

Glassfish v3 ships with JavaDB (aka Apache Derby aka Cloudscape).
I’ll be using this for trying out Rails and JRuby, but it’s also handy
for things like authentication via JDBC Realms.

A JavaDB database is essentially a directory that only one process can access at a time (a bit like sqlite). This can be Glassfish itself (an embedded database) or a standalone database process (that serves SQL clients over TCP/IP).

Both have pros and cons. I’ll take you through creating both.

option 1: standalone database server

You sure you want JavaDB? There are better options (sorry, can’t help it).

The main benefit to running a network server process is that it’s the only way for multiple clients to access the database simultaneously

(it’s also the only option that makes sense if you were clustering Glassfish).

If you need to create a schema before you deploy a webapp (with NetBeans or ‘rake migrate’)
you’ll have to stop Glassfish first unless you go down this route.

hypnotoad:databases $ asadmin start-database --dbhost 127.0.0.1
Database started in Network Server mode on host 127.0.0.1 and port 1527.
Could not connect to Derby Network Server on host 127.0.0.1 port 1527.
Starting database in the background.
Log redirected to /Users/dick/Applications/glassfishv3-tp2/glassfish/databases/derby.log.
Command start-database executed successfully.

( –dbhost defaults to ‘0.0.0.0’ but this causes problems if you change IP . Stick to 127.0.0.1).

Next, create the connection pool (and associated database - see later).
It’s simplest to do this on the command line (partly due to bug 4889 ):

hypnotoad:databases $ asadmin create-jdbc-connection-pool \
--datasourceclassname=org.apache.derby.jdbc.ClientConnectionPoolDataSource\
--isconnectvalidatereq=true --validationmethod=meta-data \
--property user=GFv3:password=GFv3:databaseName=railsdb:\
connectionAttributes=\;create\\=true \
railspool
Command create-jdbc-connection-pool executed successfully.
  • The ’;create=true’ option tells JavaDB to create the ‘railsdb’ database on demand
  • host:port defaults to localhost:1527
  • username and password can be anything, but are required

We now ‘ping’ the pool. This checks our network connection is good, and has the side-effect
of creating the ‘railsdb’ database:

hypnotoad:databases $ asadmin ping-connection-pool railspool
Command ping-connection-pool executed successfully.
hypnotoad:databases $ ls
derby.log railsdb

option 2. embed Derby in Glassfish

This is my preferred option for several reasons:

  1. it saves having to run 2 JVMs
  2. in development, I don’t mind stopping Glassfish
  3. for production, I want webapps to create their own schema anyway
  4. connection validation and authentication is no longer an issue
  5. sorry to bang on about it, but if you want a standalone database there are much better options

One side effect is that Glassfish is going to use more memory (especially if you have several connection pools configured). You might want to tweak your JVM .

There’s no need to ‘start-database’ in this case – just go ahead and make the pool:

hypnotoad:glassfishv3-tp2 $ asadmin create-jdbc-connection-pool \
--datasourceclassname org.apache.derby.jdbc.EmbeddedDataSource \
--property databaseName=\$\{com.sun.aas.instanceRoot\}/databases/railsdb:\
connectionAttributes=\;create\\=true \
railspool
Command create-jdbc-connection-pool executed successfully.
  • the different DataSource class is what makes it embedded
  • provide a full path in the databaseName attribute to avoid current working directory hell
  • since Glassfish is the database server, we can skip username,password and connection validation options

If we ping the pool, we can see Glassfish creates derby.log and the database dir

hypnotoad:glassfishv3-tp2 $ asadmin ping-connection-pool railspool
Command ping-connection-pool executed successfully.
hypnotoad:glassfishv3-tp2 $ tail derby.log
2008-05-15 11:12:48.770 GMT:
Booting Derby version The Apache Software Foundation – Apache Derby – 10.2.2.1 – (538595): instance c013800d-0119-ec48-424c-000001a39158
on database directory /Users/dick/Applications/glassfishv3-tp2/glassfish/domains/domain1/databases/railsdb
Database Class Loader started – derby.database.classpath=’‘
hypnotoad:glassfishv3-tp2 $

Butler Lampsons mamma didn’t raise no fools

Whichever option you choose, the command to give the pool a JNDI name is the same:

hypnotoad:glassfishv3-tp2 $ asadmin create-jdbc-resource --connectionpoolid=railspool jdbc/railspool
Command create-jdbc-resource executed successfully.

And we’re done. Now simply write a webapp to use the damn thing.

first look at GF3

Posted by Dick on May 13, 2008

Fishes eyes

I’ve been following Glassfish with interest for a while now
I want a Tomcat replacement: webapps, a connection pool and an admin
interface that doesn’t stink. Not much to ask.

Glassfish2 delivers all that in spades, plus clusters very nicely.
But it also has a lot of J(2)EE features that I’m not really interested in.

Glassfish v3s design follows a ‘microkernel’ model, which should mean its
a lot lighter, faster, and lets you mix and match the features you need.

It’s matured enough for me to give it a go.

Get it from https://glassfish.dev.java.net/downloads/v3-techPreview-2.html. The same ZIPfile runs on all platforms (I’m on a Macbook Pro).

cd ~/Applications
unzip ~/Downloads/gfv3-preview2.zip
PATH=$PATH:~/Applications/glassfishv3-tp2/bin

nice feature #1 : typo detection

hypnotoad:glassfishv3-tp2 $ ./bin/asadmin list-domain
Closest matching command(s):
list-domains
Remote server does not listen for requests on [localhost:8080].
Is the server up?
Command list-domain failed.
hypnotoad:glassfishv3-tp2 $ ./bin/asadmin list-domains
domain1
Command list-domains executed successfully.

nice feature #2 : boot time

hypnotoad:glassfishv3-tp2 $ time asadmin start-domain domain1
Command start-domain executed successfully.
real  0m1.029s
user  0m0.456s
sys 0m0.091s

nice feature #3 : not everyone needs an /admin webapp

First nice feature: open http://localhost:8080 and try
‘to manage the server, click here ‘. Glassfish gets the request for /admin,
realises it doesn’t have an admin webapp, and offers to install it whle U wait:

Once admingui.war downloads, it’s deployed and you get a login prompt.
Login as ‘anonymous’ (no password) and you get the usual admin screen -
as you can see there’s a lot less stuff in there by default.

nice feature #4 : you can deploy things to it

(In my experience, that’s not a given).

Just knock up a stub webapp in Netbeans ( here’s one I made earlier ) and deploy it:

hypnotoad:glassfishv3-tp2 $ time asadmin deploy ~/NetBeansProjects/hellonasty/dist/hellonasty.war
upload file successful: /private/tmp/gfv3/hellonasty.war
Command deploy executed successfully.
real  0m2.393s
user  0m0.288s
sys 0m0.071s

And here it is:

nice feature #5 : documentation

is at : http://docs.sun.com/app/docs/coll/1343.7

next steps

Seems to run OK to me, even though OS X isn’t listed as a supported platform yet.
There are a few features missing (asadmin list-commands is a lot shorter than on GFv2)
but I’m pretty pleased with it.

Next on the list : hook up NetBeans and JRuby and try deploying a database-backed Rails app.
I’ve just figured out how to get JavaDB and Glassfish to play nice.

geek christmas comes early

Posted by Dick on September 04, 2007

Solaris 10 Update 4 finally shipped today – the changelog lists all the nice features of Solaris Express I’ve been banging on about for the last year or so including

plus a load of other stuff I didn’t get a chance to try yet, like

I’ll probably stick with Solaris Express on my laptop , mainly because the wireless/NWAM bits work so well. Plus I’m really looking forward to the
upcoming mdns (aka zeroconf) support in Nevada b72 to play nice with OSX.

Servers are another matter, though.
With iSCSI in a supported Solaris release, Thumpers finally make sense.
And Glassfish v2 is in final RC now, and should be out by the end of the month. A small GF cluster is high on my todo list, and by October I should have a fully-supported stack.

Oh, and tomorrow Brian Apple will be releasing his new liquid iPods which I hear are delicious.

told you

Posted by Dick on July 10, 2007

Glassfishv2 and PostgreSQL (open source, free) now officially wizz all over
BEA, IBM and Oracle (proprietary, hideously expensive).

Feels good to have backed a winning horse. There’s another beta out now too that I’ll be upgrading
my existing install to when I get five minutes.

In the meantime, congratulations to the GF team.

adding existing SSL keypairs to Java keystores

Posted by Dick on June 26, 2007

I want my Roller install
to use LDAP authentication (instead of its own account database).
LDAP auth means cleartext passwords, so I need to run the site over SSL.

where glassfish keeps SSL certs and keys

Each Glassfish domain has it’s own keystore, which is protected by what the docs call the
‘admin master password’ (not the same as the ‘admin password’).

The master password is just a Java keystore password,
so if you didn’t say otherwise at domain creation time
it defaults to ‘changeit’.
You can check by trying to list the entries in your keystore:

goldfish $ keytool -list -keystore \
   /domains/rollerdisco/config/keystore.jks
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
s1as, Apr 22, 2007, PrivateKeyEntry,
Certificate fingerprint (MD5): 80:08:13:50:00:00:80:08:13:50:00:00

There’s just one entry – s1as – which is the SSL keypair for the domains admin webapp (om port 4848).

As of version 2, the Glassfish admin UI lets you choose keypairs from this keystore, but it can’t import into the keystore itself.
So you’ll have to break out the command line.

As you’ll see, I really hope they add that feature soon.

lots of swearing

If you’re creating a new keypair, things are relatively sane – see
Ryans howto .
I’m unlucky enough to have an existing apache-style’server.key/server.crt’ PEM keypair I want to use.

This turns out to be a massive pain in the arse. You’d think ‘keytool -import’ would do the trick,
but that only lets you add the certificate – keytool assumes it created the inital private key so doesn’t
provide a way to import one.

Googling found some very old tools for doing this, most of which only work with older, PKCS12 based keystores.

Let me save you an afternoon. The Jetty project have a tool called
PKCSImport
which is by far the least shitty way of doing this.

First, merge the two files using everyones favourite crypto swiss army knife:

goldfish $ openssl pkcs12 -export -out roller.p12 \
  -inkey roller.key -in roller.crt

It asks you for an export password. ‘foo’ works fine :)

Then get the Jetty jarfile and run the tool against your PKCS keypair:

goldfish # /usr/sfw/bin/wget http://kent.dl.sourceforge.net/sourceforge/jetty/jetty-6.1.4rc0.zip
goldfish # unzip jetty-6.1.4rc0.zip
goldfish # /j2ee/jdk/bin/java \
  -cp jetty-6.1.4rc0/lib/jetty-6.1.4rc0.jar \
  org.mortbay.jetty.security.PKCS12Import \
  roller.p12 /domains/rollerdisco/config/keystore.jks
Enter input keystore passphrase: foo
Enter output keystore passphrase: 
Alias 0: 1
Adding key for alias 1

This imports your certificate and keypair and creates a new keystore entry.
Unfortunately the entry is called ’1’, which is hardly self-documenting, so
I’ll rename that to the domain name it’ll run on:

goldfish # /j2ee/jdk/bin/keytool -changealias \
  -keystore /domains/rollerdisco/config/keystore.jks \
  -alias 1 -destalias roller.yourdomain.com

use the certificate

Glassfish already serves webapps over https, it’s just on a non-standard port of 8181
(the—domainproperties option to asadmin create-domain can specify this. Yay hindsight).

Go to the admin webapp, and browse to :

Configurations → server-config → HTTP Service → HTTP listeners

under there you’ll see 3 listeners

  • admin-listener runs the Admin Console you’re using (on https port 4848) so you probably want to leave that the hell alone
  • http-listener-1 (aka the ‘instance port’) defaults to 8080 . I set mine up on port 80 during my SMF setup .
  • http-listener-2 (is the https port), still on it’s default of port 8181

First change the http-listener-2 port from 8181 to 443, then click over to the SSL tab.

Enter the keystore alias name for the keypair you just imported in ‘Certificate Nickname:’ and tick the TLS and SSLv3 boxes.
Also select at least the ‘common ciphers’.

We’re now running the same webapp (roller) over both the http and https.
Finally, go back to http-listener-1 and set the SSL redirect port to 443 – this tells the webapp to redirect to SSL for
sensitive operations.

Alternatively, turn off the http listener (untick ‘Listener: enabled’) to ensure all traffic comes over https.