GlassFish 4.* Installation


These notes describe installation of GlassFish 4.* — the reference implementation of Java EE 7 — on a Debian or Ubuntu system. The Java SE Development Kit (version 7, or later) is assumed to be installed already. Users who prefer to download the bundle containing both JavaSE and GlassFish will need to make adjustments to Steps 2 and 3 below.

It is simple and tempting to install GlassFish in your own directory (for convenience), or to switch to superuser and install it in a more public space. Many other tutorials take one of these easy options. However the aim of this tutorial is to take a somewhat more sophisticated approach — one with clear security benefits. For this reason we take the more tricky route of installing GlassFish under the ownership of a pseudo-user 'glassfish' who has quite limited rights. This is a good impediment to hackers. We also touch on certificates and administration matters.

This document is the result of performing several installations of GlassFish. It is more of a recipe than a tutorial. Feel free to write to me if you find errors, or if you notice serious omissions.

Table of contents:

  1. Setting up users
  2. Setting up environment variables
  3. Downloading and installing GlassFish
  4. Setting up an init.d script
  5. Autostart: activating init.d script
  6. Security configuration
  7. Maintaining GlassFish
  8. Programming for GlassFish
  9. Appendix: Private GlassFish installation

1. Setting up users

It is possible to install GlassFish under your own username: the advantage is personal convenience, but the disadvantage occurs when trying to make it accessible to the public. Conversely, it is possible to install GlassFish as root; however the advantages and disadvantages are then reversed. And both approaches are ugly from the perspective of security. Far better to create a user with restricted rights, and use that for running GlassFish. Once you have added such a user (let's say 'glassfish'), you might also want to add a new group (let's called it 'glassfish' too). This group can then be used to facilitate access for all users who will be allowed to administer GlassFish.

Below are the required user- and group-related commands. Customize them to suit your environment. In particular, choose whether to give the pseudo-user 'glassfish' a shell. Doing so facilitates administration — the .bashrc file can contain handy environment variables and aliases — however this is a security concern. To allay these concerns, it is possible deny GlassFish automatic access to any shell; and instead to invoke a shell and environment variables only if and when necessary. The present instructions have been tested both ways. Generally, these instructions assume that GlassFish has no default shell.

Add a new user called 'glassfish' with group 'glassfish'
sudo adduser --system --group --home /home/glassfish [--shell /bin/bash] glassfish

Enable an existing user to be a GlassFish administrator.  Repeat for additional users.
sudo usermod -a -G glassfish existingUser

##### NOTE! ######
# The user will need to login afresh, before this modification takes effect
# The user can check their group membership with:
groups       # List should include 'glassfish'

#        Undo:
# If we want to delete the user and group 'glassfish' (and optionally remove GlassFish too):
sudo deluser [--remove-home] glassfish
sudo delgroup glassfish

We now have a limited user, 'glassfish', who will be the owner of GlassFish. Note that this user has no login ability. But don't worry. Admin tasks will still be possible, thanks to group membership (which we have already set up) shared with administrators, and to the administration passwords and security realms that are part of GlassFish.

2. Setting up environment variables

See instructions elsewhere for installation of Java SE. (GlassFish 3.1 requires Oracle's JDK 1.6.0_22 or later; GlassFish 3.1.1 requires JDK 1.6.0_26 or later, including 1.7.0, GlassFish 3.1.2 requires JDK 1.6.0_31+ or 1.7.0_03+, GlassFish 4.0 requires JDK 1.7.0+) One of the consequences of installation should be addition of an environment variable pointing to its location, e.g. JAVA_HOME=/usr/java/jdk1.7.0_25, or similar.

GlassFish can be located anywhere. For the present installation we choose to locate it under /srv. (/opt would be another common choice.)

We must ensure that GlassFish administrators and developers can access Java SE+EE. This will enable them to complete the installation of GlassFish, and subsequently to perform compilations and administration tasks. Here is an example of the required additions to their .bashrc — although those users will certainly need to make adjustments to the following, to suit their own environment.

Java SE
export JAVA_HOME=/usr/java/jdk1.7.0_25                         # Or whatever
export JAVA_BINDIR="${JAVA_HOME}/bin"
echo $PATH | /bin/grep -q -v "${JAVA_BINDIR}"
if [ $? -eq 0 ]; then export PATH="${PATH}:${JAVA_BINDIR}"; fi

export GLASSFISH_PARENT=/srv/glassfish
export GLASSFISH_HOME=/srv/glassfish/glassfish
echo $PATH | /bin/grep -q -v "${GLASSFISH_HOME}/bin"
if [ $? -eq 0 ]; then export PATH="${PATH}:${GLASSFISH_HOME}/bin"; fi

The four environment variables are essential for doing anything with GlassFish web development or administatation, and appending $GLASSFISH_HOME/bin to $PATH (as suggested above) will give administrators convenient access to asadmin and other management and development tools. [There is just one other location that administrators might want to add to their $PATH, namely $GLASSFISH_PARENT/bin. This contains the two update tools, plus an alternative version of asadmin.]

GlassFish ought to be managable by certain favoured users, logged in as themselves. It should rarely be necessary for anyone to log in as user 'glassfish', and for this reason the home directory of the pseudo-user glassfish does not need any .profile or .bashrc file.

Enabling Derby

We commonly use the database Derby: it is supplied by default with both JavaSE and Glassfish. We will launch it as a daemon, listening on socket 1527. However, as of jdk1.7.0_51, Java programs like Derby are not allowed (by default) to claim such ports. It is deemed a security risk, but is very annoying for anyone just wanting to start Derby. The symptom is an error saying access denied ("" "localhost:1527" "listen,resolve").

One solution is to supply a Derby-specific policy file whenever starting the Derby server. I don't have a precise recipe, but it helps to know that most ways of launching Derby indirectly invoke scripts in $GLASSFISH_HOME/javadb/bin/ which reference the environment variable $DERBY_OPTS. This variable is usually undefined, but you are welcome to define it by doing something like the following, where someURL is a Derby-specific security policy file:

Tell Java to apply the nominated security file

A cruder but simpler solution is just to modify Java's default security policy. This is the file containing global policies, applicable to all Java programs, found at $JAVA_HOME/jre/lib/security/java.policy. Just insert the lines

// allows Derby to claim port 1527
permission "localhost:1527", "listen";

3. Downloading and installing GlassFish

Choosing amongst the many available versions of GlassFish is very confusing, as the differences are not explained properly. Also, the naming and numbering of Java products is annoyingly volatile. However the alternatives are, roughly, as follows:

What are the distinctions?

Embedded Glassfish: Embedded Glassfish offers a programmatic way to run EJBs in a container — great for unit tests. It was initially somewhat experimental and separate from standard Java EE/GlassFish downloads. That was the case for version 3.1, and up to version 3.2_b06. These versions can be found at Maven repositories like The Central Respository as org.glassfish.extras:glassfish-embedded-all:3.1, or org.glassfish.extras:glassfish-embedded-web:3.1. Now, however, the crucial API is fully absorbed into Glassfish, so embedded containers come for free. If you are a Maven user you will need to know that the new coordinates are org.glassfish.main.extras:glassfish-embedded-all:4.0 or similar.

Actually, it is not particularly critical which version you choose: all are free, and will quickly get you up and running. But I find the GlassFish zip from to be more to my taste, as I can manage installation and operation more directly. The zip version is required for this set of instructions.

Accordingly we will download the GlassFish zip installation file, and we will opt for the 'full' version, rather than the Web Profile. In the following set of commands we download it to /srv, unzip it there, modify ownership, and finally rename GlassFish's parent directory to /srv/glassfish/.

Switch to user 'root' and get GlassFish
sudo -i
cd /srv
# You may or may not need to set the environment variable http_proxy first.
unzip      # This creates /srv/glassfish4/*

Modify GlassFish's 'home' directory
mv /srv/glassfish4 /srv/glassfish     # or make a link

Ensure owner:group is glassfish:glassfish
chown -R glassfish:glassfish /srv/glassfish

Ensure the owner and group can execute/modify/read bin files, and autodeploy
chmod -R ug+rwx /srv/glassfish/bin/
chmod -R ug+rwx /srv/glassfish/glassfish/bin/
chmod -R ug+rwx /srv/glassfish/glassfish/domains/domain1/autodeploy/

Ensure others are not allowed to execute/modify/read bin files, nor autodeploy
chmod -R o-rwx /srv/glassfish/bin/
chmod -R o-rwx /srv/glassfish/glassfish/bin/
chmod -R o-w /srv/glassfish/glassfish/domains/domain1/autodeploy/

Finished with being 'root'

#        Undo:
# In case we want to delete GlassFish:
sudo rm -rf /srv/glassfish

At this point you can already start your GlassFish server. But do not forget to stop it again before you continue with the next steps. Here are the commands for starting and stopping GlassFish:

Now switch user to being 'glassfish'
sudo su --shell /bin/bash glassfish
whoami       # should say 'glassfish'

Start GlassFish and Derby
export AS_JAVA=/usr/java/jdk1.7.0_25             # Or whatever
/srv/glassfish/bin/asadmin start-domain domain1
Waiting for domain1 to start ....
Successfully started the domain : domain1
domain  Location: /srv/glassfish/glassfish/domains/domain1
Log File: /srv/glassfish/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.

/srv/glassfish/bin/asadmin start-database
Starting database in Network Server mode on host and port 1527.
--------- Derby Network Server Information --------
Version: CSS10090/ - (1344872)  Build: 1344872  DRDA Product Id: CSS10090
:          [other information]
Starting database in the background.
Log redirected to /srv/glassfish/glassfish/databases/derby.log.
Command start-database executed successfully.

# check the log, /srv/glassfish/glassfish/domains/domain1/logs/server.log

Stop GlassFish and Derby
/srv/glassfish/bin/asadmin stop-domain domain1
Waiting for the domain to stop .
Command stop-domain executed successfully.

/srv/glassfish/bin/asadmin stop-database
Fri Jun 14 09:43:30 EST 2013 : Connection obtained for host:, port number 1527.
Fri Jun 14 09:43:31 EST 2013 : Apache Derby Network Server - - (1344872) shutdown
Command stop-database executed successfully.

# check the log, /srv/glassfish/glassfish/domains/domain1/logs/server.log

Exit from being user 'glassfish'

4. Setting up an init.d script

Let's create an init script, to help start, stop and restart GlassFish easily. (I know that init.d is a bit old-fashioned, but upstart is still unfamiliar to me.) This script may be called manually, or else automatically during reboots and shutdowns. The file we need to create is /etc/init.d/glassfish. We will take this opportunity to start Derby too, and will use the asadmin tool for both jobs.

Create init script
sudo vi /etc/init.d/glassfish

Then insert the following:

#! /bin/sh
# Provides:          glassfish
# Required-Start:    $remote_fs $network $syslog
# Required-Stop:     $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Starts GlassFish
# Description:       Starts GlassFish application server
# We need this, since NetworkServerControl uses $JAVA_HOME to find java
export JAVA_HOME=/usr/java/jdk1.7.0_25                         # Or whatever
# We need this, since asadmin contains the line 'JAVA=${AS_JAVA}/bin/java'


case "$1" in
  echo "Starting GlassFish from $GLASSFISH"
  sudo -u glassfish -E "$GLASSFISH/bin/asadmin" start-database
  sudo -u glassfish -E "$GLASSFISH/bin/asadmin" start-domain domain1
  echo "Stopping GlassFish from $GLASSFISH"
  sudo -u glassfish -E "$GLASSFISH/bin/asadmin" stop-domain domain1
  sudo -u glassfish -E "$GLASSFISH/bin/asadmin" stop-database
  $0 stop
  $0 start
  echo "# GlassFish at $GLASSFISH:"
  sudo -u glassfish -E "$GLASSFISH/bin/asadmin" list-domains | grep -v Command
  sudo -u glassfish -E "$GLASSFISH/bin/asadmin" list-domains | grep -q "domain1 running"
  if [ $? -eq 0 ]; then
    sudo -u glassfish -E "$GLASSFISH/bin/asadmin" uptime | grep -v Command
    echo "\n# Deployed applications:"
    sudo -u glassfish -E "$GLASSFISH/bin/asadmin" list-applications --long=true --resources | grep -v Command
    echo "\n# JDBC resources:"
    sudo -u glassfish -E "$GLASSFISH/bin/asadmin" list-jdbc-resources | grep "jdbc/"
  echo "\n# Derby:"
  sudo -u glassfish -E "$DERBY_BIN/NetworkServerControl" ping | sed "s/^.* : //"
  echo "Usage: $0 {start|stop|restart|status}"
  exit 1

exit 0

Make the script executable. You can now start, stop or restart GlassFish manually via the init.d script:

Make the init script executable by root
sudo chmod ug+x /etc/init.d/glassfish

sudo /etc/init.d/glassfish start

sudo /etc/init.d/glassfish status

Do some tests (here, 'EXAMPLEDB' is some pre-existing database)
firefox http://localhost:8080/
firefox file:///srv/glassfish/javadb/index.html
java -jar $GLASSFISH_PARENT/javadb/lib/derbyrun.jar ij    # 'quit;'  to exit
java -jar "$GLASSFISH_PARENT/javadb/lib/derbyrun.jar" sysinfo
java -jar "$GLASSFISH_PARENT/javadb/lib/derbyrun.jar" dblook -d  jdbc:derby://localhost:1527/EXAMPLEDB

sudo /etc/init.d/glassfish restart
sudo /etc/init.d/glassfish stop

When GlassFish is started with this init.d script, the process will be owned by the user 'glassfish'. This is a major goal of our installation procedure, as this user has very limited authorization. (Indeed, user 'glassfish' is not even able to run the init.d script!)

5. Autostart: activating init.d script

Now ensure that GlassFish (and Derby) are run whenever the server is restarted.

Configure GlassFish for autostart on Ubuntu boot
sudo update-rc.d glassfish defaults

This is a good time to reboot, and to check that http://localhost:8080/ is showing up in your browser. You will also see from ps aux that the processes GlassFish and Derby are both owned by the pseudo-user 'glassfish'. This user is very limited: it has no login shell (see /etc/passwd), and even when you become that user via sudo su --shell /bin/bash glassfish you will find that you belong to no groups, other than 'glassfish'. This is as it should be.

However, we are not done yet. The server is currently running with a widely-known default administration password … Hopefully your firewall is blocking attackers! Fixing this vulnerability is the subject of the next section.

If we want to remove this init script:

#        Undo:
sudo /etc/init.d/glassfish stop
sudo update-rc.d -f glassfish remove
sudo rm /etc/init.d/glassfish

6. Security configuration

We shall now begin the configuration of GlassFish itself. For security, you should always run these steps: change the default passwords, enable https, change the default SSL certificate used for https etc. We shall also give attention to GlassFish obfuscation.

The first step is to switch to user 'glassfish' and set environment variables. This is a pre-requisite for all three of the following subsections.

Switch user to glassfish (and remain as this user throughout Step 6!)
sudo su --shell /bin/bash glassfish
# Or 'sudo -H -u glassfish -s'

Set up environment for user 'glassfish'
export AS_JAVA=/usr/java/jdk1.7.0_25        [essential for running asadmin]
export PATH="${PATH}":"${AS_JAVA}/bin"      [essential for running keytool]
#export PATH="${PATH}":/srv/glassfish/bin   [optional: facilitates running asadmin]


GlassFish maintains a separate master password and admin password. Both passwords are managed using the utility asadmin.

Our first step is to change the master password using asadmin change-master-password. GlassFish uses the master password to protect the domain-encrypted files from unauthorized access, i.e. the certificate store which contains the certificates for https communication. When GlassFish is starting up it tries to read such 'secured' files — and for this reason GlassFish needs to be provided with the master password during startup, either in an intertactive way or in a non-interactive way. We shall choose the non-interactive way: we want our GlassFish to start up as a daemon during each Ubuntu reboot, and prefer not to have to enter a password each time. To accomplish this we need to set the --savemasterpassword option to true. This option causes the master password to be stored in the file master-password in the parent of the domain's configuration directory, namely in $GLASSFISH_HOME/domains/domain1/.

Tip: Changing the master password will cause several changes. It will create a file $GLASSFISH_HOME/domains/domain1/master-password, as well as update three files in $GLASSFISH_HOME/domains/domain1/config/, namely domain-passwords, keystore.jks and cacerts.jks. If I do this carelessly, I often get a hard-to-recover-from error, "Keystore was tampered with, or password was incorrect", so I suggest backing-up these files before updating the master password. It may save you from a re-installation. [Another tip: If you are in deep trouble, then setting export AS_DEBUG=true may help.]
# Ensure that you are running as user 'glassfish'!!

Stop GlassFish
/srv/glassfish/bin/asadmin stop-domain domain1

Backup default passwords.
# In addition to the three shown:
# - add domains/domain1/master-password, if this exists
# - add domains/domain1/local-password, just for completeness
cd /srv/glassfish/glassfish
tar cf passwords.orig.tar domains/domain1/config/domain-passwords domains/domain1/config/keystore.jks domains/domain1/config/cacerts.jks

Change master password
/srv/glassfish/bin/asadmin change-master-password --savemasterpassword=true domain1
#     Enter the current master password>     [By default this is 'changeit']
#     Enter the new master password>         [e.g. 'myMasterPwd']
#     Enter the new master password again>
# After entering the new master password twice, there is a pause of several 
# seconds.  Then you will find new versions of 'master-password'
# 'domain-passwords' 'keystore.jks' and 'cacerts.jks'.

# Your chosen master password should unlock both keystores, and reveal
# two certificates in keystore.jks, and many additional ones in cacerts.jks.
keytool -list -v -keystore /srv/glassfish/glassfish/domains/domain1/config/keystore.jks [-storepass myMasterPwd]
keytool -list -v -keystore /srv/glassfish/glassfish/domains/domain1/config/cacerts.jks [-storepass myMasterPwd]

The next step is to change the administration password using asadmin change-admin-password. Because this command is a 'remote' command we need to ensure that GlassFish is running before we can execute the command. Also, we probably want to grant password-less logins to some users; and so we shall also generate an admin password file (named .gfclient/pass).

Ensure that you are running as user 'glassfish'!!

Start GlassFish
/srv/glassfish/bin/asadmin start-domain domain1

Change admin password
/srv/glassfish/bin/asadmin change-admin-password
#     Enter admin user name [default: admin]>     [Just press Enter]
#     Enter admin password>         [By default this is blank, so just press Enter]
#     Enter new admin password>     [Must contain at least 8 chars (e.g. 'myAdminPwd')]
#     Enter new admin password again>
# There will now be a new version of '$GLASSFISH_HOME/domains/domain1/config/admin-keyfile'

Store admin password, to enable automatic login to localhost:4848
/srv/glassfish/bin/asadmin [--host localhost --port 4848] login
# Enter admin user name [Enter to accept default]>      [Just press Enter]
# Enter admin password>                                 [e.g. 'myAdminPwd']
# Login information relevant to admin user name [admin] for host [localhost] and admin port [4848] stored at [/home/glassfish/.gfclient/pass] successfully.
# Make sure that this file remains protected. Information stored in this file will be used by administration commands to manage associated domain.
# Command login executed successfully.

Stop GlassFish
/srv/glassfish/bin/asadmin stop-domain domain1

The file /home/glassfish/.gfclient/pass is handy: it may be copied to the home directory of the GF administrator, who will then be able to run asadmin without entering the password. After copying the file to the home directory of some GF administrator, ensure it is owned that user: chown gf_admin:glassfish ~gf_admin/.gfclient/pass. The group ownership for this file is irrelevant, and its permissions should obviously be limited to -rw-------.


GlassFish comes with two pre-configured server certificates that can be used for SSL (i.e. for the https: protocol). They are contained in keystore.jks, and have the aliases s1as and glassfish-instance. However this means that everybody knows these two certificates: the public keys, private keys, etc., so anyone can capture and read data sent to GlassFish even via https. Accordingly, be sure to replace the pre-configured s1as and glassfish-instance entries in your keystore.

The following code box shows you the commands needed for modifying our GlassFish keystores. We first update and extend keystore.jks. We then generate new certificates for s1as and glassfish-instance and import them into cacerts.jks — the 'truststore' used by SSL. The latter keystore contains a large number of trusted certificates, as well as our two newly-minted certificates. See elsewhere for how to obtain certificates from trusted sources, and add them to cacerts.jks.

# Ensure that you are running as user 'glassfish'!!
# Ensure GlassFish is stopped

Inspect keystore.jks
cd /srv/glassfish/glassfish/domains/domain1/config/
$AS_JAVA/bin/keytool -list -keystore keystore.jks -storepass myMasterPwd

Update keystore.jks
$AS_JAVA/bin/keytool -delete -alias s1as               -keystore keystore.jks -storepass myMasterPwd
$AS_JAVA/bin/keytool -delete -alias glassfish-instance -keystore keystore.jks -storepass myMasterPwd
$AS_JAVA/bin/keytool -genkeypair -alias s1as               -dname "CN=serverDomainName,OU=someUnit,O=someOrg,L=someCity,S=someState,C=XX" -keyalg RSA -keysize 2048 -validity 3650 -keystore keystore.jks -keypass myMasterPwd -storepass myMasterPwd
$AS_JAVA/bin/keytool -genkeypair -alias glassfish-instance -dname "CN=serverDomainName,OU=someUnit,O=someOrg,L=someCity,S=someState,C=XX" -keyalg RSA -keysize 2048 -validity 3650 -keystore keystore.jks -keypass myMasterPwd -storepass myMasterPwd

Check keystore.jks
$AS_JAVA/bin/keytool -list -keystore keystore.jks -storepass myMasterPwd

Export certificates from keystore.jks
$AS_JAVA/bin/keytool -exportcert -alias s1as               -file s1as.cert               -keystore keystore.jks -storepass myMasterPwd
$AS_JAVA/bin/keytool -exportcert -alias glassfish-instance -file glassfish-instance.cert -keystore keystore.jks -storepass myMasterPwd

Update cacerts.jks
$AS_JAVA/bin/keytool -delete -alias s1as                                                 -keystore cacerts.jks -storepass myMasterPwd
$AS_JAVA/bin/keytool -delete -alias glassfish-instance                                   -keystore cacerts.jks -storepass myMasterPwd
$AS_JAVA/bin/keytool -importcert -alias s1as               -file s1as.cert               -keystore cacerts.jks -storepass myMasterPwd
Trust this certificate? [no]:         [Enter 'yes']
$AS_JAVA/bin/keytool -importcert -alias glassfish-instance -file glassfish-instance.cert -keystore cacerts.jks -storepass myMasterPwd
Trust this certificate? [no]:         [Enter 'yes']

Check cacerts.jks and tidy up
$AS_JAVA/bin/keytool -list -keystore cacerts.jks -storepass myMasterPwd
rm s1as.cert glassfish-instance.cert

What do these two similar-sounding keystores do? They are indeed similar, but are used in a complementary way:

JVM Options and Obfuscations

Now we want to enable https for the admin console. Once we have done that we can be sure that nobody can decrypt data sent via https, since nobody else has our certificate. But this is not all we want to do here: we also want to change some of the default JVM Options, and we want to make our GlassFish not reveal too much about itself ('obfuscation').

The most likely JVM options to change are those to do with memory allocation, namely the initial (-Xmsn) and the maximum (-Xmxn) size of the memory allocation pool. Below we demonstate how to modify these two options. For more information about JVM options check the documentation for the java launcher.

Obfuscation is often considered worthwhile. In order to suppress HTTP reponse header lines like Server: GlassFish Server Open Source Edition 4.0 it is a good idea to specify asadmin create-jvm-options as an additional JVM option.

Similarly, we don't want GlassFish to send a header saying X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7). We can disable sending 'X-Powered-By' in the http/https headers with the three asadmin set commands in the code box below. Now our GlassFish is working in silent mode. Obfuscation accomplished.

Ensure that you are running as user 'glassfish'!!

# The commands here change the file at
# /srv/glassfish/glassfish/domains/domain1/config/domain.xml

First we have to start GlassFish
/srv/glassfish/bin/asadmin start-domain domain1

Enable https for remote access to admin console
# Requests to http://xxx:4848 are redirected to https://xxx:4848
/srv/glassfish/bin/asadmin set
/srv/glassfish/bin/asadmin enable-secure-admin

List current JVM options
/srv/glassfish/bin/asadmin list-jvm-options

Change JVM Options
# GlassFish 3.1.1 and earlier....
# Now update some important JVM settings.   (Adding '--' is a workaround for
# bugs #16037 and #16770, which cause certain options to be misinterpreted.
# The bug is largely fixed in GlassFish 3.1.1.)
/srv/glassfish/bin/asadmin delete-jvm-options -- -client
/srv/glassfish/bin/asadmin create-jvm-options -- -server
/srv/glassfish/bin/asadmin delete-jvm-options -- -Xmx512m
/srv/glassfish/bin/asadmin create-jvm-options -- -Xmx2048m
/srv/glassfish/bin/asadmin create-jvm-options -- -Xms1024m

# GlassFish 3.1.2 and later....
# Now update some important JVM settings.  (Option '-server' is now 
# practically the default, so we won't bother setting it explicitly.)
/srv/glassfish/bin/asadmin delete-jvm-options -Xmx512m
/srv/glassfish/bin/asadmin create-jvm-options -Xmx2048m
/srv/glassfish/bin/asadmin create-jvm-options -Xms1024m

Restart to take effect
/srv/glassfish/bin/asadmin stop-domain domain1
/srv/glassfish/bin/asadmin start-domain domain1

Check JVM options
# What JVM options are configured now?  (Confirm trust, if prompted.)
/srv/glassfish/bin/asadmin list-jvm-options

Check HTTP headers
# Check HTTP response headers (as shown below) to make sure that there are
# clues as to the server or its version.  Look for any mention of
# 'GlassFish', 'X-Powered-By', etc.  If necessary:
/srv/glassfish/bin/asadmin create-jvm-options
/srv/glassfish/bin/asadmin set
/srv/glassfish/bin/asadmin set
/srv/glassfish/bin/asadmin set

Check Error pages
# Want to show something other than default 404 page-not-found response 
# (which tend to be rather too revealing....)? 
# 1 It is possible to create 404 error pages that are application-specific
#   by editing that application's web.xml file, and adding an
#   element like
#   <error-page>
#       <error-code>404</error-code>
#       <location>/404.html</location>
#   </error-page>
# 2a It is possible to create 404 error pages that are global to the server
#    by editing the server's domain.xml file, and adding a property having
#    name="send-error_1" 
#    value="code=404 path=/tmp/404.html reason=Resource_not_found"
# 2b Or by executing a command like
#       asadmin set"code=404 path=/tmp/404.html reason=Resource_not_found"
# 2c Or by using the admin console to add a new property 'send-error_1'
#    with a value "code=404 path=/tmp/404.html reason=Resource_not_found"

We are done with user 'glassfish'.

Click here How to check HTTP headers

If we want to remove these security and configuration tweaks, start GlassFish, become user 'glassfish' (although this is unnecessary if you have the .gfclient/pass file), and enter:

#        Undo:
# Disable https for remote access to admin console
/srv/glassfish/bin/asadmin set
/srv/glassfish/bin/asadmin disable-secure-admin

# Restore default JVM Options
/srv/glassfish/bin/asadmin delete-jvm-options -- -Xmx2048m
/srv/glassfish/bin/asadmin create-jvm-options -- -Xmx512m
/srv/glassfish/bin/asadmin delete-jvm-options -- -Xms1024m

7. Maintaining GlassFish

Finally: we have installed, secured and configured our GlassFish installation. Now it has to be managed …

Starting and stopping GlassFish and Derby
# Any sudoer can do this, and the services will be owned by user 'glassfish'
sudo /etc/init.d/glassfish [start | stop | restart | status]

Monitor logs.  Should any user be able to view server.log??
less +F /srv/glassfish/glassfish/domains/domain1/logs/server.log
less +F /srv/glassfish/glassfish/databases/derby.log

Explore asadmin, doing so here as user 'glassfish'
sudo su --shell /bin/bash glassfish
export AS_JAVA=/usr/java/jdk1.7.0_25                         # Or whatever
/srv/glassfish/bin/asadmin list-commands

Test of the administrator's group membership, $PATH and copy of .gfclient/pass
asadmin list-commands
asadmin list-applications
asadmin list-jvm-options  To see all system properties: sudo $JAVA_HOME/bin/jinfo PID_of_GF

# If GlassFish was installed from a zip, then updatetool and pkg exist only
# as stubs -- however the missing bits will be downloaded and 
# installed when the stubs are first run.  If GlassFish was installed
# from a self-extracting executable, then updatetool and pkg will already
# be fully installed.
# See also the GlassFish Runtime Administration Guide at 

Before updating, we must halt GlassFish and Derby
sudo /etc/init.d/glassfish stop

Running 'pkg', the text-based updater
sudo su --shell /bin/bash glassfish     # Switch to being user 'glassfish'
export AS_JAVA=/usr/java/jdk1.7.0_25                         # Or whatever
/srv/glassfish/bin/pkg -R /srv/glassfish [list | info | history]
/srv/glassfish/bin/pkg -R /srv/glassfish image-update -v
exit                                    # Revert to being yourself

Running 'updatetool', the GUI-based updater
# It is hard to manage permissions when we want to be the user 'glassfish' 
# when updating files; yet we must be a regular user to be able to access 
# the current desktop session. 
# The  solution is to grant 'glassfish' access to the X11 session before 
# running updatetool as that user.  This is done with the 'xhost' command.
xhost +SI:localuser:glassfish          # Run this first, as yourself, not as user 'glassfish'
sudo su --shell /bin/bash glassfish    # Switch to being user 'glassfish'
export AS_JAVA=/usr/java/jdk1.7.0_25                         # Or whatever
exit                                   # Revert to being yourself
xhost -SI:localuser:glassfish          # Run this last, as yourself, not as user 'glassfish'

Restart GlassFish and Derby
sudo /etc/init.d/glassfish start

Backing-up can be done crudely by saving everything under $GLASSFISH_PARENT/ (including raw database files) — or it could be done more selectively. In the latter case, the crucial backups are:

Click here How to access a Derby DB with ij or DbVisualizer

Brief instructions for fronting GlassFish with an Apache server are available at

Thirsty for more detailed information?

Your installation contains more information, such as $GLASSFISH_HOME/docs/quickstart.html. There is more about Java EE (i.e. the specification) at, and more about GlassFish (i.e. the implementation) at

8. Programming for GlassFish

A good starting point is the official Java EE tutorial.

There are several options for progamming environments: Eclipse, NetBeans, and Emacs (of course). Users of Eclipse might like to check this introductory tutorial:, which describes how to deploy and debug a servlet from within version 3.6 (aka 'helios') of Eclipse to GlassFish 3.1.x. As of June 2013 there is support for GlassFish 4.0 in Eclipse 4.3 ('kepler'): see for the current status.

Fancy environments have their appeal, however programming web apps is not so very different from desktop apps. Indeed there are only two configuration-related things that a programmer needs to know in order to build and deploy Java EE web apps:

  1. /srv/glassfish/glassfish/modules/ This is where all the Java EE jar files are located.
  2. /srv/glassfish/glassfish/domains/domain1/autodeploy/ This is the place to drop your .war file.

If you prefer to rely on Maven for managing packages, then you just need to know about Java EE 7 coordinates at Maven Central. These will get you going:

GlassFish 4.0-bxx

Java EE 7.x
    <artifactId>javaee-api</artifactId>     Or possibly javaee-web-api

Securing GlassFish was discussed above, but securing web apps is another matter. A good starting point might be this blog by Markus Eisele. It describes how to add username/password authentication to a web app.

Appendix: Private GlassFish installation

Here is a sketch of what to do for a private installation.

The general plan is to unpack the GlassFish distro in your personal directory space, and to start and stop the server manually. In this example we choose to place GlassFish in $HOME/glassfish4, and to advertise this by setting environment variables appropriately.

GlassFish environment
export GLASSFISH_PARENT="$HOME/glassfish4"
export GLASSFISH_HOME="$HOME/glassfish4/glassfish"
echo $PATH | /bin/grep -q -v "$GLASSFISH_HOME/bin"
if [ $? -eq 0 ]; then export PATH="$PATH:$GLASSFISH_HOME/bin"; fi

To download and install GlassFish, follow the instructions above in 3. Downloading and installing GlassFish. The difference is the base directory, and everything to do with user names.

cd ~/Downloads
mv glassfish4 ~

Now you can start and stop the server by

asadmin start-domain domain1
asadmin stop-domain domain1
Acknowledgement: Some parts, particularly within Section 6, more-or-less follow the tutorial, that appeared in April 2011. This is a clear and frequently-updated installation guide, and is highly recommended.