I installed a fresh copy of Glassfish 3 awhile back to work on a client’s application. Both the installation and IntelliJ configuration were a piece of cake. But as soon as I attempted to deploy the app and fire up Glassfish, I was greeted with this warm welcome in my server log, “Java instance does not support a 32-bit JVM.”

What!? Go home Glassfish you’re drunk! I tried deploying and running the application a few more times from IntelliJ, but with the same result. (Surely trying the same thing over and over again is bound to work eventually?) So then I found the application server’s bin directory and tried launching the server with the startserv script. Much to my surprise the server launched without error and served up my application. Well, crap, surely my trusty IntelliJ isn’t letting me down? Upon inspecting the Glassfish configuration in IntelliJ I noticed that IntelliJ launches the server using the asadmin utility, rather than startserv. Sure enough, when I went back to the command line and tried to launch Glassfish using the asadmin utility I received the same error.

Problem

It turns out there’s a small inconsistency between how the asadmin utility and the startserv script resolve the java executable. Take a look at this first snippet from asadmin. You can see that admin-cli.jar is eventually launched using the java executable referenced by the JAVA variable. The JAVA variable is initialized to point to the java executable found on the PATH. However, if the AS_JAVA variable is set then the script overrides the executable from the PATH with the executable found under the location specified in AS_JAVA.

asadmin
1
2
3
4
5
6
7
...
JAVA=java
#Depends upon Java from ../config/asenv.conf
if [ ${AS_JAVA} ]; then
    JAVA=${AS_JAVA}/bin/java
fi
exec "$JAVA" -jar "$AS_INSTALL_LIB/admin-cli.jar" "$@"                     

If you take a look at this next snippet from the startserv script you’ll notice that it also ultimately launches the admin-cli.jar file. However, in this case the script simply launches the jar using the java executable found on the PATH without ever checking the AS_JAVA variable.

startserv
1
2
3
4
5
...
AS_INSTALL=`dirname "$0"`/..
AS_INSTALL_LIB="$AS_INSTALL/modules"

exec java -jar "$AS_INSTALL_LIB/admin-cli.jar" start-domain --verbose "$@"

So what’s the path found in AS_JAVA and where is it initialized? It just so happens that asadmin pulls that variable, and many others, from the asenv.conf file. In my case, the problem was the JDK referred to on line 9 of this asenv.conf snippet. As the error implied, this JDK did not support a 32 bit JVM instance.

asenv.conf
1
2
3
4
5
6
7
8
9
...
AS_IMQ_LIB="../../mq/lib"
AS_IMQ_BIN="../../mq/bin"
AS_CONFIG="../config"
AS_INSTALL=".."
AS_DEF_DOMAINS_PATH="../domains"
AS_DEF_NODES_PATH="../nodes"
AS_DERBY_INSTALL="../../javadb"
AS_JAVA=/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

Solution

In my case the solution was pretty simple. I already had a separate Java 7 installation that was available on the PATH, so I simply commented out the AS_JAVA assignment in asenv.conf. That prevented the java executable found on the PATH from being overridden, allowing the asadmin utility to use the same Java 7 installation as startserv without requiring any modification to the asadmin script.

If you don’t already have another JDK installation that supports a 32 bit JVM, you’ll need to hunt one down and install it. Assuming you want to make that new JDK available on your path, you can use the same solution I did. Otherwise, you can update the AS_JAVA variable in asenv.conf to point to your new installation. Now you either need to avoid using startserv altogether, or modify the startserv script to look for the overriding JDK defined in asenv.conf. I’m not covering Bash-Fu, so you’re on your own to make that happen.