Monday Aug 10, 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

Thursday Jul 30, 2009

TOTD #87: How to fix the error undefined method `new' for "Rack::Lock":String caused by Warbler/JRuby-Rack ?


If you are using Warbler to create a WAR file of your application and deploying on GlassFish or any other Servlet container, then you are likely seeing the following error during deployment:

[#|2009-07-30T15:29:50.788-0700|SEVERE|sun-appserver2.1|javax.enterprise.system.container.web|_ThreadID=17;
_ThreadName=httpWorkerThread-4848-0;_RequestID=1d7e8f18-1c9a-4924-bd0b-6a07eba425ba;|WebModule
[/session]unable to create shared application instance
org.jruby.rack.RackInitializationException: undefined method `new' for "Rack::Lock":String
        from /Users/arungupta/tools/glassfish/v2.1/glassfish/domains/domain1/applications/j2ee-modules/session/WEB-INF/gems/gems/actionpack-2.3.2/lib/
action_controller/middleware_stack.rb:116:in `inject'
        from /Users/arungupta/tools/glassfish/v2.1/glassfish/domains/domain1/applications/j2ee-modules/session/WEB-INF/gems/gems/actionpack-2.3.2/lib/
action_controller/middleware_stack.rb:116:in `build'
        from /Users/arungupta/tools/glassfish/v2.1/glassfish/domains/domain1/applications/j2ee-modules/session/WEB-INF/gems/gems/actionpack-2.3.2/lib/
action_controller/dispatcher.rb:82:in `initialize'

. . .

This is a known issue as reported at JRUBY-3789 and JRUBY_RACK-18.

As the bug report indicates, this is actually an issue with jruby-rack-0.9.4 and is fixed in jruby-rack-0.9.5. The 3-step workaround is described here and explained below for convenience:
  1. Do "warble war:clean" to clean up the .war file and staging area. This basically removes previous version of jruby-rack.jar.
  2. Download the latest jruby-rack-0.9.5 snapshot (complete list) and copy in the "lib" directory of your application.
  3. If "config/warble.rb" does not exist then generate it using "jruby -S config warble". Edit "config/warble.rb" such that it looks like:

      # Additional Java .jar files to include. Note that if .jar files are placed
      # in lib (and not otherwise excluded) then they need not be mentioned here.
      # JRuby and JRuby-Rack are pre-loaded in this list. Be sure to include your
      # own versions if you directly set the value
      # config.java_libs += FileList["lib/java/\*.jar"]
      config.java_libs.delete_if {|f| f =~ /jruby-rack/ }
      config.java_libs += FileList["lib/jruby-rack\*.jar"]

    This will pack jruby-rack-0.9.5 snapshot instead of the one bundled with Warbler.

    Now warbler 1.0.0 bundles "jruby-complete-1.3.0RC1.jar". Optionally, you can also download the latest jruby-complete (jruby-complete-1.3.1.jar as of this writing) and copy in the "lib" directory of your application. In that case, modify the above fragment to:

      # Additional Java .jar files to include. Note that if .jar files are placed
      # in lib (and not otherwise excluded) then they need not be mentioned here.
      # JRuby and JRuby-Rack are pre-loaded in this list. Be sure to include your
      # own versions if you directly set the value
      # config.java_libs += FileList["lib/java/\*.jar"]
      config.java_libs.delete_if {|f| f =~ /jruby-rack/ || f =~ /jruby-complete/ }
      config.java_libs += FileList["lib/jruby-complete\*.jar"]
      config.java_libs += FileList["lib/jruby-rack\*.jar"]

    This packs the "jruby-complete-1.3.1.jar" in your .war file.
And now follow your regular procedure of creating the .war file using "jruby -S warble" and happily deploy your Rails/Sintara/Merb applications on GlassFish.

There are several users who are already using Rails on GlassFish in production environment and they are listed at rubyonrails+glassfish+stories. Drop a comment on this blog if you are using it too :)

Technorati: jruby rack glassfish war servlet rubyonrails

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

Wednesday May 13, 2009

GlassFish and Servlet 3.0 Slides from San Francisco JUG


As mentioned earlier, Jan and I talked about GlassFish and Servlet 3.0 at the San Francisco JUG yesterday night. Approximately 40 attendees and a great Q&A session at the end made it a truly enjoying experience.

The GlassFish slides are available here and Servlet 3.0 slides are available here.

And did you register for JavaOne ? The GlassFish team will be there in full force and you'll be immersed in similar talks.

Here are some pictures from around the venue and the attendees:



Technorati: conf jug sfjug sanfrancisco glassfish servlet

Tuesday Nov 18, 2008

Screencast #28: Simple Web Application using Eclipse and GlassFish v3 Prelude


GlassFish v3 Prelude is now available! Some of the cool features are:
  • Modularity using OSGi
  • Rapid deployment using retain session data across HTTP redeploys and deploy-on-save
  • Embeddability
  • Dynamic languages and frameworks
  • Faster start up time
  • Integrated NetBeans and Eclipse tooling
  • Comet and Cometd
This screencast shows how you can create a simple Web application using JSP and Servlets in Eclipse 3.4, deploy it directly on GlassFish v3, use rapid deployment, and debug the application.


The GlassFish plugin for Eclipse has many more features than demonstrated in this screencast and are explained here.

A complete list of GlassFish related screencasts is available here. Other screencasts published on this blog are available here.

Also see GlassFish v3 running using Equinox, Rails and Merb applications using GlassFish Gem, and Embeddable GlassFish.

Submit your bugs Eclipse/GlassFish bugs here, talk to us using GlassFish Plugins Forum, and get the latest information on glassfishplugins.dev.java.net.

Technorati: screencast glassfish v3 eclipse jsp servlets deployonsave deployment

Sunday Nov 09, 2008

Screencast #27: Simple Web Application using NetBeans 6.5 IDE and GlassFish v3 Prelude


GlassFish v3 Prelude is now available!

It contains a Java EE 5-based Web stack. A comprehensive tooling by NetBeans IDE allows to easily develop Web applications and deploy directly on GlassFish v Prelude. Rapid deployment feature of GlassFish allows to redeploy applications without losing session state. Using the deploy-on-save feature of NetBeans the complete development cycle is reduced to edit-save-refresh. There is no longer a need to wait for explicit deployment any more, cool isn't it ?

And you can even purchase enterprise support as well!

This screencast shows how you can create a simple Web application using JSP and Servlets in NetBeans IDE, deploy it directly on GlassFish v3 and then debug it.


Are you still doing the conventional edit-save-deploy-refresh conventional development cycle ? Use NetBeans and GlassFish together to liberate yourself :)

File GlassFish related bugs here using "web_container" sub-component. File NetBeans related bug here using "glassfish_v3" sub-component. Ask your GlassFish related questions on webtier@glassfish.dev.java.net or NetBeans related questions on nbusers@netbeans.org.

All other GlassFish related screencasts are available here.

Technorati: glassfish v3 netbeans jsp servlets deployonsave deployment screencast

Wednesday Jul 23, 2008

Job Opportunity in GlassFish Web Container Team

What's common between
You are right - GlassFish is the answer!

If you are a fresh graduate, then apply for GlassFish Scripting team. However if you have
  • Experience in Developing Web container and related web-tier technologies such as JSP, Servlets, Java Server Faces and Java Standard Tag Libraries
  • Like to define the direction of Web container in Java EE platform and GlassFish Application Server
  • Worked in the Open Source & distributed teams
  • Like to play "follow the leader" where you are the leader :)
Then GlassFish team needs you. Apply now!

Technorati: glassfish webtier jsp servlets jstl javaserverfaces job

Wednesday Jul 09, 2008

Getting Started with GlassFish in IntelliJ IDEA


IntelliJ IDEA 7.0.x include plugins that provide support for configuring GlassFish. This blog provides clear instructions on how to get started by developing and deploying a JSP, Servlet and Web services using GlassFish in IntelliJ. The instructions are using IntelliJ 7.0.3 Build #7757 (with no additional plugins).
  1. Create a new project
    1. Clicking on "Create New Project" or "File", "New Project". Take the default as shown below:



      and click on "Next >".
    2. Enter the project name as "GlassFishRocks" and take all defaults as shown:



      and click on "Next >".
    3. Take another default for the source directory as shown:



      and click on "Next >".
    4. For the first time use, JDK needs to be specified. Click on "+" in top-left corner as shown here:



      Take the default option of "JSDK" and specify the Home Directory as shown:



      Click on "OK" and then click on "Next >".
    5. Let's create a Web application. Select the list of technologies as shown:



      and finally (phew!) click on "Finish". The expanded project looks like:

  2. Create a GlassFish configuration
    1. Select "Run", "Edit Configurations" as shown:


    2. Click on "+" on top-left corner and select GlassFish as shown below:


    3. Specify the location of GlassFish Application server at:



      by clicking on "Configure" button and enter the values as shown:



      and click on "OK". You can download and install GlassFish v2 UR2 from here.
    4. Enter the "Name" and select the "Server Domain" as shown:



      and click on "OK".
  3. Deploy the Web application
    1. Click on the green button in the toolbar:


    2. Click on the "Fix" button on the bottom and then click "Run". The recently created Web module is selected to be deployed as shown:

    3. This starts the GlassFish v2 UR2 Application Server and deploys the Web application showing the console as:



      and also shows the default page at "http://localhost:8080/GlassFishRocksWeb/". You can edit "index.jsp", re-deploy the Web facet and refresh the page to see the updated message.

      Notice, even though project's name is "GlassFishRocks", the application context root is "GlassFishRocksWeb".
  4. Now lets create/deploy a new Servlet.
    1. Create a new project as described above and name it "KillerServlet".
    2. Right-click on the project and select "New", "Servlet" as shown:

    3. Enter the values as shown:



      and click on "OK".
    4. The "Java EE: Structure" shows the project as:


    5. Double-click on "HelloServlet" (nested one) and add the following fragment to "doGet" method:

              java.io.PrintWriter out = response.getWriter();
              try {
                  out.println("<html>");
                  out.println("<head>");
                  out.println("<title>Servlet NewServlet</title>");
                  out.println("</head>");
                  out.println("<body>");
                  out.println("<h1>Servlet NewServlet at " + request.getContextPath () + "</h1>");
                  out.println("</body>");
                  out.println("</html>");
              } finally {
                  out.close();
              }

      NetBeans IDE auto-generates this code for a Servlet ;-) And add the following to "doPost" method:

             doGet(request, response);
    6. Double-click on "web.xml" and then select "Assembly Descriptor" tab.
    7. Click on "+" in Servlet Mappings and specify the values as:


    8. Deploy the project (as described above) and output from Servlet is displayed at "http://localhost:8080/KillerServletWeb/hello". Read more details in Creating Java EE Apps and Servlets with IntelliJ IDEA.

      Remember the weird context root, it's "KillerServletWeb" instead of "KillerServlet". Now there may be a good reason to do so but nothing obvious.
  5. Now lets create a simple Web service using the Metro Web services stack (the stack baked into GlassFish)
    1. Create a new project with name "GlassFishWS" following the instructions given above.
    2. Select the list of technologies as shown:

    3. The default generated Web service looks like:

    4. The default generated Web service uses light-weight Endpoint API to host the endpoint. Run the Web service by right-clicking in the editor pane and selecting "Run" as shown or default shortcut of Ctrl+Shift+F10:

    5. The WSDL is now available at "http://localhost:9000/HelloWorld?wsdl".
    6. Right-click on the project and select "New", "Web Service Client" as shown:



      enter the value as "WSClient" and click on "OK".
    7. In the next dialog, enter the values as shown:

    8. The generated client code has some errors as shown:



      Change the code to:

            client.HelloWorld service = new client.HelloWorldService().getHelloWorldPort();
            //invoke business method
            System.out.println(service.sayHelloWorldFrom("Duke"));

      and run WSClient.main to see the result as:



      Now you deployed a Metro Web service using light-weight Endpoint API.  The bundled plugin version is 0.9 build 2 and the steps are so much cleaner from 0.7 version of the plugin.

      Read more about Web Services support in IntelliJ IDEA.
    9. Deploying this Web service on GlassFish is really simple.
      1. Create a new GlassFish configuration as explained above.
      2. Run the project using this configuration and the Web service is now hosted at "http://localhost:8080/GlassFishWSWeb/services/HelloWorld?wsdl".
      3. Generate a client using the steps described above.
Here are few issues filed:
  • JEEAS-180 does not allow an application to be re-deployed to GlassFish and that's why the examples above use different projects.
  • JEEAS-181  asks for better integration of GlassFish logs in the IDE.
  • JEEAS-182 require support for GlassFish v3 in the GlassFish plugin. Please help by voting for this issue.
  • WSVC-61 reports the errors generated in Web services client code
So whether you are using Eclipse, IntelliJ or NetBeans - you can easily configure GlassFish and deploy your applications directly from within the IDE. Here are some related links:
However of all the IDEs, NetBeans IDE still provides the most comprehensive coverage in terms of development and deployment of Java EE applications (JSP, Servles, Java Server Faces, SOAP-based .NET 3.0-interoperable Web service, RESTful Web services, JPA, EJBs) and server plug-ins (GlassFish, Tomcat, JBoss, WebLogic, WebSphere, OC4J, SAP BusinessOne and JOnAS).


Technorati: glassfish intellij idea jsp servlets metro webservices

Wednesday May 21, 2008

Embeddable GlassFish in Action - Servlet in a Maven project

Kohsuke announced the embedability of GlassFish v3 - this is really cool! Now you can run GlassFish inside an existing JVM, without the need to start it externally. The API javadocs are available here. This blog explains how to host a Servlet using these APIs and write a simple Maven test to invoke the Servlet - all within the same VM.

The blog creates a Maven project using NetBeans but Maven CLI can be used as well.

In the NetBeans IDE, if Maven plugin is not already installed, then install it using "Tools", "Plugins","Available Plugins".
  1. Create a new Maven project
    1. Create a new project in NetBeans IDE and select "Maven" types as shown below



      Click on "Next >".
    2. Take the default "Archetype" as shown:



      Click on "Next >".
    3. Enter the "Project Name" and "Artifact Id" as shown below:



      and click on "Finish". The following output is shown in NetBeans Output window:



      This confirms the successful creation of the project.

      The command-line equivalent for all the above steps is:

      mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=org.glassfish.embedded.samples -DartifactId=webtier
  2. Update pom.xml with repositories & dependencies
    1. Expand "Project Files" and open "pom.xml". Add the following repositories (right after <url>...</url> tags)

      <repositories>
          <repository>
            <id>glassfish-repository</id>
            <name>Java.net Repository for Glassfish</name>
            <url>http://download.java.net/maven/glassfish</url>
          </repository>
          <repository>
            <id>download.java.net</id>
            <name>Java.net Maven Repository</name>
            <url>http://download.java.net/maven/2</url>
          </repository>
        </repositories>
    2. Add the following fragment after "<repositories>" to set the target JDK as 1.5:

      <build>
          <plugins>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>2.0.2</version>
              <configuration>
                <source>1.5</source>
                <target>1.5</target>
             </configuration>
           </plugin>
         </plugins>
       </build>
    3. Add the following dependencies (inside "<dependencies>" and after "</dependency>")

      <dependency>
            <groupId>org.glassfish.distributions</groupId>
            <artifactId>web-all</artifactId>
            <version>10.0-build-20080430</version>
          </dependency>
          <dependency>
            <groupId>org.glassfish.embedded</groupId>
            <artifactId>gf-embedded-api</artifactId>
            <version>1.0-alpha-4</version>
          </dependency>
  3. Add Servlet class
    1. Right-click on "Source packages", select "New", "Java Class..." and enter the value as shown below



      and click on "Finish".
    2. Replace the template class with the following Servlet

      package org.glassfish.embedded.samples.webtier;

      import java.io.IOException;
      import java.io.PrintWriter;
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;

      /\*\*
       \* @author Arun Gupta
       \*/
      public class SimpleServlet extends HttpServlet {

          @Override
          protected void doGet(HttpServletRequest request,
                  HttpServletResponse response)
                  throws ServletException, IOException {
              PrintWriter out = response.getWriter();
              out.println("Wow, I'm embedded!");
          }
      }

      This is a simple Servlet class.
  4. Add deployment descriptor (this step could be made optional with possibly a default mapping)
    1. In the "Files" window, expand "src", "main", right-click and select "New", "Folder..." as shown below ...



      and give the folder name as "resources" as shown ...



      ... click on "Finish".
    2. Using the same mechanism, create a new folder "WEB-INF" in "resources". Right-click on "WEB-INF" and select "New", "XML Document..." as shown:

    3. Enter the name as "web" as shown


    4. Click on "Next >", take defaults and click on "Finish". Replace the content of generated "web.xml" with the following ...

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
          <servlet>
              <servlet-name>SimpleServlet</servlet-name>
              <servlet-class>org.glassfish.embedded.samples.webtier.SimpleServlet</servlet-class>
          </servlet>
          <servlet-mapping>
              <servlet-name>SimpleServlet</servlet-name>
              <url-pattern>/SimpleServlet</url-pattern>
          </servlet-mapping>
      </web-app>

  5. Add a new test to invoke the Servlet
    1. In "Projects", expand "Test Packages" and open "org.glassfish.embedded.samples.webtier.AppTest" as shown:

    2. Add the following fragment at end of the class:

          private final String NAME = "AppTest";

          public void testServlet() throws Exception {
              int port = 9999;
              GlassFish glassfish = newGlassFish(port);
              URL url = new URL("http://localhost:" + port + "/" + NAME + "/SimpleServlet");
              BufferedReader br = new BufferedReader(
                      new InputStreamReader(
                      url.openConnection().getInputStream()));
              assertEquals("Wow, I'm embedded!", br.readLine());
              glassfish.stop();
          }

          private GlassFish newGlassFish(int port) throws Exception {
              GlassFish glassfish = new GlassFish(port);
              ScatteredWar war = new ScatteredWar(NAME,
                      new File("src/main/resources"),
                      new File("src/main/resources/WEB-INF/web.xml"),
                      Collections.singleton(new File("target/classes").toURI().toURL()));
              glassfish.deploy(war);
              System.out.println("Ready ...");
              return glassfish;
          }
    3. Right-click in the editor window and select "Fix Imports" as shown


    4. Take all the defaults as shown



      and click on "OK".
    5. The complete project structure looks like:

  6. Run the Test (mvn test)
    1. In Projects window, right-click the project and select "Test" as shown:

    2. The Output window shows the result as:



      Notice how GlassFish v3 started in 598 milliseconds (around 0.5 sec) and all the tests passed.
This is a work in progress and we would like to hear your feedback at users@glassfish and GlassFish Forum.

How are you using GlassFish embeddability ?

Technorati: glassfish v3 embedded servlet netbeans

Sunday Apr 13, 2008

Rails and Java EE integration - Native Rails on GlassFish v3


The last part of this tri-series blog (Part 1, Part 2) will show how a Rails application can be deployed on GlassFish - without the need of Goldspike, Warbler or any other gem or plugin. Yes, that's a native Rails app deployment on GlassFish v3.

GlassFish v3 is next version of GlassFish v2 and the focus is modularization, enablement of non-Java EE containers and modularity - download b09.

Rails powered by GlassFish provides all the details on why GlassFish provides an industry-grade and functionally-rich Application Server.

Now detailed steps:
  1. Using JRuby 1.1 (installed with Rails), create a Rails app "railsee3" as:

    ~/testbed/jruby-1.1/samples/rails >../../bin/jruby -S rails railsee3
          create 
          create  app/controllers
          create  app/helpers
          create  app/models
          . . .
          create  log/production.log
          create  log/development.log
          create  log/test.log
  2. Add Servlet descriptors
    1. Create a new directory "WEB-INF", and a new file "web.xml" in that directory using the following contents:

      <!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>
              <servlet>
                      <servlet-name>HelloServlet</servlet-name>
                      <servlet-class>server.HelloServlet</servlet-class>
              </servlet>
              <servlet-mapping>
                      <servlet-name>HelloServlet</servlet-name>
                      <url-pattern>/hello</url-pattern>
              </servlet-mapping>
      </web-app>
    2. Create a new file "sun-web.xml" in "WEB-INF" using the following contents:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" "http://www.sun.com/software
      /appserver/dtds/sun-web-app_2_5-0.dtd">
      <sun-web-app error-url="">
        <context-root>/servlet</context-root>
        <class-loader delegate="true"/>
      </sun-web-app>
    3. Create a new directory "WEB-INF/lib".
  3. Create and Copy Servlet
    1. Create a Java library with Servlet code as explained in bullet #5 here.
    2. Copy "HelloServlet.jar" from "dist" directory of NetBeans project to "WEB-INF/lib" directory.
  4. Configure JRuby-on-Rails in GlassFish - Edit "config/asenv.conf" in GlassFish directory and specify JRUBY_HOME as the last line:

    JRUBY_HOME="/Users/arungupta/testbed/jruby-1.1"

  5. Deploy the Rails application as:

  6. ~/testbed/jruby-1.1/samples/rails >~/testbed/glassfish/v3/p2b9/glassfish/bin/asadmin deploy --force=true railsee3
    railsee3 deployed successfully
    Command deploy executed successfully.
  7. The bundled Servlet is now accessible at "http://localhost:8080/servlet/hello". The default browser output looks like:



    And passing a parameter to the URL as "http://localhost:8080/railsee3/hello?name=Arun" shows the output as:


With this, your Java EE Servlet is now bundled with your Rails application deployed on GlassFish v3.

Now, lets add Controller and View to Rails application and invoke this servlet from there to show complete integration with Rails.
  1. Create a new Controller and View as

    ~/testbed/jruby-1.1/samples/rails/railsee3 >../../../bin/jruby script/generate controller home index
    JRuby limited openssl loaded. gem install jruby-openssl for full support.
    http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
          exists  app/controllers/
          exists  app/helpers/
          create  app/views/home
          exists  test/functional/
          create  app/controllers/home_controller.rb
          create  test/functional/home_controller_test.rb
          create  app/helpers/home_helper.rb
          create  app/views/home/index.html.erb
  2. Change the generated controller in "app/controllers/home_controller.rb" to:

    class HomeController < ApplicationController

    include Java

      def index
            url = java.net.URL.new("http://localhost:8080/servlet/hello");
            conn = url.open_connection;
            reader = java.io.BufferedReader.new(java.io.InputStreamReader.new(conn.get_input_stream));
            @servlet_output = "";
            input_line = reader.read_line;
            while input_line != nil
                    @servlet_output << input_line;
                    input_line = reader.read_line;
            end
            reader.close;
      end
    end
  3. Change the generated view in "app/views/home/index.rhtml.erb" to:

    <h1>Home#index</h1>
    <p>Find me in app/views/home/index.html.erb</p>

    <%= @servlet_output %>
  4. Re-deploy the Rails application as shown in bullet # 5 above and "http://localhost:8080/railsee3/home/index" shows the output as shown:

So this blog explained how a Rails application can be deployed on GlassFish v3 without the need of any gems like Warbler or plugin like Goldspike - total native deployment!

In summary, the tri-part blog showed the deployment models for a Rails application on GlassFish. Each model showed how a Java EE 5 Servlet can be co-bundled with Rails application and invoked from Rails view:
Technorati: rubyonrails netbeans glassfish v3 javaee5 servlets jruby ruby warbler
About

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


Java EE 7 Samples

Stay Connected

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today