Skip to main content

Migrating JBoss's Sample JSF-EJB3 Application To GlassFish

Posted by sekhar on February 11, 2008 at 9:32 AM PST

As part of the Migrate
to GlassFish acitivities
, I migrated a JBoss sample to GlassFish. I am going to describe what I had to do to migrate the application.

Sample Application

The sample application I migrated is "Sample JSF-EJB3 Application" from JBoss Getting Started Guide. The sample can be obtained by downloading Examples Download, unzipping and cding to gettingstarted/jsfebj3 directory. To summarize the sample is a Todo application that uses JSF, facelets, Java Persistence, EJB 3 sessions beans. For more detailed documentation on the sample see Sample JSF-EJB3 Application . Refer to this documentation for additional context as you read the rest of the blog.
For most part, the migration was easy.

If you would like to try out the migrated sample on GlassFish,

  • download the migrated Glassfish JSF-EFJ3 ear.
  • Start database: asdmin start-database
  • Start server : asadmin start-domain
  • Deploy : asadmin deploy --user admin --passwordfile file-with-admin-pwd ear

    The component name after deployment is gf-jsfejb3 (used for e.g. in listing, undeployment).
  • Access http://localhost:8080/jsfejb3

Facelets

The sample uses Facelets. For the purposes of this example, Facelets:

  • work with JSF 1.2 and GlassFish supports JSF 1.2 (requirement of Java EE 5).
  • run on GlassFish but jsf-facelets.jar is needed
  • use for configuration. In particular the only required intergration point between JSF and Facelets is in < face-config.xml>. The JBoss sample uses:
       <faces-config>
          <application>
            <view-handler>
              <com.sun.facelets.FaceletViewHandler
            </view-handler>
          </application>
        </faces-config>

The JBoss sample bundles jsf-facelets.jar "jsfejb3.ear ! app.war#WEB-INF/lib/jsf-facelets.jar". I continued to do the same for GlassFish sample in "gf-jsfejb3.ear ! app.war # WEB-INF/lib/jsf-facelets.jar".

JNDI Lookup of local ejb

The JBoss sample contains a TodoBean that uses JNDI to lookup a local ejb as follows:

    public class TodoBean {

        private Todo todo;
        ...

        private TodoDaoInt getDao () {
        try {
            InitialContext ctx = new InitialContext();
            return (TodoDaoInt) ctx.lookup("jsfejb3/TodoDao/local");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("couldn't lookup Dao", e);
        }
    }
  
    @Stateless
    public class TodoDao implements TodoDaoInt { ... }
 
    public interface TodoDaoInt { ... }

The JNDI name "jsfejb3/TodoDao/local" is nonstandard. I changed it to "java:comp/env/ejb/TodoDao" and added ejb-local-ref to web.xml

     // code changes to TodoBean class
     InitialContext ctx = new InitialContext();
     return (TodoDaoInt)ctx.lookup("java:comp/env/ejb/TodoDao");

    // added to web.xml
    <ejb-local-ref>
        <ejb-ref-name>ejb/TodoDao</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <local-home/>
        <local>TodoDaoInt</local>
    </ejb-local-ref>

Java EE 5 allows injection of entities into a managed class using dependency injection. GlassFish supports dependency injection (For JBoss support - see Sessions Beans and EJB3 Caveats). I will explore using dependency injection for migrating the sample to GlassFish at a future date.

Persistence Provider

The sample uses Hibernate as the persistence provider and HSQL database, while for GlassFish default persistence provider is Toplink and the database is Java DB . For this particular example, I chose to switch to Toplink and Java 2DB. (Other GF forum threads, blogs etc describe integration of Hibernate in GlassFish.)

So here is the "jsfejb3.ear ! app.jar # META-INF/persistence.xml" from the JBoss sample:

  <persistence>
    <persistence-unit name="helloworld">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <jta-data-source>java:/DefaultDS</jta-data-source>
      <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
        <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
      </properties>
    </persistence-unit>
  </persistence>

And here is "jsfejb3.ear ! app.jar # META-INF/persistence.xml" for GlassFish migrated sample.

  <persistence>
    <persistence-unit name="helloworld">
      <jta-data-source>jdbc/__default</jta-data-source>
      <properties>
        <property name="toplink.ddl-generation" value="drop-and-create-tables"/>
      </properties>
   </persistence-unit>
  </persistence>

I did notice two differences as a result of swtiching persistence providers.

Pre-population of database at deployment time: The example contains an import.sql file containing SQL statements which prepopulates the database with a list of items. For e.g.

     insert into Todo (id, title, description) values (1, 'This is a title', 'The description is here!')

It appears that Hibnerate will execute the import.sql if found on classpath. Does such a similar mechanism exist in Toplink ? I looked but could not find any.
I would love to hear feedback from Toplink developers.

Warning message on dropping of tables: During deployment a warning message is generated. It does not impact the deployment or running of the application. I started an email thread on this. But my analysis so far. In the following entity class:

    @Entity
    public class Todo implements Serializable {
        ...
        @Id @GeneratedValue
        public long getId() { return id;}
        ...
    }

the @GeneratedValue defaults to @GeneratedValue.AUTO which leaves the primary key mapping to the persistence provider. And in Toplink seems to generate a Table for @GeneratedValue.AUTO . When the sample application is deployed, the actual data tables are dropped but not the table generated for the primary key. Hence the warning message. However, as I said, it does not prevent the application from working.

Packaging changes

Here is a summary of packaging changes I made to JBoss ear (by modifying build.xml).

  • In app.war moved TodoBean.class from WEB-INF/ to WEB-INF/classes.
    In JBoss sample, TodoBean.class is packaged as "jboss-jsfejb3.ear ! app.war ! TodoBean.class" . However, app.war failed verification by GlassFish verifier. So I moved it TodoBean.class to "gf-jsfejb3.ear ! app.war # WEB-INF/classes/TodoBean.class"
  • excluded "jsfejb3.ear # META-INF/jboss-app.xml" It is specific to JBoss and deals with class loader repositories.

As always, feedback is welcome. For questions and feedback, visit Migrate To GlassFish project and follow the "Discussion Forums" link .

Related Topics >>

Comments

gf-jsfejb3 does not work

The example at https://migrate2glassfish.dev.java.net/blogs/gf-jsfejb3.ear does not work on GlassFish-v3-preview. Error due deployment with Run Verifier enabled: server.log: Exception while deploying the app org.glassfish.deployment.common.DeploymentException: Some verifier tests failed for the given application. Aborting deployment. Please see server.log for more details. verifier-results: Error Name : Could not verify successfully. Error Description : java.lang.NullPointerException

Hi Keith, I was OOO and got back today. For GlassFish -> JBoss issues, I suggest that you post your questions to a JBoss forum, where there are other developers with more detailed knowledge related to JBoss issues. For JBoss -> GlassFish migration issues please use the GlassFish forum.

Yes, import.sql is a pretty wretched solution even when you're using Hibernate and do not care about interoperability. Also I never understood why it is also executed before table drop.

hi sekhar, i am facing huge problem while migrating from Glassfish v2 to jboss 4.3.i have created a .ear which is working on Glassfish.but when i am trying to deploy it on jboss,it is giving lots of problems.Can you please help me.i already posted on communities. Thanks Kieth

Gordon - Thanks for the feedback.

Thanks for the article - this clarifies exactly one problem that we have found ...

Please explain, why is there no standardisation of the JNDI names used for data sources and EJBs?

If the EJB name jsfejb3/TodoDao/local is a non-standard name, and should be changed to java:comp/env/ejb/TodoDao then why is the data souce name java:/DefaultDS also wrong, and has to be changed to jdbc/__default in persistence.xml?

These conventions are apparently inconsistent with one another.

We write applications which we have to support on multiple vendors. We can copy with supplying a additional vendor-specific deployment descriptor - but now it seems that we also have to munge the contents of persistence.xml on a per-vendor basis - not good! Please can you direct me to a reference that explains how these JNDI names are supposed to be specified, in a vendor-portable standard form?

Ed.

TopLink Essentials does not support executing SQL from a file as in the case of the import.sql but in general it is better to code your population within the demo or application and allow the persistence provider to do for you what it does best, translate your domain classes to the database. Hardcoded SQL seldom works well on multiple databases limiting the deployment target and the audience of your demo/application to a specific database. --Gordon Yorke