pagetop
Javablog
by Java coders, for Java codersRSS

Tomcat is Dead, Long Live Glassfish!

December 26th, 2009 by

SUN finished off 2009 with a release of Glassfish v3 - a high visibility Open Source implementation of Java Enterprise 6 - and the NetBeans 6.8 IDE.

Combined, these releases significantly reduce the barrier to entry for writing and deploying Java Enterprise applications. However, the documentation is sparse at best, and misleading at worst (some cases in point). This post documents getting Glassfish running with sensible parameters - unlike the defaults - covering:-

  • Admin panel with secure connection and password
  • mod-jk delegation from Apache
  • Enabling the Security Manager
  • Registering a PostgreSQL JDBC connection through JNDI
  • Hibernate to access the JNDI via JPA, whilst allowing persistence in J2SE main methods and tests.

Glassfish is much easier to configure than the perplexing Servlet Container, Apache Tomcat. With support for Ruby on Rails and PHP Web Applications, there is no good reason why anybody should still be using Tomcat - if anything, you should be asking yourself why you’re still using Apache HTTPD!

Installing on Ubuntu

The J2EE version of NetBeans comes with Glassfish and JavaDB bundled. Installation is therefore trivial on the development side. This focuses on installing Glassfish on a server machine, such as Ubuntu Hardy. Using elsewhere and elsewhere as a benchmark, the short version is to download the ZIP version of Glassfish v3 and unextract it into /opt/. Then create an executable script at /etc/init.d/glassfish containing the following

#!/bin/bash
GLASSFISH_AS_ADMIN="/opt/glassfishv3/bin/asadmin --secure=true" # might need to use "false" on first start
case $1 in
start)
        $GLASSFISH_AS_ADMIN start-domain domain1
        ;; 
stop)
        $GLASSFISH_AS_ADMIN stop-domain domain1
        ;; 
restart)
        $0 stop
        $0 start
        ;; 
esac    
exit 0

which allows the Glassfish server to start up or shutdown with /etc/init.d/glassfish start and /etc/init.d/glassfish stop respectively. The following command ensures that Glassfish starts up from reboots.

update-rc.d glassfish defaults 90 10

Securing Glassfish

By default, Glassfish allows unauthorised users to log on to an unencrypted port 4848 and upload applications that run with full root privileges. I consider this to be a major security hold and my first instinct was to get SSL, reboot, then install an admin password. Point your browser to port 4848 of your new Glassfish server and navigate to

Configuration -> Network Config -> Protocols -> admin-listener -> Check “Security Enabled”

restart the server and point your browser to the same location, this time using https. Then navigate to

Enterprise Server -> Administrator Password -> Enter “New Password”

then

Configuration -> Security -> Check “Security Manager”

and restart.

You should do these steps on a local installation of Glassfish, bundle up the binaries, and then send to your server - to avoid a race condition where the whole world has root access to your server. Alternatively, ensure that port 4848 is not world visible during these steps.

Delegation from Apache

mod_jk allows Apache to forward requests on the standard HTTP and HTTPS ports (80 and 443 respectively) to Glassfish, which might be running on any port. Clients never send requests to anything other than the standard ports - essential for bypassing over-zealous home or corporate firewalls.

I already had mod_jk forwarding requests to a Tomcat instance, so the details here are a little light on setting up the Apache-side configuration. They should be the same as for an Apache -> Tomcat bridge, luckily many Quick Start Guides exist. On Ubuntu, this amounts to typing

a2enmod jk

creating a /etc/apache2/workers.properties file containing something like

worker.list=worker1
worker.worker1.port=8009
worker.worker1.host=localhost
worker.worker1.type=ajp13
worker.worker1.lbfactor=1

adding the following to your /etc/apache2/sites-available/default (right up at the top, before any VirtualHost declarations)

JkWorkersFile /etc/apache2/workers.properties

and then in each virtual host, you add lines similar to

JkLogFile /var/log/apache2/HOSTNAME-mod_jk.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JkMount /MyJ2eeWebApp|/* worker1

to forward all requests beginning “/MyJ2eeWebApp.*” to the worker1 thread.

Go to the Glassfish admin panel and create a jk-listener through

Configuration -> Network Config -> New. enter name, e.g. “jk-listener” and select port number (8009 to agree with worker1 above) and tick “JK Listener”

Then restart/reload Apache.

Note that you need to enable each Web Application individually through mod_jk - it’s not possible to forward a directory (e.g. everything starting /j2ee/) to the base of the J2EE Web Applications. Which is unfortunate.

JNDI Access of JDBC Data Sources

Glassfish comes with built-in support for accessing the Apache Derby database - but it would be a stretch of the imagination to call this a deployment quality database. It’s very useful as a development database.

My preferred database is PostgreSQL, which has decent JDBC 4 support. Download the JDBC 4 driver and place it in the Glassfish /opt/glassfishv3/glassfish/domains/domain1/lib/ folder, then restart Glassfish.

To add a PostgreSQL JDBC source, use the Glassfish admin panel

Resources -> JDBC -> Connection Pools -> New

or

Common Tasks -> Create New JDBC Connection Pool

Use a descriptive CamelCaseName for your connection pool selecting javax.sql.DataSource as Resource Type and Postgresql as Vendor. In the next screen, go straight to the bottom and enter at least the following properties, depending on your database setup

databaseName = mydb
user = myusername
password = mypassword
portNumber = 5432
URL = jdbc:postgresql://localhost:5432/mydb

You might also want to tune the connection pool parameters, although you can always do that later.

Once done, click ping up at the top to confirm that the connection works. Then go to “JDBC Resources” and create a new resource using the naming convention of jdbc/your_db_name, select the newly created pool.

This JDBC connection is now available to any Application that requests it! You might want to further investigate the possibility of using a Security Policy for access to the JDBC connections.

JPA JNDI with Hibernate

For an introduction to JPA, see the Archive for the ‘JPA’ Category.

There are two options for using hibernate, either bundle with your apps or go to

Update Tool -> Available Add-Ons -> hibernate

Be careful about choosing the site-wide installation - SUN are currently shipping the “3.5 beta” release of Hibernate, which has a few bugs in it, but is an attempt at JPA 2 compliance - make sure this release of Hibernate plays nicely with your codebase and database providers. Removing Add-Ons is very complicated.

It is disappointing that the security policy is not set automatically. To allow hibernate to function, add the following to server.policy

grant {
    permission java.util.PropertyPermission "*", "read";
    permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
};

If anybody knows how to restrict this to just the Hibernate classes, please respond in the comments. So that you know what you’re enabling, see ReflectPermission. Security permissions can also be set on a per-application basis by editing granted.policy. A SUN blog claims “During deployment, the Glasfish policy provider translates security-contraints, method-permissions and common security annotations into grant statements and writes them to a file called granted.policy”, although I have yet to see an example of this working. Again, please comment below if you have an example.

This allows you to use whatever JDBC resource you like on your development or test environments - e.g. HSQLDB, Derby, PostgreSQL, MySQL - but provides you with access to your more stable database on deployment, without any changes to your persistence.xml. Note that because you’re not embedding your JDBC driver with your application, you have more freedom to use GPL drivers such as MySQL Connector-J.

A disadvantage of using the JDBC/JNDI approach is that you will need to be within a Container to access the database - and remember that the @PersistenceUnit annotation allows injection on Container managed classes such as Servlets

@PersistenceUnit(unitName="MyPU")
private EntityManagerFactory emf;

But this means that main applications and junit tests will fail to obtain a connection. It is possible to programmatically reset the JNDI data source and supply the URL of a database connection when obtaining an EntityManagerFactory

// properties are read from a hibernate.properties file - similar for other vendors
properties.put("javax.persistence.jtaDataSource", "");
properties.put("javax.persistence.nonJtaDataSource", "");
emf = Persistence.createEntityManagerFactory("MyPU", properties);

So try to write your code so that DAOs and other database-managing code take in the EntityManagerFactory instances so you know where the persistence units are coming from.


This entry was posted by by on Saturday, December 26th, 2009 at 11:12 pm, and is filed under Database, deployment, EJB3, Hibernate, J2EE, Java 6, JPA, PostgreSQL. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.



7 comments on “Tomcat is Dead, Long Live Glassfish!”

Thanks for sharing this. Packed with small but useful info.

Small nitpick: it’s JNDI… UPDATE: Thanks for spotting this, now fixed! - Sam

With regard to the lack of a password on the initial install, that was a conscious decision, as we hoped to make the initial developer experience as simple as we can. We expect, as you’ve suggested as well, that users would add a password to the system before deploying to production. Personally, I like this approach as, before coming on board at Sun, most of my interaction with GlassFish was on my developer box and I was always forgetting the password. :)

Hope that helps. Interesting post. Glad you’re at least mostly happy with our product. :) We’re going to try to make it even better in the next version.

@Jason thanks for responding here.

With regards to the password and SSL, my personal preference would be to have SSL enabled by default - with a highlighted prompt to change the password in the admin panel.

I am indeed very happy with Glassfish - for the next version, I’d like to see hibernate shipped as default - with more JDBC drivers, or install sources - and better memory usage. In my 64 bit Ubuntu Hardy VPS, I’m seeing a standard Glassfish instance taking up 800m! Oh, and some “quick guides” ;-)

I like this provoking subject. Nevertheless, market share tells us something different ;-) .

Diego Bravo wrote:

Excellent post, those OS/support issues take a lot of time reading docs for setup.

vary helpful I was totally gone with some other thing to install Glassfish, now I got.

Leave a comment

Markdown is supported.

To include code snippets in your comment, use

<pre><code># lang java
... code here ...
</code></pre>

or use 4 spaces at the start of the line instead of using code and pre tags.

Comment feed: RSS