As I outlined in Migrate to GlassFish acitivities , I am migrating samples from different application servers to GlassFish to illustrate migration to GlassFish. Here, I selected the WebLogic's "JSP SimpleTag" s ]]>Simple Tag Sample Application

The sample application that I migrated is the JSP Simple Tagsample from the WebLogic 9.2 distribution. The sample uses the Simple TAG API for iterating through a collection and accessing a database. I used the GlassFish + MySql bundle, resource injection, virtual directory mapping to migrate the application.

The source for the WebLogic sample is in the directory wls-install/weblogic92/samples/server/examples/src/examples/webapp/jsp/tags/simple.

To try the migrated sample to GlassFish

Deployment: WLS Split Directory -> GF Exploded Directory

This sample uses a split directory development structure. Thus, to deploy on GlassFish, I first generated a directory in exploded format using an ant build target in the build.xml for the WebLogic sample as follows:

  • cd wls-install/weblogic92/samples/server/examples/src/webapp/jsp/tags/simple
  • ant build
  • ant package.exploded.ear

The above will build a jspSimpleTagEar directory in exploded format as shown below:

 WebLogic: Exploded EAR jspSimpleTagEar META-INF .. application.xml .. weblogic-application.xml jspSimpleTagWar .. ExamplesFooter.jsp .. ExamplesHeader.jsp .. SimpleTag.jsp .. wls_examples.css ++ WEB-INF .. web.xml .. weblogic.xml ++ classes/examples/webapp/jsp/tags/simple .. ExecuteSql.class .. IteratorTag.class ++ tlds .. simpleTag.tld 

I repackaged the exploded directory as follows:

  • Removed weblogic-application.xml. It was empty in this example.
  • Replaced weblogic.xml with sun-web.xml. The mapping is described below.
  • Modified simpleTag.jsp to use datasource name
  • Modified to use resource injection of DataSource.
  • Modified ExamplesHeader.jsp to handle relative path in virtual directories.

Thus, the exploded ear on GlassFish is as follows:

 GlassFish: Exploded EAR  jspSimpleTagEar META-INF .. application.xml jspSimpleTagWar .. ExamplesFooter.jsp .. ExamplesHeader.jsp .. SimpleTag.jsp .. wls_examples.css ++ WEB-INF .. web.xml .. sun-web.xml ++ classes/examples/webapp/jsp/tags/simple .. ExecuteSql.class .. IteratorTag.class ++ tlds .. simpleTag.tld 

Then I deployed the exploded directory gf_jspSimpleTag on GlassFish:

 asadmin deploydir gf_jspSimpleTag 

PointBase -> MySql

The WebLogic sample uses PointBase database. While GlassFish does support PointBase, I chose to use MySql and used the GlassFish + MySql bundle which can be downloaded from Next, I prepared the MySql database for the example - creating, configuring and populating.

Database name change

The WebLogic sample uses a database "examples-dataSource-demoXAPool". This step is not necessary but I wanted a more suitable name related to my migration work.

Create and Populate wls92examples database

Next, I created the wls92examples and populated it. To populate the script I used a script that came with the WebLogic sample. So here are the steps:

 $ cd gf-install/mysql/bin $ mysql -u root mysql> create database wls92examples; mysql> grant all on wls92examples.* to 'sekhar'@'localhost' identified by 'secretpwd'; mysql> quit $ mysql -u sekhar -p Enter password: secretepwd mysql> use wls92examples; mysql> source wls-install/weblogic92/samples/server/examples/src/examples/common/ddl/demo_mysql.ddl mysql> quit 

Create a MySqlPool Connection Pool

Next, I created a new JDBC Connection Pool

  • Name: MySqlPool
  • Resource type: javax.sql.DataSource
  • Datbase vendor: MySQL

I set the following properties using the GlassFish Admin Console. The properties can be set either when the MySqlPool connection pool is created or after pool creation by

  • Navigate to: Resources -> Connection Pools -> MySqlPool
  • Goto AdditionalProperties tab
  • set the properties described below.

The properties that need to be set are:

    • RelaxAutoCommit = true
      This property needs to be set to true since ExecuteSql class implements the following method from javax.servlet.jsp.tagext.TryCatchFinally interface:
       public void doCatch(Throwable t) throws Throwable { if (conn != null) conn.rollback(); throw t; } 

      The code makes an assumption that the autocommit is false. If autocommit is true, the above method will result in an exception ( logged to <gf-domain>/server.log file ):

       com.mysql.jdbc.exceptions.MySQLNonTransientConnectionException: Can't call rollback when autocommit=true 
    • user, password properties
      Set the user and password used in creating and populating the "wls92examples" database.


  • URL property
    Set the URL property to jdbc:mysql://:3306/wls92examples . This URL will be used to connect to the wls92examples database.


Create JDBC Resource jdbc/wls92examples

Create a JDBC Resource as follows:

  • JNDI name : jdbc/wls92examples
  • Pool name : MySqlPool ( created in above step )
  • Description:

Source Code Changes

I modified the code as described here.

SimpleTag.jsp: Data source name change

Since I changed the database name to "wls92examples" (as described above), accordingly, I changed the datasource name accordingly here as well from

 // WebLogic String dataSourceName = "examples-dataSource-demoXAPool"; 


 // GlassFish String dataSourceName = "wls92examples; Resource injection of DataSource

The class establishes a connection to a database has non portable code

  • use of weblogic.jndi.WLInitialContextFactory
  • JNDI lookup on t3://localhost:7001

I wanted to make the code more portable. So I rewrote the code to use resource injection in Java EE 5.

 //File name:  import javax.sql.DataSource; import javax.annotation.Resource; public class ExecuteSql extends BodyTagSupport implements TryCatchFinally { .... @Resource(name="jdbc/wls92examples") DataSource wlsds; ... omitted other modifcations to code ... } 

Resource injection works with managed classes. I was able to resource injection since ExceuteSql class is a managed class. ExecuteSql extends BodyTagSupport which in turn implements javax.servlet.jsp.tagext.Tag interface.

weblogic.xml -> sun-web.xml Mapping

I migrated the appserver specific deployment descriptor : weblogic to sun-web.xml as follows (Additional details ater the mapping).

 <!-- weblogic.xml --> <?xml version="1.0" encoding="ISO-8859-1"?> <weblogic-web-app xmlns=""> <jsp-descriptor> <page-check-seconds>1</page-check-seconds> <verbose>true</verbose> </jsp-descriptor> <!-- Use the virtual-directory-mapping element to specify document roots other than the default document root of the Web application for certain kinds of requests, such as image requests. All images for a set of Web applications can be stored in a single location, and need not be copied to the document root of each Web application that uses them. For an incoming request, if a virtual directory has been specified servlet container will search for the requested resource first in the virtual directory and then in the Web application's original document root. --> <virtual-directory-mapping> <local-path>C:/bea/weblogic92/samples/server/</local-path> <url-pattern>/examples/*</url-pattern> </virtual-directory-mapping> <virtual-directory-mapping> <local-path>C:/bea/weblogic92/samples/server/examples/build</local-path> <url-pattern>images/*</url-pattern> </virtual-directory-mapping>  <!-- sun-web.xml --> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" ""> <sun-web-app> <jsp-config> <property name="modificationTestInterval" value="1"/> <property name="verbose" value="true"/> </jsp-config> <property name="alternatedocroot_1" value="from=/examples/* dir=C:/bea/weblogic92/samples/server/"/> <property name="alternatedocroot_2" value="from=/images/* dir=C:/bea/weblogic92/samples/server/examples/build"/> </sun-web-app> 

Virtual Directory Mapping

The example uses virtual directory mapping to locate the BEA logo in the example. The GlassFish equivalent for WebLogic's virtual-directory-mapping is the alternatedocroot property. I also had to make two more changes to bring up the BEA logo. Of course, I could have replaced it with a GlassFish logo once I was done :-) but I am trying to show migration issues here.

URL Pattern

In alternatedocroot_2, I changed the URL pattern from images/* to /images/*. Withtout the preceeding / , the following WARNING is generated in the GlassFish server.log file (i.e. gf-install/domain/domain1/logs/server.log )

 [#|2008-05-15T17:57:49.500-0400|WARNING|sun-appserver9.1|javax.enterprise.system.container.web|_ThreadID=24;_ThreadName=httpWorkerThread-4848-1;images/*;_RequestID=1b29dda8-9133-4863-b0ef-9b7ec44c8576;|WEB0504: URL pattern images/* for alternate docbase is invalid|#] 

Relative Path in URL

Another issue I ran into was related to use of a relative path in ExamplesHeader.jsp. This file contains a reference to SRC using a relative path as shown in the following fragment.

 <!-- weblogic : ExamplesHeader.jsp fragment --> ... <!-- TITLE --> <table border=0 cellspacing="18" cellpadding="0"> <tr> <td valign="top"> <a HREF=""><IMG SRC="../../../../images/logo_tm_onwt.jpg" alt="BEA Logo" width="161" height="96" border="0"></a> <h3><%=request.getParameter("title")%></h3> </td> </tr> </table> ... 

The relative path used for SRC did not work (the BEA logo won't come up). I changed the SRC reference to images/* .

 <!-- GlassFish : ExamplesHeader.jsp fragment --> ... <table border=0 cellspacing="18" cellpadding="0"> <tr> <td valign="top"> <a HREF=""><IMG SRC="images/logo_tm_onwt.jpg" alt="BEA Logo" width="161" height="96" border="0"></a> <h3><%=request.getParameter("title")%></h3> </td> </tr> </table> ... 


Except for the rewrite of the code to take advantage of resource injection for injecting a datasource, the code changes were minimal.

As always, feedback is welcome. For questions and feedback, visit <a h