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 a WebSphere Application Server V ]]>WebSphere Sample Application

The sample application I selected is BasicCalculator from the WebSphere Application Server V6.1 Technology Samples (part of the Samples Gallery). Note that it is WebSphere V6.1 not WebSphere Application Server Community Edition (WAS CE). The Technology Samples demonstrate the use of Java EE/J2EE and WebSphere technologies. So I thought these would be good candidates to illustrate migration of WebSphere applications to GlassFish. Also, since WebSphere Application Server V6.1 supports J2EE 1.4, I expect the migration example to be of interest to developers working on for e.g. production applications based on J2EE 1.4

The Technology Samples is a collection of following samples (packaged in a single TechnologySamples.ear file):

  • Enterprise Beans - A basic calculator application using a stateless session bean, performs arithmetic operations (+, -, * , / )
  • J2EE Application Client - A basic calculator application that uses the stateless session bean.
  • Security - Consists of two samples FormLogin and JAASLogin .

For simplicity, I migrated only the Enterprise Beans sample to GlassFish. I plan to migrate the rest of them at a later date. To try the migrated sample on GlassFish,

Summary: The migration was straight forward. No code changes were required. The application used standard J2EE 1.4 features - stateless beans, JSP, ejb references and so on. The only problem was with the url-pattern used in the WEB-INF/web.xml. Most of the work was in verifying WAS ear file, generating Sun Deployment Descriptors from WAS ear, and then packaging an ear for deployment on GlassFish.

WAS BasicCalcualtor Ear file

In order to migrate only the BasicCalculator, I used the Ant's build scripts in the Technology Samples to repackage the classes, WAS deployment descriptors and other files and generate a BasicCalculator.ear file containing only the Enterprise Beans sample. The layout of the WAS ear file is as follows:

 WebSphere Application Server BasicCalculator Ear file  BasicCalculator.ear .... META-INF/ application.xml ibm-application-bnd.xmi ibm-application-ext.xmi MANIFEST.MF .... BasicCalculator.jar .... META-INF/ .... MANIFEST.MF .... ejb-jar.xml .... ibm-ejb-jar-bnd.xmi .... ibm-ejb-jar-ext.xmi .... com/ibm/websphere/samples/technologysamples/ejb/stateless/basiccalculatorejb/ .... BasicCalculator.class .... BasicCalculatorBean.class .... BasicCalculatorHome.class .... BasicCalculatorWeb.jar .... BasicCalculator.jsp .... META-INF/ .... MANIFEST.MF .... WEB-INF/ .... ibm-web-bnd.xmi .... ibm-web-ext.xmi .... web.xml .... classes/com/ibm/websphere/samples/technologysamples/ejb/stateless/basiccalculatorwar/ .... BasicCalculatorJspBean.class .... BasicCalculatorServlet.class 

Verification of WAS Ear file

Next, I ran the GlassFish verifier on the WAS ear file to save time by catch any errors before deployment:

$ verifier was-BasicCalculator.ear

The GlassFish verifier generated the following error. It is turning out to be handy tool in migrating to GlassFish. The GlassFish verifier generates an output file was-BasicCalculator.ear.txt in the directory where it is invoked.

 --------------------------- STATIC VERIFICATION RESULTS --------------------------- ----------------------------------------------------- ERRORS THAT OCCURRED WHILE RUNNING STATIC VERIFICATION ----------------------------------------------------- ---------------------------------- NUMBER OF FAILURES/WARNINGS/ERRORS ---------------------------------- # of Failures : 0 # of Warnings : 0 # of Errors : 1 Error Name : Could not verify successfully. Error Description : java.lang.IllegalArgumentException: Invalid URL Pattern: [BasicCalculatorServlet] 

So, I looked in WAS WEB-INF/web.xml and found the following URL pattern:

 <web-app id="WebApp_1"> .. <servlet-mapping id="ServletMapping_1"> <servlet-name>BasicCalcServlet</servlet-name> <url-pattern>BasicCalculatorServlet</url-pattern> </servlet-mapping> </web-app> 

It is not immediately obvious why the url-pattern works on WebSphere but not on GlassFish. The Servlet DTD in the WAS web.xml was as required by Servlet 2.5 spec

 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> 

and SVR 11.2 of Servlet Spec indicates an exact match of the url-pattern. I was guessing a leading / might fix it. Instead of going down this path, I let GF migration tool fixed the problem for me.

Migration tool for GlassFish

I ran the Migration Tool for GlassFish (download here ) on the WAS ear file as:

$ asmigrate -S ws50 -T glassfish -t was2gf TechnologySamples.ear

The Migration Tool for GlassFish currently supports WAS 4.x, 5.x but I was using WAS 6.1. There are some differences in WAS 5.x and WAS 6.1 deployment descriptor files. Nonetheless, the GF Migration Tool took the deployent descriptors ( Java EE standard as well ibm*.xmi files) and generated the following files for GlassFish:

  • web.xml
  • ejb-jar.xml
  • sun-web.xml
  • sun-ejb-jar.xml

The generated web.xml had the following url-pattern - note the leading / . This fixed the problem.

 <web-app> .. <servlet-mapping> <servlet-name>BasicCalcServlet</servlet-name> <url-pattern>/BasicCalculatorServlet</url-pattern> </servlet-mapping> </web-app> 

GlassFish BasicCalculator ear file

Next, using Ant build script I repackaged compiled classes, GF Migration Tool generated files etc into an ear successfully deployed on GlassFish. The GF Migration Tool generates build scripts (although it did not in this case - I will be investigating this). Notethat the only difference between the WAS ear and the GlassFish ear were the GF Migration Tool generated files. So here is what the BasicCalculator.ear for GlassFish looks like.

 GlassFish Application Server BasicCalculator Ear file  BasicCalculator.ear .... META-INF/ .... application.xml .... MANIFEST.MF .... BasicCalculator.jar .... META-INF/ .... MANIFEST.MF .... ejb-jar.xml .... sun-ejb-jar.xml .... com/ibm/websphere/samples/technologysamples/ejb/stateless/basiccalculatorejb/ .... BasicCalculator.class .... BasicCalculatorBean.class .... BasicCalculatorHome.class .... BasicCalculatorWeb.jar .... BasicCalculator.jsp .... META-INF/ .... MANIFEST.MF .... WEB-INF/ .... sun-web.xml .... web.xml .... classes/com/ibm/websphere/samples/technologysamples/ejb/stateless/basiccalculatorwar/ .... BasicCalculatorJspBean.class .... BasicCalculatorServlet.class 

JNDI names: ibm-*-bnd.xmi files

WAS uses binding files that contain JNDI names to reference other components in the application. In this particular example, they are ibm-ejb-jar-bnd.xmi, ibm-web-bnd.xmi . The GF Migration Tool migrated the JNDI names to sun-ejb-jar.xml and sun-web.xml as shown below.

  <!-- ibm-ejb-jar-bnd.xmi -->  <ejbbnd:EJBJarBinding xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ejbbnd="ejbbnd.xmi" xmlns:commonbnd="commonbnd.xmi" xmlns:ejb="ejb.xmi" xmi:id="ejb-jar_ID_Bnd"> .... <ejbBindings xmi:id="Session_1_Bnd" jndiName="WSsamples/BasicCalculator"> <enterpriseBean xmi:type="ejb:Session" href="META-INF/ejb-jar.xml#Session_1"/> </ejbBindings> </ejbbnd:EJBJarBinding> | V  <!-- sun-ejb-jar.xml -->  <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD ..."> <sun-ejb-jar> <enterprise-beans> <ejb> <ejb-name>BasicCalculator</ejb-name> <jndi-name>WSsamples/BasicCalculator</jndi-name> </ejb> </enterprise-beans> </sun-ejb-jar> 
  <!-- ibm-web-bnd.xmi -->  <?xml version="1.0" encoding="UTF-8"?> <webappbnd:WebAppBinding xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:webappbnd="webappbnd.xmi" xmlns:webapplication="webapplication.xmi" xmlns:commonbnd="commonbnd.xmi" xmlns:common="common.xmi" xmi:id="WebApp_1_Bnd" virtualHostName="default_host"> <webapp href="WEB-INF/web.xml#WebApp_1"/> <ejbRefBindings xmi:id="EjbRefBinding_1" jndiName="WSsamples/BasicCalculator"> <bindingEjbRef href="WEB-INF/web.xml#EjbRef_1"/> </ejbRefBindings> </webappbnd:WebAppBinding> | V  <!-- sun-web.xml -->  <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD ..."> <sun-web-app> <ejb-ref> <ejb-ref-name>WSsamples/BasicCalculator</ejb-ref-name> <jndi-name>WSsamples/BasicCalculator</jndi-name> </ejb-ref> </sun-web-app> 

Id Mapping

As I noted above, in WAS every XML element in the deployment descriptor has an XML id attribute used to reference an XML element (for either standard or ibm* files). For e.g.

 <!-- WAS : web.xml --> <web-app id="WebApp_1"> .... <servlet-mapping id="ServletMapping_1"> .... </servlet-mapping> .... </web-app> 

It looks like XML id attributes are automatically generated by a WAS assembly tool (e.g. Application Server Toolkit and Rationale Application Developer) . Any input from WebSphere developers ?

GF Migration Tool drops the XML id attributes since they are not used by the Sun specific deployment descriptors. Here is the generated web.xml.

 <!-- Generated by Migration Tool for GlassFish: web.xml --> <web-app> .... <servlet-mapping> .... </servlet-mapping> .... </web-app> 

Summary

So,to summarize, migrating J2EE/Java EE compliant applications such as this one involve minimal or no code changes. Furthermore GlassFish verifier and Migration Tool for GlassFish are helpful in migrating to GlassFish. You feedback on the tools would be valuable. The GlassFish verifier is part of the GlassFish distribution and is in /bin directory. You can download the Migration Tool from here. Use Migrate To GlassFish Issuetracker to file issues against the GF Migration Tool. I have started to do this myself and encourage others to do so as well. I will be back with more examples. As always, your feedback is welcome.