This tutorial is for setting up ORACLE Glassfish v3 with virtual hosting where one Glassfish domain exists for every one name based virtual host.  The web has a number of articles that discuss virtual hosting using one Glassfish domain. This is a good solution if:

  • all the applications being deployed are written by the same developer team, so there is no need to isolate each developer group’s environment
  • there is no need to separate each application into its own JVM

The rationale behind jailing a glassfish domain for an httpd virtual host is to provide an isolated JVM instance and administrative environment for each group of developers on the same server. This tutorial uses CentOS/RHEL 5.5, and was tested on RHEL >5.3.

This example walks you through configuring a server with two virtual hosts.

To accomplish this task, we need:

  • jdk 1.6 (openjdk 1.6 will work)

  • apache 2.2 name based virtual hosts set up
  • put name based virtual host directives into a separate file for clarity(vhosts.conf)
  • mod_jk

  • glassfish v3


As root configure httpd/mod_jk:

  1. download and configure mod_jk, the apache jakarta connector
    1. create worker definition file
    2. create httpd configuration file specific to mod_jk
    3. tie mod_jk workers to virtual host directives
  2. create group jee and user glassfish
  3. edit firewall rules to allow web console access (tcp 4848, 4849)

Authenticate as the newly created glassfish user

  1. download and unzip glassfish v3
  2. set up user environment (.bash_profile)
  3. configure/create domains
    1. add jk listener to domain1 on 8009
    2. create domain2
    3. add jk listener to domain2 on 8010

Authenticate again as root

  1. create and test initialization daemon
  2. restart httpd

Words of Caution

Remember OSGi
Where to look in case of a problem

Let us begin

Authenticate as the root user
The apache jakarta connector ( is missing from CentOS’ after a fresh install, i was also unlucky in finding it using yum.
Fortunately the apache foundation has pre-compiled binaries of mod_jk for major OS distributions (there is available source code for custom compiles) here :

Download a current version of mod_jk that suits your distribution and move it into httpd’s module directory.

# mv /etc/httpd/modules/

Create a workers property file in httpd’s extra configuration directory:

# vi /etc/httpd/conf.d/

# Define 2 workers using ajp13
worker.list=worker1, worker2
# Set properties for worker1 (ajp13)
# Set properties for worker2 (ajp13)

create a file called jk.conf in /etc/httpd/conf.d/

# vi /etc/httpd/conf.d/jk.conf


LoadModule jk_module modules/
# Where to find the worker definitions
JkWorkersFile /etc/httpd/conf.d/
# Where to put jk logs
JkLogFile /var/log/httpd/mod_jk.log
# Set the jk log level [debug/error/info]
JkLogLevel debug
# Select the log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
# JkOptions indicate to send SSL KEY SIZE,
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
# JkRequestLogFormat set the request format
JkRequestLogFormat "%w %V %T"

Add the JkMount directive JkMount /* worker1 to vhosts.conf. The /* means that we are forwarding all traffic directed to the virtual host to the respective worker process called worker1 which we defined in the file.

# vi /etc/httpd/conf.d/vhosts.conf

NameVirtualHost *:80
NameVirtualHost *:443
# NOTE: NameVirtualHost cannot be used without a port specifier
# (e.g. :80) if mod_ssl is being used, due to the nature of the
# SSL protocol.
# VirtualHost example:
# Almost any Apache directive may go into a VirtualHost container.
# The first VirtualHost section is used for requests without a known
# server name.
    ServerAlias bar
    JkMount /* worker1
    ServerAlias foo
    JkMount /* worker2

At this point we are finished with basic configuration for mod_jk and httpd virtual hosts. We are creating a restricted user that will house Glassfish AS v3.

# /usr/sbin/groupadd jee

# /usr/sbin/useradd -m -g jee  glassfish

# passwd glassfish

Let’s authenticate as the glassfish user, download and perform basic setup for glassfish.

# su - glassfish

$ wget

$ unzip

The following change to .bash_profile is for accessing binaries in the glassfish/bin folder without specifying their full path.
$ vi .bash_profile


$ . ./.bash_profile (or log-out and log-in again)

$ which asadmin (This should return the full path of the asadmin tool, i.e. /home/glassfish/glassfishv3/bin/asadmin)

log-out as the glassfish user

$ exit

Authenticate as the root user again (if you performed su - glassfish you just changed user back to the root user)

Next we open TCP ports for the Glassfish admin console. By default the initial domain’s admin console responds on port 4848.

# vi /etc/sysconfig/iptables and add 4848 and 4849

# /sbin/service iptables restart

Let us authenticate as the glassfish user again to set up the two domains for creating a glassfish mod_jk listener and tying it to the defined worker threads.

# su - glassfish

$ asadmin start-domain domain1

We are adding a http listener called jk-connector-8009 to the admin console corresponding to domain1 (which is denoted by the --port 4848 option), the --listenerport 8009 option specifies which port the listener should listen on, and are specifying that the listener is of type jk-listener.

$ asadmin --user admin --host localhost --port 4848 create-http-listener --listeneraddress --listenerport 8009 --defaultvs server jk-connector-8009

$ asadmin --user admin --host localhost --port 4848 set

Let us create a second domain called domain2 that the virtual host bar will route requests to.

$ asadmin create-domain --portbase 4801 --profile developer domain2

The portbase option above signals the asadmin tool the ports it should allocate for all its components (admin console listener, http listener, etc.). Specifying --portbase 4801 means that the admin tool will set up the admin console to respond on port (4801+48)=4849. With a little bit of google-ing, you can find the rest of the port rules. For our purposes this is all we need to access the admin console for domain2, provided of course that you opened port 4849 using iptables.

$ asadmin start-domain domain2

$ asadmin --user admin --host localhost --port 4849 create-http-listener --listeneraddress --listenerport 8010 --defaultvs server jk-connector-8010

$ asadmin --user admin --host localhost --port 4849 set

Authenticate as root again to create an initialization script and set it up as a service spawned at runlevel 3.

# vi /etc/init.d/glassfish

# glassfish:          Startup script for Glassfish Application Server.
# chkconfig: 3 80 05
# description:      Startup script for domain1 of Glassfish Application Server.
start() {
        echo -n "Starting Glassfish: "
        echo "Starting Glassfish at `date`" >> $GLASSFISH_HOME/domains/domain1/logs/startup.log
        echo "Starting Glassfish at `date`" >> $GLASSFISH_HOME/domains/domain2/logs/startup.log
        su $GLASSFISH_OWNER -c "$GLASSFISH_HOME/bin/asadmin start-domain domain1" >> $GLASSFISH_HOME/domains/domain1/logs/startup.log
        su $GLASSFISH_OWNER -c "$GLASSFISH_HOME/bin/asadmin start-domain domain2" >> $GLASSFISH_HOME/domains/domain2/logs/startup.log
        sleep 2
        echo "done"
stop() {
        echo -n "Stopping Glassfish: "
        echo "Stopping Glassfish at `date`" >> $GLASSFISH_HOME/domains/domain1/logs/startup.log
        echo "Stopping Glassfish at `date`" >> $GLASSFISH_HOME/domains/domain2/logs/startup.log
        su $GLASSFISH_OWNER -c "$GLASSFISH_HOME/bin/asadmin stop-domain domain1" >> $GLASSFISH_HOME/domains/domain1/logs/startup.log
        su $GLASSFISH_OWNER -c "$GLASSFISH_HOME/bin/asadmin stop-domain domain2" >> $GLASSFISH_HOME/domains/domain2/logs/startup.log
        echo "done"
# See how we were called.
case "$1" in
                echo $"Usage: glassfish {start|stop|restart}"

Notice that you need to edit the GLASSFISH_OWNER and GLASSFISH_HOME variables if you chose different locations/usernames in your setup. If you have named your domains differently, don’t forget to modify the lines in the script that contain domain1 and domain2. Note that you need to startup and shutdown each domain separately.

Let us make this script executable, and add it as a service to be spawned at runlevel 3.
# chmod +x /etc/init.d/glassfish

# chkconfig --add glassfish

# chkconfig --level 3 glassfish on

Let’s test the service we just created by using it to bounce glassfish.
# /etc/init.d/glassfish stop

# /etc/init.d/glassfish start

Fix possible errors, and if all went well, test httpd for syntax errors and virtual hosts:

# httpd -tS
If you get a Syntax OK along with a table of ports (80.*) listing the virtual hosts you defined restart httpd by:

# service httpd restart

If you get an initial 503 service unavailable error in your web-browser, call up the admin consoles at 4848 and 4949. This is because of OSGi. If there is no application deployed glassfish will not listen until at least the admin console is accessed because of lazy initialization. Calling up the admin console will fix this., or will correct this.

NOTE on Glassfish Admin Console Access

The admin console for both and will access the admin console for glassfish domain1.
Similarly, and will access the admin console for glassfish domain2.
In other words, the admin console will respond based on the port assigned to it regardless of the virtual host name.

NOTE on Security

Don’t forget to set administrator password for the admin console, otherwise anyone may access the console without authenticating first. This a potential security –Gaping Hole the size of the Grand Canyon– issue.
Making the admin console for all domains be available via https instead of the http protocol is a good idea as well, and it is a setting in the admin console’s listener configuration.

There are 2 rules for resolving errors


If you receive a 500 error in your browser, there is a problem with the configuration. To track the errors down, a good place to start are the httpd access and error logs as well as the mod_jk.log file you specified in the jk.conf file using the JkLogFile directive, you may also check whether httpd is listening on port 80 (http) and that iptables is allowing this port.

# netstat -an | grep 80

# tail -f /var/log/http/mod_jk.log

follow httpd 2.2 errors if restarted (google is an excellent tool)


If you think your configuration is flawless in spite of the 500 error, restart glassfish and httpd for good measure. If this does not help you, please refer to RULE ONE.

Reverting to Initial Configuration

Perform the following steps as the root user.

# userdel glassfish

# groupdel jee

# rm -rf /home/glassfish

# rm -f /etc/init.d/glassfish

# rm -f /etc/httpd/conf.d/jk.conf /etc/httpd/conf.d/

# rm -f /etc/httpd/modules/

# vi /etc/httpd/conf.d/vhosts.conf and remove the JkMount rules

# vi /etc/sysconfig/iptables and remove port 4848 and 4849 from accept rules

To check if httpd will start back up execute the commands below.

# httpd -t

# httpd -S
Finally, if all is copacetic, restart httpd.
# httpd -k restart

I hope that this post was helpful to you.


Posted by 신공표 트랙백 0 : 댓글 0

댓글을 달아 주세요