Start GlassFish 4 automatically on CentOS 6


The purpose of this post is to document how to start GlassFish 4 automatically whenever the server it is installed in reboots.

The VPS that is hosting my Oracle APEX installation rebooted without warning the other day (as should be expected of cheap services), which required me to personally SSH into the server to restart GlassFish.

The prospect of having to manually restart GlassFish every time the server reboots does not look appealing to me.  I need to find a way to make GlassFish start automatically on boot.

Using GlassFish create-service command

Run the command

The GlassFish 4 Administration Guide Page 3-13 clearly recommends the use of the built-in command called create-service in order to automatically start GlassFish when the server boots up.

Let’s try and see it in action.

[root@server ~]# $GLASSFISH_DIR/bin/asadmin
Use "exit" to exit and "help" for online help.
asadmin> create-service
Found the Linux Service and successfully uninstalled it.
The Service was created successfully. Here are the details:
Name of the service:domain1
Type of the service:Domain
Configuration location of the service:/etc/init.d/GlassFish_domain1
User account that will run the service: root
You have created the service but you need to start it yourself.  Here are the most typical Linux commands of interest:

* /etc/init.d/GlassFish_domain1 start
* /etc/init.d/GlassFish_domain1 stop
* /etc/init.d/GlassFish_domain1 restart

For your convenience this message has also been saved to this file: $GLASSFISH_DIR/glassfish/domains/domain1/PlatformServices.log
Command create-service executed successfully.
asadmin> exit
Command multimode executed successfully.

Attempt to start GlassFish service

It seemed that the command completed successfully.  Now let’s try to start the service.

[root@server ~]# /etc/init.d/GlassFish_domain1 start
[root@server ~]# /etc/init.d/GlassFish_domain1: line 54: $GLASSFISH_DIR/glassfish/lib/nadmin: Permission denied

Something is wrong in the script somewhere.  Let’s examine the contents of the init script created by the create-service command.

[root@server ~]# vi /etc/init.d/GlassFish_domain1

Review lines 50 to 64:


case "$1" in
    $ASADMIN start-domain    --domaindir $GLASSFISH_DIR/glassfish/domains  domain1 &
    $ASADMIN stop-domain   --domaindir /$GLASSFISH_DIR/glassfish/domains  domain1 &
    $ASADMIN restart-domain   --domaindir $GLASSFISH_DIR/glassfish/domains  domain1 &
    echo "usage: $0 (start|stop|restart|help)"

The path to the asadmin command is wrongly set in the script.  The correct path should be $GLASSFISH_DIR/bin/asadmin.  Changing this to the correct path should rectify the error.

Modify the script

Change line 50 as follows:


Start GlassFish service

The GlassFish server can now be started using the modified script.

[root@server ~]# service GlassFish_domain1 start
[root@server ~]# Waiting for domain1 to start .........................
Successfully started the domain : domain1
domain  Location: $GLASSFISH_DIR/glassfish/domains/domain1
Log File: $GLASSFISH_DIR/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.

Restart GlassFish service

The GlassFish server can also be restarted by the script.

[root@server ~]# service GlassFish_domain1 restart
[root@server ~]# Successfully restarted the domain
Command restart-domain executed successfully.

Stop GlassFish service

Last but not least, the script can stop the GlassFish domain.

[root@server ~]# service GlassFish_domain1 stop
[root@server ~]# Waiting for the domain to stop
Command stop-domain executed successfully.

Start GlassFish 4 automatically on reboot

In addition to creating the init.d script, the asadmin create-service command also creates symbolic links inside the rc*.d folders, which makes GlassFish start automatically on runlevels 3,4 and 5.

Problems with the script

Although the script created by the asadmin create-service command is functional, I am not quite satisfied with it for the following reasons:

No chkconfig support

Other scripts in the init.d folder can be managed via the chkconfig command.  You can set which runlevels you want to run your service in using this command.  However, the script created using the asadmin create-service command is not compatible with chkconfig.

[root@server ~]# chkconfig GlassFish_domain1 --list
service GlassFish_domain1 does not support chkconfig

No status checking

Other scripts in the init.d folder use the status operand to check the running status of the service.  For instance, for the Apache web server:

[hnizam@server ~]$ sudo service httpd status
httpd (pid  13365) is running...

Unfortunately, the script provided by the asadmin create-service command does not include the definition for the status operand.

[root@server ~]# service GlassFish_domain1 status
usage: /etc/init.d/GlassFish_domain1 (start|stop|restart|help)

GlassFish runs under root user

Finally, the way the script created by the asadmin create-service command is written makes GlassFish run under the root user ID.

If you installed GlassFish under a non-root non-privileged user, and wants the GlassFish process to run under this user ID, the script will not do this for you.


To start GlassFish 4 automatically every time the server boots up, you can use the asadmin create-service command.  However, on Centos 6 at least, the script created by the command will not work out of the box.  Some modifications need to be done on the script before it will work as intended.

Set up WordPress on CentOS

The purpose of this post is to document the steps to set up WordPress on a server.

The server operating system is going to be CentOS which currently is my preferred server operating system.

The final objective is to have a WordPress website accessible via

Perform operating system installation

First of all, the latest version of CentOS, which is 6.4, is installed on the server and the server is given the hostname  A minimal install is chosen to prevent unwanted programs to be installed, which can both be a security risk and a waste of disk space.

A non-root user is then created.

[root@server ~]# useradd hnizam
[root@server ~]# passwd hnizam
Changing password for user hnizam.
New password:<type password here>
Retype new password:<re-type password here>
passwd: all authentication tokens updated successfully.

This user is then given sudo permissions.

[root@server ~]# vi /etc/sudoers
## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
## Syntax:
##      user    MACHINE=COMMANDS
## The COMMANDS section may have other options added to it.
## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL
hnizam  ALL=(ALL)       NOPASSWD: ALL

This user is going to be used for all subsequent commands, to limit exposure on the root account.

The OS is then updated to the latest version.

[hnizam@server ~]$ sudo yum check-update

[hnizam@server ~]$ sudo yum upgrade

[hnizam@server ~]$ sudo shutdown -ry now

Check WordPress requirements

Now that the operating system is properly set up, it is time to begin the process of installing WordPress.  First, the requirements for installing WordPress should be reviewed.  At the time of writing, the current version of WordPress is 3.7.1 and according to the WordPress requirements page, the requirements for installing WordPress are:

  • PHP version 5.2.4 or greater
  • MySQL version 5.0 or greater
  • Web server capable of supporting the above (Apache or Nginx is recommended)

To enable pretty permalinks, the Apache module mod_rewrite is needed.

Apache is being chosen as the web server for this particular case as it is one of the earliest web servers and also one of the most used web server software.

Install web server (Apache)

Install the Apache software

The package group feature of the yum package manager is used to install the Apache web server software.

[hnizam@server ~]$ sudo yum grouplist | grep -i web
   Web Server
   Web Servlet Engine
   Web-Based Enterprise Management
[hnizam@server ~]$ sudo yum groupinstall "Web Server"

The Apache web server is installed as the httpd service.  The chkconfig command is used to enable the httpd service at server boot-up.

[hnizam@server ~]$ sudo chkconfig httpd --list
httpd           0:off   1:off   2:off   3:off   4:off   5:off   6:off
[hnizam@server ~]$ sudo chkconfig httpd on
[hnizam@server ~]$ sudo chkconfig httpd --list
httpd           0:off   1:off   2:on    3:on    4:on    5:on    6:off

Next, the Apache web server is started, and the ports used by the web server (port 80 for http and port 443 for https) is opened at the firewall to enable the web server to be accessed by the public.

[hnizam@server ~]$ sudo service httpd start
Starting httpd:                                            [  OK  ]
[hnizam@server ~]$ sudo iptables -L -vn
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
 1930  156K ACCEPT     all  --  *      *             state RELATED,ESTABLISHED
    3   236 ACCEPT     icmp --  *      *  
    0     0 ACCEPT     all  --  lo     *  
    1    60 ACCEPT     tcp  --  *      *             state NEW tcp dpt:22
   98 26516 REJECT     all  --  *      *             reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REJECT     all  --  *      *             reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT 1317 packets, 168K bytes)
 pkts bytes target     prot opt in     out     source               destination
[hnizam@server ~]$ sudo iptables -I INPUT 5 -m state --state NEW -p tcp --dport 80 -j ACCEPT
[hnizam@server ~]$ sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 443 -j ACCEPT
[hnizam@server ~]$ sudo iptables -L -vn
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
 2277  186K ACCEPT     all  --  *      *             state RELATED,ESTABLISHED
    3   236 ACCEPT     icmp --  *      *  
    0     0 ACCEPT     all  --  lo     *  
    1    60 ACCEPT     tcp  --  *      *             state NEW tcp dpt:22
    0     0 ACCEPT     tcp  --  *      *             state NEW tcp dpt:80
    0     0 ACCEPT     tcp  --  *      *             state NEW tcp dpt:443
  108 29500 REJECT     all  --  *      *             reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REJECT     all  --  *      *             reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT 5 packets, 920 bytes)
 pkts bytes target     prot opt in     out     source               destination
[hnizam@server ~]$ sudo service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]

Post-installation checks

At this point, the URLs and should be accessible, and the default CentOS Apache welcome page is shown when these URLs are opened in a browser.

Set up WordPress - CentOS Apache http welcome page

For the https page, the browser will show a certificate error, because the SSL certificate used by the default Apache installation is a self-signed certificate based on the hostname of the system.

Set up WordPress - Certificate error

The certificate error should be ignored as it is the expected behavior.  To make SSL work without the browser showing a certificate error will require acquiring a certificate from a certificate authority like VeriSign or Comodo, which is outside the scope of this post.  A welcome page similar to the one from the http page is shown after the certificate error is ignored:

Set up WordPress - CentOS Apache https welcome page

The details of the self-signed certificate is shown when the padlock with the red cross is clicked and then ‘Certificate information’ is clicked.  Notice that the ‘Issued to:’ and ‘Issued by:’ fields are the same, which confirms that it is a self-signed certificate.

Set up WordPress - Self-signed certificate details

Install database server (MySQL)

Now that the web server has been successfully installed, it is time to install the database server.

Install the MySQL software

The method used to install MySQL is the same as the method used to install Apache, which is via yum.

[hnizam@server ~]$ sudo yum grouplist | grep -i mysql
   MySQL Database client
   MySQL Database server
[hnizam@server ~]$ sudo yum groupinstall "MySQL Database server"

The MySQL database server is installed as the mysqld service.  The chkconfig command is used to enable the mysqld service at server boot-up.

[hnizam@server ~]$ sudo chkconfig mysqld --list
mysqld          0:off   1:off   2:off   3:off   4:off   5:off   6:off
[hnizam@server ~]$ sudo chkconfig mysqld on
[hnizam@server ~]$ sudo chkconfig mysqld --list
mysqld          0:off   1:off   2:on    3:on    4:on    5:on    6:off

Next, the mysqld service is started for the first time.

[hnizam@server ~]$ sudo service mysqld start
Initializing MySQL database:  Installing MySQL system tables...
Filling help tables...

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system

To do so, start the server, then issue the following commands:

/usr/bin/mysqladmin -u root password 'new-password'
/usr/bin/mysqladmin -u root -h password 'new-password'

Alternatively you can run:

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the manual for more instructions.

You can start the MySQL daemon with:
cd /usr ; /usr/bin/mysqld_safe &

You can test the MySQL daemon with
cd /usr/mysql-test ; perl

Please report any problems with the /usr/bin/mysqlbug script!

                                                           [  OK  ]
Starting mysqld:                                           [  OK  ]

Post-installation tasks

Now that the MySQL database server is installed and running, it is time to run the secure installation command as per advised by the MySQL first-time-start script.  The command offers to change the MySQL root password, remove anonymous user access to the MySQL database, and several other changes to help secure the database.

[hnizam@server ~]$ sudo /usr/bin/mysql_secure_installation


In order to log into MySQL to secure it, we'll need the current
password for the root user.  If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): <Enter>
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.

Set root password? [Y/n] Y
New password: mysqlrootpassword
Re-enter new password: mysqlrootpassword
Password updated successfully!
Reloading privilege tables..
 ... Success!

By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MySQL comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MySQL
installation should now be secure.

Thanks for using MySQL!

Install PHP

The next step is to install the PHP interpreter.

Install the PHP interpreter software.

Same as previously, the yum package manager is used to perform the installation.

[hnizam@server ~]$ sudo yum grouplist | grep -i php
   PHP Support
[hnizam@server ~]$ sudo yum groupinstall "PHP Support"

To be able to set up WordPress properly, the PHP-MySQL extension must also be installed.

[hnizam@server ~]$ sudo yum install php-mysql

Test PHP installation

To test whether the PHP interpreter is working correctly, first the web server needs to be restarted.

[hnizam@server ~]$ sudo service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]

Next, a test file containing the phpinfo() function is created in the web server root directory.

[hnizam@server ~]$ sudo vi /var/www/html/test.php

Now when the browser is set to or, a page with a lot of details about the system is shown similar to the screenshot below.

Set up WordPress - PHP info page

This indicates that the PHP installation is successful and that the PHP interpreter is working correctly with the web server.

The test file is then deleted.

[hnizam@server ~]$ sudo rm /var/www/html/test.php

Install and set up WordPress

With all the prerequisites now installed, it is time to install and set up WordPress itself, using the installation guide from the website.

Create the database and database user

A new database is created inside the installed MySQL database server to be used by WordPress and a new database user that owns the privileges to the new database is also created.

[hnizam@server ~]$ mysql -u root -p
Enter password: mysqlrootpassword
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.1.69 Source distribution

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database wordpressdb;
Query OK, 1 row affected (0.00 sec)

mysql> grant all privileges on wordpressdb.* to "wordpressdbuser"@"localhost" identified by "wordpressdbpassword";
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> exit
[hnizam@server ~]$

The above commands create a database named wordpressdb and a user named wordpressdbuser whose password is wordpressdbpassword.  Any other names can be used for the database, username, and password if desired.

Download and extract the WordPress software

The latest version of the WordPress software is downloaded to the server using wget and then extracted using the tar command.

[hnizam@server ~]$ sudo yum install wget
[hnizam@server ~]$ wget
[hnizam@server ~]$ tar -xzvf latest.tar.gz

The above commands result in an extracted folder named wordpress which contains the WordPress software.

[hnizam@server ~]$ ls -l
total 4492
-rw-rw-r--. 1 hnizam hnizam 4594818 Oct 30 04:08 latest.tar.gz
drwxr-xr-x. 5 hnizam hnizam    4096 Oct 30 04:08 wordpress

Copy extracted WordPress folder into www folder

The extracted folder is then copied into /var/www/ folder to ensure that the SELinux contexts are properly set for Apache web server.  The WordPress site will be served by Apache from this location.  Moving the folder using the mv command will preserve the SELinux contexts from the original location which is not what is desired.  Therefore, the folder is copied using the cp command.

[hnizam@server ~]$ sudo cp -R wordpress /var/www/

Next, the owner of the WordPress folder is changed to the Apache user to enable the Apache web server to read and write to that folder.

[hnizam@server ~]$ sudo chown -R apache:apache /var/www/wordpress

Set up Apache virtual host

The Apache web server needs to be configured to make it use the directory above when a browser asks for or

First, the httpd.conf file is modified.

[hnizam@server ~]$ sudo vi /etc/httpd/conf/httpd.conf
### Section 3: Virtual Hosts
# VirtualHost: If you want to maintain multiple domains/hostnames on your
# machine you can setup VirtualHost containers for them. Most configurations
# use only name-based virtual hosts so the server doesn't need to worry about
# IP addresses. This is indicated by the asterisks in the directives below.
# Please see the documentation at
# <URL:>
# for further details before you try to setup virtual hosts.
# You may use the command line option '-S' to verify your virtual host
# configuration.

# Use name-based virtual hosting.
#NameVirtualHost *:80
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.
#<VirtualHost *:80>
#    ServerAdmin
#    DocumentRoot /www/docs/
#    ServerName
#    ErrorLog logs/
#    CustomLog logs/ common

<VirtualHost _default_:80>
    DocumentRoot "/var/www/html"

<VirtualHost *:80>
    DocumentRoot "/var/www/wordpress"
    <Directory "/var/www/wordpress">
        Options FollowSymLinks
        AllowOverride All
    ErrorLog logs/
    CustomLog logs/ combined

Next, the SSL key and certificate for the https site are generated.

[hnizam@server ~]$ openssl genrsa -out wordpress.key -des3 2048
Generating RSA private key, 2048 bit long modulus
e is 65537 (0x10001)
Enter pass phrase for wordpress.key: passphrase
Verifying - Enter pass phrase for wordpress.key: passphrase
[hnizam@server ~]$ openssl req -new -key wordpress.key -out wordpress.csr
Enter pass phrase for wordpress.key: passphrase
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [XX]:MY
State or Province Name (full name) []:Kuala Lumpur
Locality Name (eg, city) [Default City]:Kuala Lumpur
Organization Name (eg, company) [Default Company Ltd]
Organizational Unit Name (eg, section) []:wordpress
Common Name (eg, your name or your server's hostname) []
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[hnizam@server ~]$ openssl x509 -req -days 365 -in wordpress.csr -signkey wordpress.key -out wordpress.crt
Signature ok
subject=/C=MY/ST=Kuala Lumpur/L=Kuala Lumpur/
Getting Private key
Enter pass phrase for wordpress.key: passphrase

The generated key and certificate are then copied to their proper destinations to apply correct SELinux contexts on them.  The read permissions are modified so that only the root user has access to them.

[hnizam@server ~]$ sudo cp wordpress.key /etc/pki/tls/private/
[hnizam@server ~]$ sudo chmod 600 /etc/pki//tls/private/wordpress.key
[hnizam@server ~]$ sudo cp wordpress.crt /etc/pki/tls/certs/
[hnizam@server ~]$ sudo chmod 600 /etc/pki//tls/certs/wordpress.crt
[hnizam@server ~]$ rm wordpress.crt wordpress.csr wordpress.key

Next, the virtual host configuration is added to the Apache SSL configuration file.

[hnizam@server ~]$ sudo vi /etc/httpd/conf.d/ssl.conf
<VirtualHost *:443>
    DocumentRoot "/var/www/wordpress"
    <Directory "var/www/wordpress">
        Options FollowSymLinks
        AllowOverride All
    ErrorLog logs/
    CustomLog logs/wordpress.hazrulnizam.comssl_access_log combined
    LogLevel warn
    SSLEngine on
    SSLProtocol all -SSLv2
    SSLCertificateFile /etc/pki/tls/certs/wordpress.crt
    SSLCertificateKeyFile /etc/pki/tls/private/wordpress.key

The Apache web server is then restarted to load the new configurations.

[hnizam@server ~]$ sudo service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd: Apache/2.2.15 mod_ssl/2.2.15 (Pass Phrase Dialog)
Some of your private key files are encrypted for security reasons.
In order to read them you have to provide the pass phrases.

Server (RSA)
Enter pass phrase:passphrase

OK: Pass Phrase Dialog successful.
                                                           [  OK  ]

Notice that there is a prompt for the passphrase of the private key when Apache is starting up.  This passphrase is going to be asked every time the Apache web server is started, including during server restarts.  This can be avoided by using a private key that is not protected by a pass phrase (do not use the -des3 flag when creating the key using the openssl genrsa command).  However, care must be taken to protect the key from being accessed by anyone else.

At this point, provided that the DNS entry for has been correctly added, pointing a browser to will show the following page:

Set up WordPress - WordPress error page

This shows that Apache is correctly reading the WordPress files and together with the PHP interpreter is serving out dynamic PHP pages to the browser.

Enable WordPress to send emails

Before proceeding with the final step of WordPress installation, SELinux needs to be configured to allow WordPress to send emails out from the system.  There are a few events that triggers WordPress to send notification emails such as when a new comment has been posted to a post.

The setsebool command is used to change the corresponding SELinux boolean to allow Apache, and in turn WordPress, to send out emails.

[hnizam@server ~]$ sudo getsebool httpd_can_sendmail
httpd_can_sendmail --> off
[hnizam@server ~]$ sudo setsebool httpd_can_sendmail on
[hnizam@server ~]$ sudo getsebool httpd_can_sendmail
httpd_can_sendmail --> on

Install and set up WordPress via the browser

The final step of installing WordPress involves creating a WordPress configuration file.  This configuration file can either be manually created at the server, or can be created by WordPress itself via the browser.  This post will continue via the browser method as all the prerequisites to make it successful has been performed above.

The URL is entered in the browser address bar.

Set up WordPress - WordPress error page

The ‘Create a Configuration File’ button is then clicked.

Set up WordPress - Create configuration file page

The next page shows that several information is needed to complete the installation such as database name, database username, database password, and database host.  The corresponding information are the one used in the ‘Create the database and database user’ section above.

The ‘Let’s go’ button is then clicked.

Set up WordPress - Setup Configuration page

The Database Name is changed to wordpressdb, while User Name is changed to wordpressdbuser and Password is changed to wordpressdbpassword.  The Database Host and Table Prefix fields are left at the default values.

The page is then submitted.

Set up WordPress - Configuration success

WordPress is now communicating correctly with the database.  The ‘Run the install’ button is then clicked.

Set up WordPress - Install page

On this page, the Site Title, Username, Password and email address will have to be provided.  The Site Title will be the title shown when the WordPress site is accessed once it is installed.  The Username and Password are different than the database username and password.  This will be the username that will be used to log in to the WordPress administration pages.

Once all the required fields are filled in and the ‘Install WordPress’ button pressed, the WordPress installation is completed and the website is now usable.

Set up WordPress - Install success page

An email about the new WordPress website will also be sent to the email address specified on the install page.

Set up WordPress - New WordPress Site email

This marks the end of the WordPress install.

Optional tasks

Force SSL on login and administration

The WordPress website is now working, but when you click ‘Log in’ from the main page, it will bring you to the http version of the login page.  The username and password that you type will be sent in clear-text through the internet, making them vulnerable to anyone who would want to steal your password.

WordPress has a built-in feature to force logins and/or the administration pages to be served via https instead of http.

To enable this, edit the WordPress config file and add the following line near the end.

[hnizam@server wordpress]$ sudo vi wp-config.php
 * For developers: WordPress debugging mode.
 * Change this to true to enable the display of notices during development.
 * It is strongly recommended that plugin and theme developers use WP_DEBUG
 * in their development environments.
define('WP_DEBUG', false);

define('FORCE_SSL_ADMIN', true);

/* That's all, stop editing! Happy blogging. */

/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
        define('ABSPATH', dirname(__FILE__) . '/');

/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');

You can use FORCE_SSL_LOGIN instead of FORCE_SSL_ADMIN if you just want to protect the login page.  The administration pages will not be served via https unless you specifically asks for the https protocol via the browser.

Enable pretty permalinks

One of the first things that should be done after a WordPress install is to enable pretty permalinks.  The word-based URL will help the website to rank higher in search engine results compared to the default post ID URL.

Just go to the Settings > Permalinks via the administration pages, and choose Postname-based permalinks instead of the default.  If you followed the install steps above, pretty permalinks should work correctly.

Install plugins and themes

One of the great things about WordPress is the abundance of plugins and themes that exist in the ecosystem.  Use them to customize the website and to help in managing the website.

OpenSSL workaround for Oracle XE wallet

In Oracle, the UTL_HTTP package is used to fetch pages from the internet directly by the database.  For example, using the UTL_HTTP.REQUEST function, the first 2000 bytes of a web page can be displayed:

SQL> select UTL_HTTP.REQUEST('') from dual;

<!doctype html><html itemscope="" itemtype=""><head><me
ta content="Search the world's information, including webpages, images, videos a
nd more. Google has many special features to help you find exactly what you're l
ooking for." name="description"><meta content="noodp" name="robots"><meta itempr
op="image" content="/images/google_favicon_128.png"><title>Google</title><script
>(function(){{kEI:"X057UtKqGYvprQeorYDgAQ",getEI:function(a){for(var b;a&&(!a.g
etAttribute||!(b=a.getAttribute("eid")));)a=a.parentNode;return b||google.kEI},h
:function(){},kHL:"en",time:function(){return(new Date).getTime()},log:function(
a,b,c,l,k){var d=new Image,,,g="",h="gen_204";k&&(h=
k);d.onerror=d.onload=d.onabort=function(){delete f[e]};f[e]=d;c||-1!"


However, for pages served with SSL i.e. the https protocol, UTL_HTTP will need access to an Oracle Wallet that stores the trusted certificates for the encryption. Attempting to connect without a wallet will result in a certificate validation error:

SQL> select UTL_HTTP.REQUEST('') from dual;
select UTL_HTTP.REQUEST('') from dual
ERROR at line 1:
ORA-29273: HTTP request failed
ORA-06512: at "SYS.UTL_HTTP", line 1722
ORA-29024: Certificate validation failure
ORA-06512: at line 1


An Oracle Wallet can be created by the Oracle Wallet Manager program.  Unfortunately, the Oracle Wallet Manager program is not distributed with Oracle XE.  I think this is because historically encryption has been part of Oracle Advanced Security, a paid optional Oracle feature.  The good news is SSL/TLS encryption is no longer part of Oracle Advanced Security, as per the Oracle 11gR2 Licensing Guide:

Network encryption (native network encryption and SSL/TLS) and strong authentication services (Kerberos, PKI, and RADIUS) are no longer part of Oracle Advanced Security and are available in all licensed editions of all supported releases of the Oracle database.

So far we have established that using TLS/SSL with Oracle XE is not violating any Oracle licensing issue.  We just have to find a way to create the wallet to be used by Oracle XE.  Of course you can run Oracle Wallet Manager from a non-XE Oracle installation somewhere, and transfer the wallet to your Oracle XE installation.  But what if you do not have access to any properly licensed installation of Oracle?

From the Oracle 11gR2 Advanced Security Guide:

Oracle Wallet Manager stores X.509 certificates and private keys in PKCS #12 format, and generates certificate requests according to the PKCS #10 specification. These capabilities make the Oracle wallet structure interoperable with supported third-party PKI applications and provide wallet portability across operating systems.

Therefore, we can use OpenSSL to create a PKCS #12 archive and it should work with Oracle XE.

In Oracle terminology, a wallet is a directory containing a file named ewallet.p12. Therefore, the PKCS #12 file must be named as such.

In this example I will use the Oracle Support web page as the target page.  First, grab the certificate and all the certificates in its chain by using a browser.  In Firefox, this is done by clicking the padlock icon in the address bar, then clicking on ‘More Information…’.

Firefox Page Info - Security tabThen click on ‘View Certificate’

Firefox Certificate ViewerGo to the ‘Details’ tab

Firefox Certificate Viewer - Details tabSelect the certificate at the bottom of the chain ( and click ‘Export…’.

Save Certificate to FileChange the ‘Save as type’ to ‘X.509 Certificate with chain (PEM)’ and save the certificates to a file.

Transfer this file (mine is named to your Oracle XE server where you want your wallet to be (I chose /u01/app/oracle/wallet).

Now use OpenSSL’s pkcs12 command to create the wallet file using the certificate file as input.  Use the -export flag to create a PKCS #12 file instead of reading one, and use the -nokeys flag to indicate that a private key does not exist inside the input file.  Enter a suitable password when prompted.  This password will have to be provided when using UTL_HTTP later.

[oracle@oraclexe ~]$ cd /u01/app/oracle/wallet
[oracle@oraclexe wallet]$ openssl pkcs12 -export -in -out ewallet.p12 -nokeys
Enter Export Password:
Verifying - Enter Export Password:
[oracle@oraclexe wallet]$

Now we can make SSL calls to the Oracle Support website from the database by providing the wallet and password to UTL_HTTP:

SQL> set pagesize 100
SQL> select UTL_HTTP.REQUEST('',null,'file:/u01/app/oracle/wallet','password') Output from dual;

<title>Oracle Configuration Support Manager</title>
<meta http-equiv="REFRESH" content="0;url=/epmos/faces/MosIndex.jspx"></HEAD>


GlassFish 4 cannot do SSL for multiple virtual hosts

I have been trying to get SSL working on GlassFish, when I realised that unlike Apache (where the SSL configuration can be defined in the virtual host block), the SSL settings for GlassFish is attached to the network listener, not the virtual host.

In the case of a default GlassFish OSE 4.0 installation, the network listener http-listener-2 is the SSL listener, and only one certificate can be associated with the listener at any one time.  The default certificate given to http-listener-2 is a self-signed certificate given the alias s1as.  Changing this to a CA-signed certificate is a matter of modifying the keystore file using the Java keytool program, and changing the certificate alias used by the network listener (via the SSL tab on the network listener configuration page).

I wanted to host multiple virtual hosts, each using a different SSL certificate as they have different domains, on GlassFish.  I wondered why one listener can only use one SSL certificate, because on Apache each virtual host block can house its own SSL settings and hosting multiple SSL sites is definitely possible (I tried).

So I began scouring the documentation and found this in the GlassFish 4.0 Security Guide:

Name-based Virtual Hosts Using name-based virtual hosts for a secure application can be problematic. This is a design limitation of the SSL protocol itself. The SSL handshake, where the client browser accepts the server certificate, must occur before the HTTP request is accessed. As a result, the request information containing the virtual host name cannot be determined prior to authentication, and it is therefore not possible to assign multiple certificates to a single IP address.

If all virtual hosts on a single IP address need to authenticate against the same certificate, the addition of multiple virtual hosts probably will not interfere with normal SSL operations on the server. Be aware, however, that most browsers will compare the server’s domain name against the domain name listed in the certificate, if any (applicable primarily to official, CA-signed certificates). If the domain names do not match, these browsers display a warning. In general, only address-based virtual hosts are commonly used with SSL in a production environment.

Okay, so it seems like GlassFish is blaming the SSL protocol for not being able to use different certificates for different virtual hosts.  The explanation makes sense though; the server will need to know from the client the name of the virtual host the client is connecting to, but this exchange will also have to be encrypted using SSL.  But which SSL certificate should the server use for this initial exchange?  The problem is understandable.

However, if the problem is the SSL protocol, shouldn’t all web servers behave the same way?  If it is impossible on GlassFish, how come it is possible on Apache?

I did some more digging, and stumbled on an Apache wiki page which stated:

As a rule, it is impossible to host more than one SSL virtual host on the same IP address and port. This is because Apache needs to know the name of the host in order to choose the correct certificate to setup the encryption layer. But the name of the host being requested is contained only in the HTTP request headers, which are part of the encrypted content. It is therefore not available until after the encryption is already negotiated. This means that the correct certificate cannot be selected, and clients will receive certificate mismatch warnings and be vulnerable to man-in-the-middle attacks.

I find it quite weird that the Apache documentation is agreeing in saying that it is impossible because I am sure it worked when I tried it.  This very blog is running on a multiple-certificate SSL server!

Then I clicked on the link on that wiki page that leads to another wiki page, which has the answer: Server Name Indication (SNI).

Apparently, SNI is an extension to the SSL protocol that was introduced in 2006 which allowed virtual hosts to use different SSL certificates and the Apache version that I use has already included SNI inside its SSL implementation.

Before SNI, one IP address and port combination can only use one SSL certificate. The introduction of SNI lifted this limitation of the SSL protocol.  So let’s get back to GlassFish.  Does it support SNI?  Based on the documentation, no.  Why doesn’t it support SNI?  Let’s find out.

Googling GlassFish SNI brought me to an interesting post by Ricardo Martín Camarero.  His encounter with SNI is the opposite of mine; he knew it was not supposed to be possible until someone told him otherwise.  He made me realise through his post that since GlassFish runs on Java, SNI support will be dependent on the Java VM.

As of the current version of Java, which is version 7, SNI implementation is only supported for clients i.e. Java clients will be able to connect to servers utilizing SNI with no certificate errors.

SNI support for servers will be added to Java 8.  As such, we might have to wait until the next version of GlassFish to use SNI.

Move Oracle APEX on Oracle XE 11gR2 from EPG to APEX Listener

I have been playing with Oracle Application Express (APEX) to make a few applications, but I have never been bothered to switch from the default Embedded PL/SQL Gateway (EPG).  However, after becoming a little bit familiar with APEX and its different configurations, I became interested to explore other ways of deploying APEX.

The purpose of this post is to document the switch-over of my APEX deployment from EPG to APEX Listener.

The OS of the server is CentOS 6.4.  I installed Oracle Express Edition (XE) 11gR2, with which APEX 4.0 is included.  I then upgraded APEX to 4.2.3, and installed GlassFish 4 Open Source Edition on the server.

Next, configure the APEX_PUBLIC_USER user.

 SQL> alter user apex_public_user identified by password account unlock;

After that it is time to disable EPG.

SQL> exec dbms_xdb.sethttpport(0);

Next, go into the APEX unzipped directory and run the configure restful services script.

$ cd apex_install_directory
$ sqlplus / as sysdba
SQL> @apex_rest_config
Enter a password for the APEX_LISTENER user              []
Enter a password for the APEX_REST_PUBLIC_USER user              []

PL/SQL procedure successfully completed.

PL/SQL procedure successfully completed.

...create APEX_LISTENER user

PL/SQL procedure successfully completed.

User created.

...create APEX_REST_PUBLIC_USER user

User created.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Grant succeeded.

Session altered.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Synonym created.

Session altered.

PL/SQL procedure successfully completed.


Then, grant connect privileges to the APEX_040200 user.

  -- Look for the ACL currently assigned to '*' and give APEX_040200
  -- the "connect" privilege if APEX_040200 does not have the privilege yet.


     'connect') IS NULL THEN
     'APEX_040200', TRUE, 'connect');

  -- When no ACL has been assigned to '*'.
    'ACL that lets power users to connect to everywhere',
    'APEX_040200', TRUE, 'connect');

Download and unzip APEX Listener.

Configure APEX Listener.

# java -jar apex.war
This Listener instance has not yet been configured.
Please complete the following prompts

Enter the location to store configuration data:/root/apex_listener/
Oct 15, 2013 1:31:28 AM oracle.dbtools.common.config.cmds.ConfigDir execute
INFO: Set config.dir to /root/apex_listener/ in: /root/apex_listener/apex.war
Oct 15, 2013 1:31:29 AM oracle.dbtools.common.config.file.ConfigurationFolder logConfigFolder
INFO: Using configuration folder: /root/apex_listener/apex
Enter the name of the database server [localhost]:
Enter the database listen port [1521]:
Enter 1 to specify the database service name, or 2 to specify the database SID [1]:2
Enter the database SID [xe]:
Enter the database user name [APEX_PUBLIC_USER]:
Enter the database password for APEX_PUBLIC_USER:
Confirm password:
Enter 1 to enter passwords for the RESTful Services database users (APEX_LISTENER,APEX_REST_PUBLIC_USER), 2 to use the same password as used for APEX_PUBLIC_USER or, 3 to skip this step [1]:1
Enter the database password for APEX_LISTENER:
Confirm password:
Enter the database password for APEX_REST_PUBLIC_USER:
Confirm password:
Oct 15, 2013 1:32:38 AM oracle.dbtools.common.config.file.ConfigurationFiles update
INFO: Updated configurations: defaults, apex, apex_al, apex_rt
Enter 1 if you wish to start in standalone mode or 2 to exit [1]:2

Configure administrator for APEX Listener

# java -jar apex.war user adminlistener "Listener Administrator"
Oct 15, 2013 1:36:58 AM oracle.dbtools.common.config.file.ConfigurationFolder logConfigFolder
INFO: Using configuration folder: /root/apex_listener/apex
Enter a password for user adminlistener:
Confirm password for user adminlistener:
Oct 15, 2013 1:37:14 AM oracle.dbtools.standalone.ModifyUser execute
INFO: Created user: adminlistener in file: /root/apex_listener/apex/credentials

Create war for static images

# java -jar apex.war static /u01/app/oracle/apex/images
WAR Generation complete
 WAR location     : /root/apex_listener/i.war
 Context path     : /i
 Static resources : /u01/app/oracle/apex/images
Ensure the static resources are available at path: /u01/app/oracle/apex/images

Deploy on GlassFish.

Extracting tablespace DDL from Oracle

I have always used EM Database Control or the EM Console (that is installed with Oracle Client) to extract any DDL from Oracle Database.  I believe the main reason is Oracle has been encouraging young admins like me to use the GUI tools by insisting on using them in all Oracle’s training courses (DB Admin I and II comes to mind).

Today, I had to extract the DDL for a tablespace, without any of the GUI tools.

Luckily, Google saved the day, and I found this thread on the Oracle forums.

Basically, a function for this has already been included in Oracle inside the DBMS_METADATA package.

Just use the GET_DDL function:


Installing GlassFish Server Open Source Edition 4.0 on CentOS 6.4

I have been reading up on Oracle APEX Listener, and I want to try using it to serve Oracle APEX instead of the Embedded PL/SQL Gateway (EPG).  EPG is the default option for the APEX that is included in Oracle Database XE; it works, but many of the features of APEX like RESTful services cannot be used with it.

Oracle APEX Listener must run on top of an application server, and the only supported servers are Oracle WebLogic and GlassFish Server.  Since WebLogic costs money, the free way to try APEX Listener is by first installing GlassFish Server.

This post is intended to document the process of installing GlassFish 4.0 server on CentOS 6.4.

Let’s start with a minimal CentOS 6.4 installation.

Then, install Java SDK by going to the Java SDK Download Page (via a desktop, as wget won’t work) and copying the rpm over to the server.  Proceed with installation of the rpm.

# rpm -Uvh jdk-7u25-linux-x64.rpm

After that, grab the GlassFish Server Open Source Edition installer from the GlassFish Server website.

# yum install wget
# wget

The installer chosen above is a graphical installer (there are other install options, which will not be covered in this post), so we will need to install x11 and configure forwarding with SSH.

# yum install xorg-x11-xauth xorg-x11-utils

Ensure the hostname of the server can be resolved via DNS (the installation will flag errors during the config stage if the server hostname is not resolvable.

# hostname

# ping host.domain.tld

Login again via SSH and enable X11 forwarding, and run the installer.

# sh
Extracting the installer archive...
Extracting the installer runtime...
Extracting the installer resources...
Extracting the installer metadata...

Welcome to GlassFish installer

Using the user defined JAVA_HOME : /usr
Entering setup...
SwixML 1.5 (#144)

The graphical installer will then load.

GlassFish Install 1 - IntroductionClick Next.

The next page is supposed to give a choice of installation type, but only one type (Typical Installation) is available.

GlassFish Install 02 - Installation TypeClick Next.

In the next page you can specify the directory in which you wish to install GlassFish Server Open Source Edition.  The default directory is ~/glassfish4.

GlassFish Install 03 - Install DirectoryI will accept the default.  Click Next.

The next page is the JDK selection page.

GlassFish Install 04 - JDK SelectionThe installer has detected correctly the JDK which was installed earlier.  There is an option to type in another custom location of any JDK you want to use instead.  Click Next.

Next comes the update tool page.  The installer will install an update tool that will check for GlassFish Server updates.  You can uncheck this if you want.

GlassFish Install 05 - Update ToolI will leave it installed.  Click Next.

Then comes the summary page before finalising the install.

GlassFish Install 07 - Ready to InstallClick Install.

Installation will then begin.

GlassFish Install 08 - ProgressAfter the installation has finished, the installer will perform some configuration, and the next page will show the configuration results.

GlassFish Install 09 - Config ResultsTake note of the Admin Port.  In this case it is 4848.  Click Next.

Finally, the installer will show a summary of the installation.

GlassFish Install 10 - SummaryClick Exit to close the installer.

By default, the GlassFish console running on the Admin Port (4848 as noted during the installation) will not accept remote connections.  Therefore, we have to run a browser from the server itself.

# yum install firefox
# dbus-uuidgen > /var/lib/dbus/machine-id
# firefox

Key in localhost:4848 to the address bar, and the GlassFish console will load!

GlassFish Install 11 - GlassFish ConsoleGlassFish Server Open Source Edition is now ready to be used.

Update 30 August 2013 – Securing the Admin Port

It turns out, to enable remote access to the GlassFish Console is easy.  Just use the enable-secure-admin command:

# /root/glassfish4/bin/asadmin enable-secure-admin
remote failure: At least one admin user has an empty password, which secure admin does not permit. Use the change-admin-password command or the admin console to create non-empty passwords for admin accounts.
Command enable-secure-admin failed.

The command failed because the default password for the GlassFish Console admin is blank.  We need to set it to a non-blank password before enabling secure admin.

# /root/glassfish4/bin/asadmin change-admin-password
Enter admin user name [default: admin]>
Enter the admin password>
Enter the new admin password>
Enter the new admin password again>
Command change-admin-password executed successfully.

Now try the enable-secure-admin command again.

# /root/glassfish4/bin/asadmin enable-secure-admin
Authentication failed with password from login store: /root/.gfclient/pass
Enter admin password for user "admin">
You must restart all running servers for the change in secure admin to take effect.
Command enable-secure-admin executed successfully.

Restart the domain for the changes to take effect.

# /root/glassfish4/bin/asadmin stop-domain
Waiting for the domain to stop .
Command stop-domain executed successfully.

# /root/glassfish4/bin/asadmin start-domain
Waiting for domain1 to start ............................
Successfully started the domain : domain1
domain  Location: /root/glassfish4/glassfish/domains/domain1
Log File: /root/glassfish4/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.

Don’t forget to open up port 4848 at the firewall.

# iptables -I INPUT 5 -m state --state NEW -p tcp --dport 4848 -j ACCEPT

Now the GlassFish Console is accessible outside of localhost.  Key in hostname:4848 in the address bar of your browser, and you will be presented with the GlassFish Console login page.  Your browser might throw a certificate error due to the self-signed certificate; just ignore this and add an exception.

GlassFish Install 12 - GlassFish Console Login PageUser Name should be ‘admin’ and the password will be the password you keyed in during the change-admin-password command earlier.