Deploying Grails On GlassFish v3

March 11, 2010

March 11, 2010

This article walks through the steps of moving into a clean install of a 64 bit CentOS release 5.4 (Which is theoretically equivalent to Red Hat Enterprise Linux (RHEL)).  The final objective is to run a successfully deployed grails application on the web.

This is the 11th article in the Getting Started with Grails tutorial series.  The entire series is as follows:

  1. Introduction
  2. Getting started with JRuby
  3. Getting started with GlassFish
  4. Restarting GlassFish
  5. Getting started with load balancing (Apache)
  6. Load balancing with web server redundancy (Apache)
  7. Load balancing with web server failover (Apache)
  8. Getting Started with Message Oriented Web Services (Java EE)
  9. Setting up a local network using FireWire
  10. Sending Email from Grails
  11. Deploying Grails on GlassFish v3

For starters, I’m running on a MacBook Pro using Mac OS X Version 10.5.8 (Leopard) and using the bash terminal shell.


So let’s get going…

Step 1 – Security

The first step is to log into your server:

ssh -p <port number> <username>@<ip address or domain name>

for example

ssh -p 1234 fred@123.45.67.89

and of course, respond at the prompt with your username.

Being that the username that you’re using may be given to you by the sys admin person, you should change the password to something secure (use both letters and numbers which do not spell anything from ANY dictionary (even the cleaver use of numbers to represent letters, such as ‘3’ for ‘e’ is dangerous)).  Change the password via the command:

passwd

… and follow the prompts for entering the new password (twice).

Don’t forget to also change the root password.  First login as root with:

su

… and login using the ORIGINAL (sys admin supplied) password to become root.

Now change the password here just like we did before with:

passwd

… and follow the prompts for entering the new password (twice).

OK just to be sure, logout from root via:

exit

and then logout from your username account via:

exit

and now log back in as before:

ssh -p 1234 fred@123.45.67.89
but, of course, use your new passwordand then try to become root via

su

… using the new password.

From here out, all communications with the remote server shall be through ssh…

Step 2 – Install The Java SDK

Due to licensing conflicts between the Linux and Java licenses, Java nor the SDK are installed within the linux releases (yet(?)).  As such, we need to do a Java install…

We first have to web surf over to:

http://java.sun.com/javase/downloads/index.jsp

And download the file:

jdk-6u18-linux-x64.bin

to your desktop system.  Note:  you want to download the JDK (not the JRE).

We now need to Secure FTP this file into our server.

It’s easiest to cd into the local directory that contains the file to upload.  Then open up an SFTP connection via…

sftp -oPort=<ssh port number> <username>@<IP address or domain name>

For example:

sftp -oPort=1234 fred@123.45.67.89

Then:

put <localFileName>

will cause the file identified by <localFileName> to your home directory on the remote server.

Just for reference, using the help command from within sftp will produce a nice list of the available commands.

and then terminate the sftp session with the command:

exit

Now the java JRE’s bin file needs to be placed into a more appropriate directory.  Thus ssh back into the server via:

ssh -p <port number> <username>@<ip address or domain name>

Then:

su

cd /opt

mkdir Java

cd Java

mv /home/<username>/<nameOfJREBinFile> .

chown root.root

sh <nameOfJDKBinFile>

The End User Licensing Agreement (EULA) will be displayed to you a page at a time.  Hitting the space-bar will proceed you to the next page.  When you get to the accept question, you’ll probably want to answer yes followed by a carriage return.  The bin file will then be unpacked into a JDK directory in the file’s current directory.

Now that the java files are in place, there’s some cleanup to do.  First create a symbolic link to help out with future updates of the JVM.  For example:

rm jre-6u18-linux-x64.bin

ln -s jdk1.6.0_18/ current

ls -la

Secondly, cd to your personal (non-root) home directory and edit the .bashrc file:

exit

cd

ls -la

cp .bashrc .bashrc_original

vi .bashrc

and append the following line to the file:

export PATH=/opt/java/current/bin:$PATH

and then save and quit the vi editor.

Finally activate the .bashrc script with:

source .bashrc

and test that your JVM is configured properly:

java -version

and you should see something like:

java version “1.6.0_18”
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)

Ta Da!  You now have the JDK on your server.  :-)
Step 3 – Install GlassFish

Although I’ve previously blogged about setting up GlassFish version 2.1 on a remote server (“Getting Started with GlassFish“), the installation of GlassFish version 3.0 onto a Linux server is different enough to merit a new howTo.

We start with the same URL from which we download GlassFish:

https://glassfish.dev.java.net/

But this time download the GlassFish 3.0 ZIP file (the “full version” not the “web profile”).

and use the same methodology as described in Step 2 to upload the glassfishv3.zip file to the remote server directory:

/opt/glassfish

but instead of using the sh command to unpack the .bin file as we did in Step 2, we need unzip the .zip file.  Luckily, the ability to unzip a file is present within Linux server images. As to be expected use the following command (as root):

unzip glassfishv3.zip

Now, this will create a glassfishv3 directory as well as a __MACOSX directory.  One of these directories will be used, and one will not.  Assuming that your system is a Linux system like mine, you’ll want to clean things up by removing the unnecessary __MACOSX directory with the (as root) command below (BE CAREFUL with this command, especially when in root mode (this cannot be over stressed)):

rm -rf __MACOSX

And for connivence, create a symbolic link:

ln -s ./glassfishv3 current

And finally, to make life simpler for you, (not as root) append the following command to the end of your home directory’s .bashrc file:

export PATH=/opt/glassfish/current/bin:$PATH

and once your .bashrc file is edited, save and quit then activate the .bashrc configurations via:

source .bashrc

And finally to test if your glassfish version 3 is configured properly, execute:

asadmin -?

and you should see the man page for the glassfish’s asadmin.

Excellent!  Your on your way to world domination.  ;-)

Step 4 – Setting up GlassFish Security

If you finished the previous step, your Unix based GlassFish server is ready to be turned on.  Note:  Firewall port 4848 should be disabled at this point (before we turn on GlassFish).  Behind the firewall, we’ll want to set up the GlassFish security features so that our system console will operate using a secure connection as opposed to using the default non-secure communication protocol – THEN we’ll turn on firewall port 4848.

To verify that the extended paths that were established in Step 3 have taken effect, run the command:

env

and note that out of the listing produced there should be two lines that look somewhat like:

PATH=<a bunch of stuff>:/opt/glassfish/current/bin:/opt/java/current/bin:<a bunch of more stuff>

Now we can command-line invoke the GlassFish administrator from anywhere.  The following commands will turn the GlassFish server on:

su

asadmin start-domain

Note:  if you are not root and attempt to execute the (seemingly equivalent) command:

sudo asadmin start-domain

you will get the following  error message:

/opt/glassfish/current/bin/asadmin: line 17: exec: java: not found

That said, make sure that you only operate the asadmin command as root (whoami returns “root”).

End of Note.

As GlassFish starts up (about 20 to 30 seconds), there will be a couple lines of status messages as follows:

Waiting for DAS to start ….

Started domain: domain1

Domain location: /opt/glassfish/glassfishv3/glassfish/domains/domain1

Log file: /opt/glassfish/glassfishv3/glassfish/domains/domain1/logs/server.log

Admin port for the domain: 4848

Command start-domain executed successfully.

and then the command prompt will be given back to you.  Your GlassFish DAS (domain1 server) is now running on your CentOS server.

Ideally, GlassFish should be configured to operate within a cluster.  As of this writing though, GlassFish version 3 does not support clustering.  :-(   I hope that the new owners see the value of continuing to improve upon GlassFish, which IMNSHO is the best app server on the planet.  Yes Oracle, I hope you’re reading this. OK, end of my digression.

Using your favorite web browser, surf over to:

http://localhost:4848

At which point you should (hopefully) be served up a page that looks something like:

Using the hierarchy tree on the left, and as show in the image above, go to:

Configuration –> Network Config –> Protocols –> admin-listener

and then click on the:

checkbox.  Then thebutton.

If you were to proceed with operating your GlassFish server at this point, you’ll successfully operate the GlassFish v3 Administration Console via https BUT YOUR ADMIN CONSOLE WOULD BE ACCESSIBLE WITHOUT A PASSWORD (Doooough).

Surfing the hierarchy tree to:

Enterprise Server –> Administrator Password

as shown:

and fill in the new password (twice).  Then click thebutton.

In order for the security features to take effect, we’ll need to reboot the GlassFish server.  This is done through going to the hierarchy selection:

Enterprise Server –> General

Which will display the image:

and press the  button to restart the GlassFish server.

To validate that your server is operating securely, open a new browse window and try to go to the insecure address:

http://localhost:4848

and, as expected, you’ll find that there is no response from the server.  When you go to the secure address:

https://localhost:4848

you’ll be redirected and served a page that looks like:

Go ahead and click the here link which will bring you to the page:

Which, when the GlassFish rebooting is finished, will automatically bring you to the login page:

Logging in with the username admin and the password that you just established should/will bring you to your admin home page:

Way cool!  You’re now running your GlassFish server securely.   :-)

Step 5 – Turning on your database

Within the GlassFish environment, no database is turned on by default.  As such, you must physically turn on the database of your choice.  There are many databases to choose from.  The simplest (but least capable to handle large amounts of traffic gracefully) is the javadb database that is included within the GlassFish v3 install.  If you cd over to where the javadb resides using:

cd /opt/glassfish/current

and then through executing the statement:

ls -l

you’ll see something like:

drwxr-xr-x  2 root root 4096 Mar 10 14:50 bin

drwxr-xr-x 10 root root 4096 Dec  2 22:24 glassfish

drwxr-xr-x  4 root root 4096 Dec  2 22:51 javadb

drwxr-xr-x  5 root root 4096 Dec  2 22:56 mq

drwxrwxr-x  4 root root 4096 Dec  2 22:29 pkg

Let’s, for simplicity sake, use the (default) built-in javadb for now.  To start the javadb, execute the commands:

su

asadmin start-database –dbhome /opt/glassfish/current/javadb

As the database starts up, there will be a ton of informative messages spewed to your console – the most important of which is the last line which should read:

Command start-database executed successfully.

At this point, your database is operating.  Testing of your database will be done in the next step.

Step 6 – Using the Hello World Application to test your GlassFish server and Database

As the name of this step implies, we’ll use an off-the-shelf known and simple application to test your new GlassFish environment. – Namely the packaged application “helloworld.war”.  This can be downloaded through the following link:

https://glassfish.dev.java.net/downloads/quickstart/hello.war

This link will download the hello.war file into your local system.

To upload this Grails web-app to your server, log into your GlassFish v3 administration Console and go to:

Applications

as shown:

Clicking on the button will bring you to:

Clicking the button will bring up a browser through which you can select the hello.war file that you just downloaded to your desktop system.  Once the war file has been selected, click the button, the GlassFish v3 Application Console will become embellished to look like:

Go ahead and accept the default settings and click the button to upload the application to the server.  Once the war file has been deployed to the server you’ll see something like:

The last step in birthing your helloworld application is to click on the helloworld’s Lanuch link under the Applications Action column to see:

Enter your name in the textbox:and click the  button to see:

Ta-daaaaa!  You’ve just successfully served up from your Linux server a grails-generated web page containing information formatted from the database.  Congratulations!

Step 6 – Packaging your Grails Application

In the previous step, we deployed a preexisting known functional web-app.  Most likely though, you’ll now be wanting to deploy a web-app of your own creation.  NetBeans is the IDE that I’m currently using for designing my Grails applications.  As such, if you right-click on the application name from the NetBeans hierarchy tree (left side of window) you’ll see the following contextual menu:

Just to be on the safe side, select the Clean-out-your-intermediate-files command as shown above to remove any possible intermediate files from the development environment.

Next we build the projects WAR file via highlighting the project name within the hierarchy tree window, and right click to bring up the following contextual menu:

And select the Build-the-WAR-file command as shown above.

When the Build-the-WAR-file process is running, you’ll see a bunch of information scrolled to your Output console window concluding with a statement such as:

Done creating WAR /Users/fletch/Projects/NetBeansProjects/myTest/myTest-0.1.war

This statement not only tells you that the building of the WAR file was successful, but where your newly created WAR file is located.  Using this newly created WAR file, redo Step 6 to deploy it into your GlassFish server.

Further Discussions 1 – Exceeding JVM Memory Capacity

When deploying small files, the default configuration of GlassFish is sufficient.  However, the WAR file of my relatively large web-app was over 300MBytes which exceeded the default GlassFish environment’s JVM heap capacity.  The error messages that were produced were quite cryptic but at one error message snippet that I was able to get traction with was:

java.lang.OutOfMemoryError: GC overhead limit exceeded

This became the clue as to how to overcome my size limitation.  It turns out that GlassFish v3 defaults to a Java Virtual Machine (JVM) heap size of 512 MBytes.  Although the default JVM heap size is larger than my WAR file, there must be other GlassFish processes that are taking up space within the Java environment.  The changing of the JVM heap size configuration to something larger can be done via the graphical GlassFish v3 Administration Console.  From within the GlassFish v2 Administration Console open up:

Configuration –> JVM Settings –> JVM Options

As shown below:

Modify the JVM heap size settings from 512 MBytes (-Xmx512m) to 2048 MBytes (-Xmx2048m) as shown below:

And press the button to introduce a new JVM parameter entry location as shown below:

Enter the JVM heap size setting to be 2048 MBytes (-Xms2048m) as shown below:

For these new JVM settings to take effect, you’ll need to click the button producing:

Notice that there’s a new message on the top left of the screen that says:  

This message is also an active link.  Go ahead and click the link which will bring you to:

Clicking the button will, as expected, reboot the GlassFish environment.

Further Discussions 2 – When GlassFish v3 goes wiggy on you

Sometimes, when attempting to stop or restart one of your web-apps, GlassFish will respond with a not-so-helpful message.

There are two nuclear options available to you — The lessor of the two, Redeploying your web-app;  And the more traumatic normal (or possibly even forced) restarting of GlassFish.  We’ll first go through the act of redeploying your web-app…

Although the first attempt at redeploying your web-app should be via the app’s redeploy button.  Being that GlassFish has lost the ability to stop the app though, you’ll get another less-than-helpful message such as:

Upon attempting to stop GlassFish via:

su

asadmin stop-domain

you’ll also get a not-so-helpful “a problem occurred” message.  The nuclear option here is to do (while still as root) a:

ps aux | grep glassfish

command through which you’ll be presented something like:

root     14004  2.9 86.9 2711176 1791612 ?     Sl   10:00   2:50 /opt/java/jdk1.6.0_18/bin/java -cp /opt/glassfish/glassfishv3/glassfish/modules/glassfish.jar -XX:+UnlockDiagnosticVMOptions -XX:MaxPermSize=192m -XX:NewRatio=2 -XX:+LogVMOutput -XX:LogFile=/opt/glassfish/glassfishv3/glassfish/domains/domain1/logs/jvm.log -Xms2048m -Xmx2048m -client -javaagent:/opt/glassfish/glassfishv3/glassfish/lib/monitor/btrace-agent.jar=unsafe=true,noServer=true -Dosgi.shell.telnet.maxconn=1 -Djdbc.drivers=org.apache.derby.jdbc.ClientDriver -Dfelix.fileinstall.dir=/opt/glassfish/glassfishv3/glassfish/modules/autostart/ -Djavax.net.ssl.keyStore=/opt/glassfish/glassfishv3/glassfish/domains/domain1/config/keystore.jks -Dosgi.shell.telnet.port=6666 -Djava.security.policy=/opt/glassfish/glassfishv3/glassfish/domains/domain1/config/server.policy -Dfelix.fileinstall.poll=5000 -Dcom.sun.aas.instanceRoot=/opt/glassfish/glassfishv3/glassfish/domains/domain1 -Dcom.sun.enterprise.config.config_environment_factory_class=com.sun.enterprise.config.serverbeans.AppserverConfigEnvironmentFactory -Dosgi.shell.telnet.ip=127.0.0.1 -Djava.endorsed.dirs=/opt/glassfish/glassfishv3/glassfish/modules/endorsed:/opt/glassfish/glassfishv3/glassfish/lib/endorsed -Dcom.sun.aas.installRoot=/opt/glassfish/glassfishv3/glassfish -Djava.ext.dirs=/opt/java/jdk1.6.0_18/lib/ext:/opt/java/jdk1.6.0_18/jre/lib/ext:/opt/glassfish/glassfishv3/glassfish/domains/domain1/lib/ext -Dfelix.fileinstall.bundles.new.start=true -Djavax.net.ssl.trustStore=/opt/glassfish/glassfishv3/glassfish/domains/domain1/config/cacerts.jks -Dcom.sun.enterprise.security.httpsOutboundKeyAlias=s1as -Djava.security.auth.login.config=/opt/glassfish/glassfishv3/glassfish/domains/domain1/config/login.conf -DANTLR_USE_DIRECT_CLASS_LOADING=true -Dfelix.fileinstall.debug=1 -Dorg.glassfish.web.rfc2109_cookie_names_enforced=false -Djava.library.path=/opt/glassfish/glassfishv3/glassfish/lib:/opt/java/jdk1.6.0_18/jre/lib/amd64/server:/opt/java/jdk1.6.0_18/jre/lib/amd64:/opt/java/jdk1.6.0_18/lib/amd64:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib com.sun.enterprise.glassfish.bootstrap.ASMain -domainname domain1 -asadmin-args start-domain -instancename server -verbose false -debug false -asadmin-classpath /opt/glassfish/current/glassfish/modules/admin-cli.jar -asadmin-classname com.sun.enterprise.admin.cli.AsadminMain -upgrade false -domaindir /opt/glassfish/glassfishv3/glassfish/domains/domain1 -read-stdin true

root     17283  0.0  0.0  61160   748 pts/0    S+   11:37   0:00 grep glassfish

This kind-of-scary output is merely telling you that there are two GlassFish=related processes found on your server — processes 14004 and 17283.  The second process is just the grep statement which is producing this output.  The first process is your GlassFish application running amok.  Thus, as mentioned before, the nuclear option is to just kill GlassFish with the command (as root):

kill 14004

To verify that you have successfully stopped the GlassFish process, run the following statement again:

ps aux | grep glassfish

And you should now see only the grep statement running.  Sometimes, the simple kill statement won’t kill the process.  To REALLY force the process to stop, you can use:

kill -9 14004

This statement grants the kill command the highest authority possible and will override everything.

Then restart GlassFish with the command (as root):

asadmin start-domain

When your GlassFish environment finishes starting back up, your applications that were running before should be back on line.