Arun Gupta, Miles to go ...

Arun Gupta is a technology enthusiast, a passionate runner, and a community guy who works for Oracle.

http://blogs.sun.com/arungupta/date/20091002 Friday October 02, 2009

TOTD #109: How to convert a JSF managed bean to JSR 299 bean (Web Beans) ?

This entry is a follow up to TOTD #95 and shows how to use the recent integrations of JSR 299 in GlassFish v3 to convert a JSF managed bean to a JSR 299 bean (aka Web Beans). The TOTD #95 describes a simple Java EE 6 web application that uses Java Server Faces 2.0 components for displaying the results of a database query conducted by EJB 3.1 and JPA 2.0 classes.

The EJB class, which also acts as the JSF managed bean, looks like:

@javax.ejb.Stateless
@ManagedBean
public class StateList {
  @PersistenceUnit
  EntityManagerFactory emf;

  public List getStates() {
    return    emf.createEntityManager().createNamedQuery(”States.findAll”).getResultList();
  }
}

Three changes are required to convert this class into a JSR 299 compliant bean (Web Bean) as listed below:

  1. Add an empty "beans.xml" to the WEB-INF directory.
  2. Replace "@ManagedBean" with "@javax.inject.Named annotation". "@javax.inject" annotations are defined by JSR 330.
  3. Resource injection does not work with JPA classes, yet, so populate EntityManager explicitly as explained below:
    1. Replace EntityManagerFactory resource injection:

      @PersistenceUnit
      EntityManagerFactory emf;
      

      with:
      EntityManager emf = Persistence.createEntityManagerFactory("HelloEclipseLinkPU");
      
    2. Add the required entity classes explicitly to "persistence.xml". If the persistence unit is injected then the container automatically scans the web application root for any entity classes.
      1. Expand "Configuration Files" and edit "persistence.xml".
      2. Uncheck "Include All Entity Classes in ..." check box.
      3. Click on "Add Class...", select "state.States", and click on "OK".

That's it, re-deploy your application and now you are using the Web Beans integration in GlassFish v3 instead of JSF managed bean. The output is available at "http://localhost:8080/HelloEclipseLink/forwardToJSF.jsp" as shown:



This is the exact same output as shown in TOTD #95.

Now, one-by-one, JPA, EJB, Transactions and other components will start working. Read Roger's blog for another example of Web Beans in GlassFish.

A complete archive of all the tips is available here.

Technorati: totd glassfish v3 mysql javaee6 javaserverfaces webbeans jsr299 netbeans

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20090904 Friday September 04, 2009

TOTD #101: Applying Servlet 3.0/Java EE 6 “web-fragment.xml” to Lift – Deploy on GlassFish v3

TOTD #100 explained how to deploy Lift framework applications on GlassFish v3. As explained in TOTD #91, Java EE 6 defines how the framework configuration deployment descriptor can be defined in “META-INF/web-fragment.xml” in the JAR file of the framework instead of mixing it with "WEB-INF/web.xml" which is intended for application deployment descriptor aspects.

This Tip Of The Day (TOTD) explains how to leverage ”web-fragment.xml” to deploy a Lift application on a Java EE 6 compliant container. The original "lift-*.jar" files are untouched and instead a new JAR file is included that contains only the framework configuration deployment descriptor.

The generated "web.xml" from TOTD #100 looks like:

<?xml version="1.0" encoding="ISO-8859-1"?>

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

<web-app>
<filter>
 <filter-name>LiftFilter</filter-name>
 <display-name>Lift Filter</display-name>
 <description>The Filter that intercepts lift calls</description>
 <filter-class>net.liftweb.http.LiftFilter</filter-class>
</filter>
 

<filter-mapping>
 <filter-name>LiftFilter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

</web-app>

The deployment descriptor defines a Servlet Filter (LiftFilter) that registers the Lift framework with the Web container. And then it defines a URL mapping to "/*". All of this information is required by the Lift framework for request dispatching. And so that makes this fragment suitable for "web-fragment.xml".

Here are simple steps to make this change:

  1. Remove “src/main/webapp/WEB-INF/web.xml” because no application specific deployment descriptors are required.
  2. Include “lift-web-fragment.jar” in the “WEB-INF/lib” of your application by adding the following fragment in your “pom.xml”:
    <dependencies>
            
    . . .
    
      <!– web-fragment –>
      <dependency>
        <groupId>org.glassfish.extras</groupId>
        <artifactId>lift-web-fragment</artifactId>
        <version>1.0</version>
        <scope>runtime</scope>
      </dependency>
    </dependencies>
    
    . . .
    
    <repositories>
      <repository>
        <id>maven2-repository.dev.java.net</id>
        <name>Java.net Repository for Maven</name>
        <url>http://download.java.net/maven/2/</url>
      </repository>
    </repositories>
    
    
    This file contains only “META-INF/web-fragment.xml” with the following content:
    <web-fragment>
     <filter>
     <filter-name>LiftFilter</filter-name>
     <display-name>Lift Filter</display-name>
     <description>The Filter that intercepts lift calls</description>
     <filter-class>net.liftweb.http.LiftFilter</filter-class>
     </filter>
     
    
     <filter-mapping>
     <filter-name>LiftFilter</filter-name>
     <url-pattern>/*</url-pattern>
     </filter-mapping>
    </web-fragment>
    
    
  3. Create the WAR file without “web.xml” by editing “pom.xml” and adding the following fragment:
    <build>
       . . .
      <plugins>
        . . .
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-war-plugin</artifactId>
          <version>2.1-beta-1</version>
          <configuration>
            <failOnMissingWebXml>false</failOnMissingWebXml>
          </configuration>
        </plugin>
      </plugins>
    </build>
    

That's it, now now you can create a WAR file using “mvn package” and deploy this web application on GlassFish v3 latest promoted build (61 as of today) as explained in TOTD #100.

Technorati: totd glassfish v3 lift scala javaee6 servlet web-fragment

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20090817 Monday August 17, 2009

TOTD #95: EJB 3.1 + Java Server Faces 2.0 + JPA 2.0 web application - Getting Started with Java EE 6 using NetBeans 6.8 M1 & GlassFish v3


TOTD #93 showed how to get started with Java EE 6 using NetBeans 6.8 M1 and GlassFish v3 by building a simple Servlet 3.0 + JPA 2.0 web application. TOTD #94 built upon it by using Java Server Faces 2 instead of Servlet 3.0 for displaying the results. However we are still using a POJO for all the database interactions. This works fine if we are only reading values from the database but that's not how a typical web application behaves. The web application would typically perform all CRUD operations. More typically they like to perform one or more CRUD operations within the context of a transaction. And how do you do transactions in the context of a web application ? Java EE 6 comes to your rescue.

The EJB 3.1 specification (another new specification in Java EE 6) allow POJO classes to be annotated with @EJB and bundled within WEB-INF/classes of a WAR file. And so you get all transactional capabilities in your web application very easily.

This Tip Of The Day (TOTD) shows how to enhance the application created in TOTD #94 and use EJB 3.1 instead of the JSF managed bean for performing the business logic. There are two ways to achieve this pattern as described below.

Lets call this TOTD #95.1

  1. The easiest way to back a JSF page with an EJB is to convert the managed bean into an EJB by adding @javax.ejb.Stateless annotation. So change the  "StateList" class from TOTD #94 as shown below:

    @javax.ejb.Stateless
    @ManagedBean
    public class StateList {
        @PersistenceUnit
        EntityManagerFactory emf;

        public List<States> getStates() {
            return emf.createEntityManager().createNamedQuery("States.findAll").getResultList();
        }
    }

    The change is highlighted in bold, and that's it!
Because of "Deploy-on-save" feature in NetBeans and GlassFish v3, the application is autodeployed. Otherwise right-click on the project and select Run (default shortcut "F6"). As earlier, the results can be seen at "http://localhost:8080/HelloEclipseLink/forwardToJSF.jsp" or "http://localhost:8080/HelloEclipseLink/faces/template-client.xhtml" and looks like:



The big difference this time is that the business logic is executed by an EJB in a fully transactional manner. Even though the logic in this case is a single read-only operation to the database, but you get the idea :)

Alternatively, you can use the delegate pattern in the managed bean as described below. Lets call this #95.2.
  1. Right-click on the project, select "New", "Session Bean ..." and create a stateless session bean by selecting the options as shown below:



    This creates a stateless session with the name "StateBeanBean" (bug #170392 for redundant "Bean" in the name).
  2. Simplify your managed bean by refactoring all the business logic to the EJB as shown below:

    @Stateless
    public class StateBeanBean {
        @PersistenceUnit
        EntityManagerFactory emf;
        
        public List<States> getStates() {
            return emf.createEntityManager().createNamedQuery("States.findAll").getResultList();
        }
    }

    and

    @ManagedBean
    public class StateList {
        @EJB StateBeanBean bean;

        public List<States> getStates() {
            return bean.getStates();
        }
    }

    In fact the EJB code can be further simplified to:

    @Stateless
    public class StateBeanBean {
        @PersistenceContext
        EntityManager em;
       
        public List<States> getStates() {
            return em.createNamedQuery("States.findAll").getResultList();
        }
    }

    The changes are highlighted in bold.
If the application is already running then Deploy-on-Save would have automatically deployed the entire application. Otherwise right-click on the project and select Run (default shortcut "F6"). Again, the results can be seen at "http://localhost:8080/HelloEclipseLink/forwardToJSF.jsp" or "http://localhost:8080/HelloEclipseLink/faces/template-client.xhtml" and are displayed as shown in the screenshot above.

The updated directory structure looks like:



The important point to note is that our EJB is bundled in the WAR file and no additional deployment descriptors were added or existing ones modified to achieve that. Now, that's really clean :)

The next blog in this series will show how managed beans can be replaced with WebBeans, err JCDI.

Also refer to other Java EE 6 blog entries.

Please leave suggestions on other TOTD that you'd like to see. A complete archive of all the tips is available here.

Technorati: totd glassfish v3 mysql javaee6 javaserverfaces jpa2 ejb netbeans

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20090814 Friday August 14, 2009

TOTD #94: A simple Java Server Faces 2.0 + JPA 2.0 application - Getting Started with Java EE 6 using NetBeans 6.8 M1 & GlassFish v3


TOTD #93 showed how to get started with Java EE 6 using NetBeans 6.8 M1 and GlassFish v3 by building a simple Servlet 3.0 + JPA 2.0 web application. JPA 2.0 + Eclipselink was used for the database connectivity and Servlet 3.0 was used for displaying the results to the user. The sample demonstrated how the two technologies can be mixed to create a simple web application. But Servlets are meant for server-side processing rather than displaying the results to end user. JavaServer Faces 2 (another new specification in Java EE 6) is designed to fulfill that purpose.

This Tip Of The Day (TOTD) shows how to enhance the application created in TOTD #93 and use JSF 2 for displaying the results.

  1. Right-click on the project, select "Properties", select "Frameworks", click on "Add ..." as shown below:



    Select "JavaServer Faces" and click on "OK". The following configuration screen is shown:



    Click on "OK" to complete the dialog. This generates a whole bunch of files (7 to be accurate) in your project. Most of these files are leftover from previous version of NetBeans and will be cleaned up. For example, "faces-config.xml" is now optional and "forwardToJSF.jsp" is redundant.
  2. Anyway, lets add a POJO class that will be our managed bean. Right-click on "server" package and select "New", "Java Class ...", give the name as "StateList". Change the class such that it looks like:

    package server;

    import java.util.List;
    import javax.faces.bean.ManagedBean;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.PersistenceUnit;
    import states.States;

    /**
     * @author arungupta
     */
    @ManagedBean
    public class StateList {
        @PersistenceUnit
        EntityManagerFactory emf;

        public List<States> getStates() {
            return emf.createEntityManager().createNamedQuery("States.findAll").getResultList();
        }
    }

    Here are the main characterisitcs of this class:
    1. This is a POJO class with @ManagedBean annotation. This annotation makes this class a managed bean that can be used in the JSF pages. As no other annotations or parameters are specified, this is a request-scoped managed bean with the name "stateList" and lazily initialized. More details about this annotation are available in the javadocs.
    2. The persistence unit created in TOTD #93 is injected using @PersistenceUnit annotation.
    3. The POJO has one getter method that queries the database and return the list of all the states.
  3. In the generated file "template-client.xhtml", change the "head" template to:

    Show States

    and "body" template to:

                    <h:dataTable var="state" value="#{stateList.states}" border="1">
                        <h:column><h:outputText value="#{state.abbrev}"/></h:column>
                        <h:column><h:outputText value="#{state.name}"/></h:column>
                    </h:dataTable>

  4. This uses the standard JSF "dataTable", "column", and "outputText" tags and uses the value expression to fetch the values from the managed bean.

If the application is already running from TOTD #93, then Deploy-on-Save would have automatically deployed the entire application. Otherwise right-click on the project and select Run (default shortcut "F6"). The results can be seen at "http://localhost:8080/HelloEclipseLink/forwardToJSF.jsp" or "http://localhost:8080/HelloEclipseLink/faces/template-client.xhtml" and looks like:



The updated directory structure looks like:



There were multiple files added by the JSF framework support in NetBeans. But as I said earlier, they will be cleaned up before the final release.

Also refer to other Java EE 6 blog entries.

Please leave suggestions on other TOTD that you'd like to see. A complete archive of all the tips is available here.

Technorati: totd glassfish v3 mysql javaee6 javaserverfaces jpa2 netbeans

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20090813 Thursday August 13, 2009

TOTD #93: Getting Started with Java EE 6 using NetBeans 6.8 M1 & GlassFish v3 - A simple Servlet 3.0 + JPA 2.0 app


NetBeans 6.8 M1 introduces support for creating Java EE 6 applications ... cool!

This Tip Of The Day (TOTD) shows how to create a simple web application using JPA 2.0 and Servlet 3.0 and deploy on GlassFish v3 latest promoted build (58 as of this writing). If you can work with the one week older build then NetBeans 6.8 M1 comes pre-bundled with 57. The example below should work fine on that as well.

  1. Create the database, table, and populate some data into it as shown below:

    ~/tools/glassfish/v3/58/glassfishv3/bin >sudo mysql --user root
    Password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 1592
    Server version: 5.1.30 MySQL Community Server (GPL)

    Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

    mysql> create database states;
    Query OK, 1 row affected (0.02 sec)

    mysql> CREATE USER duke IDENTIFIED by 'glassfish';
    Query OK, 0 rows affected (0.00 sec)

    mysql> GRANT ALL on states.* TO duke;
    Query OK, 0 rows affected (0.24 sec)

    mysql> use states;
    Database changed

    mysql> CREATE TABLE STATES (
        ->       id INT,
        ->       abbrev VARCHAR(2),
        ->       name VARCHAR(50),
        ->       PRIMARY KEY (id)
        -> );
    Query OK, 0 rows affected (0.16 sec)

    mysql> INSERT INTO STATES VALUES (1, "AL", "Alabama");
    INSERT INTO STATES VALUES (2, "AK", "Alaska");

    . . .

    mysql> INSERT INTO STATES VALUES (49, "WI", "Wisconsin");
    Query OK, 1 row affected (0.00 sec)

    mysql> INSERT INTO STATES VALUES (50, "WY", "Wyoming");
    Query OK, 1 row affected (0.00 sec)

    The complete INSERT statement is available in TOTD #38. Most of this step can be executed from within the IDE as well as explained in TOTD #38.
  2. Download and unzip GlassFish v3 build 58. Copy the latest MySQL Connector/J jar in "domains/domain1/lib" directory of GlassFish and start the application server as:

    ~/tools/glassfish/v3/58/glassfishv3/bin >asadmin start-domain
  3. Create JDBC connection pool and JNDI resource as shown below:

    ~/tools/glassfish/v3/58/glassfishv3/bin >./asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource --restype javax.sql.DataSource --property "User=duke:Password=glassfish:URL=jdbc\:mysql\://localhost/states" jdbc/states

    Command create-jdbc-connection-pool executed successfully.
    ~/tools/glassfish/v3/58/glassfishv3/bin >./asadmin ping-connection-pool jdbc/states

    Command ping-connection-pool executed successfully.
    ~/tools/glassfish/v3/58/glassfishv3/bin >./asadmin create-jdbc-resource --connectionpoolid jdbc/states jdbc/jndi_states

    Command create-jdbc-resource executed successfully.

  4. Download NetBeans 6.8 M1 and install "All" version. Expand "Servers" node and add the recently installed GlassFish server.
  5. Create a new Web project and name it "HelloEclipseLink". Make sure to choose "GlassFish v3" as the server and "Java EE 6 Web" as the Java EE version as shown below:



    Take defaults elsewhere.
  6. Create the Persistence Unit
    1. Right-click on the newly created project and select "New", "Entity Classes from Database ...". Choose the earlier created data source "jdbc/jndi_states" as shown below:

    2. Select "STATES" table in "Available Tables:" and click on "Add >" and then "Next >".
    3. Click on "Create Persistence Unit ...", take all the defaults and click on "Create". "EclipseLink" is the Reference Implementation for JPA 2.0 is the default choosen Persistence Provider as shown below:

    4. Enter the package name as "server" and click on "Finish".
  7. Create a Servlet to retrieve and display all the information from the database
    1. Right click on the project, "New", "Servlet ...".
    2. Give the Servlet name "ShowStates" and package "server".
    3. Even though you can take all the defaults and click on "Finish" but instead click on "Next >" and the following screen is shown:



      Notice "Add information to deployment descriptor (web.xml)" checkbox. Servlet 3.0 makes "web.xml" optional in most of the common cases by providing corresponding annotations and NetBeans 6.8 leverages that functionality. As a result, no "web.xml" will be bundled in our WAR file. Click on "Finish" now.

      The generated servlet code looks like:



      Notice @WebServlet annotation, this makes "web.xml" optional. TOTD #82 provide another example on how to use Servlet 3.0 with EJB 3.1.
    4. Inject the Persistence Unit as:

          @PersistenceUnit
          EntityManagerFactory emf;

      right above "processRequest" method.
    5. Change the "try" block of "processRequest" method to:

                  List<States> list = emf.createEntityManager().createNamedQuery("States.findAll").getResultList();
                  out.println("<table border=\"1\">");
                  for (States state : list) {
                      out.println("<tr><td>" + state.getAbbrev() +
                              "</td><td>" + state.getName() +
                              "</td></tr>");
                  }
                  out.println("</table>");

      This uses a predefined query to retrieve all rows from the table and then display them in a simple formatted HTML table.
  8. Run the project
    1. Right click on the project, select "Properties" and change the "Relative URL" to "/ShowStates". This is the exact URL that you specified earlier.

    2. Right-click on the project and select "Run" to see the following output:



So we created a simple web application that uses Servlet 3.0, JPA 2.0, EclipseLink and deployed on GlassFish v3 using NetBeans 6.8 M1. NetBeans provides reasonable defaults making you a lazy programmer. Believe this is more evident when you start playing with Java EE support in other IDEs ;-)

Finally, lets look at the structure of the generated WAR file:



It's very clean - no "web.xml", only the relevant classes and "persistence.xml".

Also refer to other Java EE 6 blog entries. A future blog entry will show how to use JSF 2.0 instead of Servlet for displaying the results.

Please leave suggestions on other TOTD that you'd like to see. A complete archive of all the tips is available here.

Technorati: totd glassfish v3 mysql javaee6 servlet3 jpa2 netbeans

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20090811 Tuesday August 11, 2009

TOTD #91: Applying Java EE 6 "web-fragment.xml" to Apache Wicket - Deploy on GlassFish v3


"Extensibility" is a major theme of Java EE 6. This theme enables seamless pluggability of other popular Web frameworks with Java EE 6.

Before Java EE 6, these frameworks have to rely upon registering servlet listeners/filters in "web.xml" or some other similar mechanism to register the framework with the Web container. Thus your application and framework deployment descriptors are mixed together. As an application developer you need to figure out the magical descriptors of the framework that will make this registration.

What if you are using multiple frameworks ? Then "web.xml" need to have multiple of those listeners/servlets. So your deployment descriptor becomes daunting and maintenance nightmare even before any application deployment artifacts are added.

Instead you should focus on your application descriptors and let the framework developer provide the descriptors along with their jar file so that the registration is indeed magical.

For that, the Servlet 3.0 specification introduces "web module deployment descriptor fragment" (aka "web-fragment.xml"). The spec defines it as:

A web fragment is a logical partitioning of the web app in such a way that the frameworks being used within the web app can define all the artifacts without asking devlopers to edit or add information in the web.xml.

Basically, the framework configuration deployment descriptor can now be defined in "META-INF/web-fragment.xml" in the JAR file of the framework. The Web container picks up and use the configuration for registering the framework. The spec clearly defines the rules around ordering, duplicates and other complexities.

TOTD #86 explained how to get started with Apache Wicket on GlassFish. This Tip Of The Day (TOTD) explains how to leverage "web-fragment.xml" to deploy a Wicket application on GlassFish v3. The basic concepts are also discussed here.

For the "Hello World" app discussed in TOTD #86, the generated "web.xml" looks like:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">

        <display-name>helloworld</display-name>

         <!-- 
              There are three means to configure Wickets configuration mode and they are
              tested in the order given.
              1) A system property: -Dwicket.configuration
              2) servlet specific <init-param>
              3) context specific <context-param>
              The value might be either "development" (reloading when templates change)
              or "deployment". If no configuration is found, "development" is the default.
        -->

        <filter>
                <filter-name>wicket.helloworld</filter-name>
                <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
                <init-param>
                        <param-name>applicationClassName</param-name>
                        <param-value>org.glassfish.samples.WicketApplication</param-value>
                </init-param>
        </filter>

 <filter-mapping>
  <filter-name>wicket.helloworld</filter-name>
        <url-pattern>/*</url-pattern>
 </filter-mapping>


</web-app>

This deployment descriptor defines a Servlet Filter (wicket.helloworld) that registers the Wicket framework with the Web container. The filter specifies an initialization parameter that specifies the class name of the Wicket application to be loaded. And it also contains some other information that is also relevant to the framework. None of this application is either required or specified by the application. And so that makes this fragment a suitable candidate for "web-fragment.xml".

Here are the simple steps to make this change:
  1. Remove "src/main/webapp/WEB-INF/web.xml" because no application specific deployment descriptors are required.
  2. Include "wicket-quickstart-web-fragment.jar" in the "WEB-INF/lib" directory of your application by adding the following fragment in your "pom.xml":

        <dependencies>

            . . .
            <!-- web-fragment -->
            <dependency>
                <groupId>org.glassfish.extras</groupId>
                <artifactId>wicket-quickstart-web-fragment</artifactId>
                <version>1.0</version>
                <scope>runtime</scope>
            </dependency>
        </dependencies>

       . . .

        <repositories>
            <repository>
                <id>maven2-repository.dev.java.net</id>
                <name>Java.net Repository for Maven</name>
                <url>http://download.java.net/maven/2/</url>
            </repository>
        </repositories>

    This file contains only "META-INF/web-fragment.xml" with the following content:

    <web-fragment>
            <filter>
                    <filter-name>wicket.helloworld</filter-name>
                    <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
                    <init-param>
                            <param-name>applicationClassName</param-name>
                            <param-value>org.glassfish.samples.WicketApplication</param-value>
                    </init-param>
            </filter>

            <filter-mapping>
                    <filter-name>wicket.helloworld</filter-name>
                    <url-pattern>/*</url-pattern>
            </filter-mapping>
    </web-fragment>

  3. Create the WAR file without "web.xml" by editing "pom.xml" and adding the following fragment:

          <plugins>
                . . .
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.1-beta-1</version>
                    <configuration>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>
                . . .
          </plugins>

That's it, now you can create a WAR file using "mvn package" and deploy this web application on GlassFish v3 latest promoted build (58 as of today) as explained in TOTD #86.

The updated WAR file structure looks like:

helloworld-1.0-SNAPSHOT
helloworld-1.0-SNAPSHOT/META-INF
helloworld-1.0-SNAPSHOT/WEB-INF
helloworld-1.0-SNAPSHOT/WEB-INF/classes
helloworld-1.0-SNAPSHOT/WEB-INF/classes/log4j.properties
helloworld-1.0-SNAPSHOT/WEB-INF/classes/org
helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish
helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish/samples
helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish/samples/HomePage.class
helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish/samples/HomePage.html
helloworld-1.0-SNAPSHOT/WEB-INF/classes/org/glassfish/samples/WicketApplication.class
helloworld-1.0-SNAPSHOT/WEB-INF/lib
helloworld-1.0-SNAPSHOT/WEB-INF/lib/log4j-1.2.14.jar
helloworld-1.0-SNAPSHOT/WEB-INF/lib/slf4j-api-1.4.2.jar
helloworld-1.0-SNAPSHOT/WEB-INF/lib/slf4j-log4j12-1.4.2.jar
helloworld-1.0-SNAPSHOT/WEB-INF/lib/wicket-1.4.0.jar
helloworld-1.0-SNAPSHOT/WEB-INF/lib/wicket-quickstart-web-fragment-1.0.jar

Notice, there is no "web.xml" and the additional "wicket-quickstart-web-fragment-1.0.jar" and everything works as is!

It would be nice if the next version of wicket-*.jar can include "META-INF/web-fragment.xml" then everything will work out-of-the-box :)

Here is a snapshot of the deployed application:



Are you deploying your Wicket applications on GlassFish ?


Technorati: totd glassfish v3 wicket javaee6 servlet web-fragment

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20090519 Tuesday May 19, 2009

TOTD #82: Getting Started with Servlet 3.0 and EJB 3.1 in Java EE 6 using NetBeans 6.7


EJB 3.1 (JSR 318) and Servlet 3.0 (JSR 315) are the two new JSRs in Java EE 6 (JSR 316).

The EJB 3.1 specification provides multiple new features such as WAR packaging, Optional Local Business Interfaces, EJB.lite, Portable Global JNDI Names, Singleton Session Beans (Container-managed and Bean-managed concurrency), Application Initialization and Shutdown events, Timer Service enhancements, Simple/Light-weight Asynchrony, and many other features defined in the specification.

The Servlet 3.0 specification is an update to Servlet 2.5 and focuses on ease-of-use. It also adds several new features such as "web.xml" free deployment (mostly), Dynamic Registration of servlets/filters, Pluggability of frameworks using "web-fragment.xml", Asynchronous API, Security enhancements (Constraints via annotations, programmatic container authentication and logout), and several other miscellaneous additions like default error page, file upload, etc.

GlassFish v3 provides the most complete implementation of EJB 3.1 and Servlet 3.0 along with other Java EE 6 specifications. This Tip Of The Day (TOTD) will show how to create a simple EJB and invoke it from a Servlet, all in a deployment-descriptor free way.

  1. Enable support for v3 Preview in NetBeans
    1. Using NetBeans 6.7 latest nightly, enable support for recent GlassFish v3 builds either using the command-line switch or the marker module.
    2. Download and unzip GlassFish v3 Preview 47b. The latest promoted builds are always available here.
    3. In the "Services" tab, right-click on "Servers" and click on "Add Server". Select "GlassFish v3" as shown below:



      and click on "Next".
    4. Specify location of the previously unzipped bundle, click on "Next >", and press "Finish".
  2. Create a new Web project by right-click in the "Projects" pane, select "New Project", choose "Java Web" and "Web  Application" as categories and projects.
  3. Click on "Next >", choose "Java EE 5" as the Java EE version and click on "Finish". A future version of NetBeans will will provide direct support for Java EE 6.
  4. Add a POJO-based EJB
    1. Right-click on "Source Packages" and select "New", "Java Class..." as shown below:



      Give the class name as "HelloEJB" and package as "server" as shown below:



      and click on "Finish".
    2. Add "@Stateless" class-level annotation and press Shift+Command+I (default shortcut) to fix the imports. This annotation comes from the "javax.ejb" package.
    3. Add the following method:

          public String sayHello(String name) {
              return "Hello " + name;
          }

      to the class. And can you believe it, that's your complete EJB ready to be deployed and that too in a WAR file - the beauty of Java EE 6. The complete class looks like:


      package server;

      import javax.ejb.Stateless;

      /**
       * @author arungupta
       */
      @Stateless
      public class HelloEJB {
          public String sayHello(String name) {
              return "Hello " + name;
          }
      }
  5. Add a Servlet to invoke this EJB
    1. Add a new class "HelloServlet" in the "server" package as explained above.
    2. Add "@WebServlet" class-level annotation and Shift+Command+I to fix the imports. This annotation comes from the "javax.servlet.annotation" package. And specify a URL pattern as:

      @WebServlet(urlPatterns="/hello")
    3. According to the Servlet3 specification, the contract is inherited from the "javax.servlet.http.HttpServlet" interface. So add:

      extends HttpServlet

      to the class.
    4. Inject a local EJB reference using the code:

      @EJB HelloEJB ejbClient;
    5. Override the GET method as:

          @Override
          public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
              res.setContentType("text/html");
              res.getOutputStream().print("<h1>Hosted at: " + req.getContextPath() + "</h1>");
              res.getOutputStream().print("<h2>" + ejbClient.sayHello("Duke") + "</h2>");
          }

      and again Shift+Command+I to fix the imports. The complete class looks like:

      package server;

      import java.io.IOException;
      import javax.ejb.EJB;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;

      /**
       * @author arungupta
       */
      @WebServlet(urlPatterns="/hello")
      public class HelloServlet extends HttpServlet {
          @EJB HelloEJB ejbClient;

          @Override
          public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
              res.setContentType("text/html");
              res.getOutputStream().print("<h1>Hosted at: " + req.getContextPath() + "</h1>");
              res.getOutputStream().print("<h2>" + ejbClient.sayHello("Duke") + "</h2>");
          }
      }
That completes the project creation. Now lets make our application deployment descriptor free by expanding "WEB-INF" directory and deleting "sun-web.xml" and "web.xml". Java EE 6 makes the deployment descriptors optional by introducing equivalent annotations.

Lets run the project by right-click on the project and select "Run". The web application is deployed to GlassFish v3 Preview 47b and "http://localhost:8080/WebApplication1" shows the default "index.jsp" created by the IDE.

Our servlet is accessible at "http://localhost:8080/WebApplication1/hello" and shows the output as:



The directory of the generated WAR file looks like:



As evident "WEB-INF/classes" has only two POJO classes and yet this is a Java EE 6 application.

So we created a trivial Java EE 6 application using Servlet 3 and EJB 3.1 APIs and deployed successfully on GlassFish v3 Preview 47b using NetBeans 6.7.

Please leave suggestions on other TOTD (Tip Of The Day) that you'd like to see. A complete archive of all the tips is available here.

Technorati: totd glassfish v3 javaee6 servlet3 ejb3.1 netbeans

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

Valid HTML! Valid CSS!

This is a personal weblog, I do not speak for my employer.