X

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

Guest Author


EJB 3.1 (JSR
318
) and Servlet 3.0 ( href="http://jcp.org/en/jsr/detail?id=315">JSR 315)
are the two new JSRs in Java EE 6 ( href="http://jcp.org/en/jsr/detail?id=316">JSR 316).



The EJB 3.1 specification provides multiple new features such as href="http://blogs.sun.com/arungupta/entry/ejbs_in_a_war_simplified">WAR
packaging, href="http://blogs.sun.com/kensaks/entry/optional_local_business_interfaces">Optional
Local Business Interfaces, EJB.lite, href="http://blogs.sun.com/kensaks/entry/portable_global_jndi_names">Portable
Global JNDI Names, href="http://blogs.sun.com/MaheshKannan/entry/singleton_ejb_support_in_glassfish">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 href="http://jcp.org/en/jsr/detail?id=318">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 href="http://blogs.sun.com/swchan/entry/servlet_3_0_annotations">"web.xml"
free
deployment (mostly), Dynamic Registration of
servlets/filters,
Pluggability
of frameworks using "web-fragment.xml"
, Asynchronous API,
href="http://blogs.sun.com/swchan/entry/servlet_3_0_security_annotations">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 style="font-weight: bold;">Tip style="font-weight: bold;">Of style="font-weight: bold;">The style="font-weight: bold;">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 href="http://bits.netbeans.org/download/trunk/nightly/latest/">NetBeans
      6.7 latest nightly, enable support for recent GlassFish v3
      builds either using the href="http://blogs.sun.com/vkraemer/entry/7_0_and_glassfish_v3">command-line
      switch or href="http://blogs.sun.com/vkraemer/entry/experimental_features_marker">the
      marker module.
    2. Download and unzip href="http://download.java.net/glassfish/v3-preview/promoted/glassfish-v3-preview-b47b.zip">GlassFish
      v3 Preview 47b. The latest promoted builds are always
      available href="http://download.java.net/glassfish/v3-preview/promoted/">here.
    3. In the "Services" tab, right-click on "Servers" and click
      on "Add Server". Select "GlassFish v3" as shown below:

      alt=""
      src="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/Image/07e1e46598af054bec0c6261f64aa93e/nb67b_v3_registration.png">


      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:

      alt=""
      src="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/Image/24de5aa57efccc432a7636323412c025/nb67_v3_new_class.png">


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

      alt=""
      src="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/Image/1c3e8333998f207f022edc8af4554a0c/nb67_v3_new_class_ejb.png">


      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:

      style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
      cellpadding="2" cellspacing="2">    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:


      style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
      cellpadding="2" cellspacing="2">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:

      style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
      cellpadding="2" cellspacing="2">@WebServlet(urlPatterns="/hello")
    3. According to the Servlet3 specification, the contract is
      inherited from the "javax.servlet.http.HttpServlet" interface. So add:

      style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
      cellpadding="2" cellspacing="2">extends HttpServlet

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

      style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
      cellpadding="2" cellspacing="2">@EJB HelloEJB ejbClient;
    5. Override the GET method as:

      style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
      cellpadding="2" cellspacing="2">    @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:

      style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
      cellpadding="2" cellspacing="2">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:



alt=""
src="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/Image/298a046eb4fe5d4f8617d2099d905ba3/nb67_v3_servlet3_output.png">



The directory of the generated WAR file looks like:



alt=""
src="//cdn.app.compendium.com/uploads/user/e7c690e8-6ff9-102a-ac6d-e4aebca50425/f4a5b21d-66fa-4885-92bf-c4e81c06d916/Image/98a06640826679b0fb71e950b2a5072c/nb67_v3_servlet3_dir_structure.png">



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 href="http://blogs.sun.com/arungupta/tags/totd">here.




Technorati: href="http://technorati.com/tags/totd">totd
href="http://technorati.com/tags/glassfish">glassfish
v3 href="http://technorati.com/tags/javaee6">javaee6 href="http://technorati.com/tags/servlet3">servlet3
ejb3.1
netbeans

Join the discussion

Comments ( 15 )
  • keith Tuesday, July 7, 2009

    Just wonder, is it considered good or bad practice for a Servlet to have direct contact to a EJB Session bean?

    I was creating an App with JSP>Servlet>Bean the bean then connected to the EjbSessionBean which connected to the Persistant class (Entity).

    Then got to thinking, why have I got this standard Bean at all? Would it be OK to connect directly to the EjbSessionBean?

    Or as I say, is this 'bad practice'?


  • guest Monday, August 10, 2009

    This doesn't work, I just get the following error:

    [#|2009-08-11T01:16:41.659+0100|SEVERE|glassfish|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=14;_ThreadName=Thread-1;|StandardWrapperValve[com.myproject.servlets.TestServlet]: PWC1406: Servlet.service() for servlet com.myproject.servlets.TestServlet threw exception

    javax.ejb.AccessLocalException: Client not authorized for this invocation.

    at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1680)

    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:185)

    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:82)

    at $Proxy93.sayHello(Unknown Source)

    at com.myproject.servlets.__EJB31_Generated__TestService__Intf____Bean__.sayHello(Unknown Source)

    at com.myproject.servlets.TestServlet.doPost(TestServlet.java:24)

    at com.myproject.servlets.TestServlet.doGet(TestServlet.java:19)

    at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)

    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)

    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1461)

    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:293)

    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:187)

    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:647)

    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)

    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)

    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)

    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:351)

    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:249)

    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:146)

    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:746)

    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:655)

    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:905)

    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:161)

    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:136)

    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:103)

    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:89)

    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)

    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)

    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)

    at com.sun.grizzly.ContextTask.run(ContextTask.java:69)

    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

    at java.lang.Thread.run(Thread.java:619)

    |#]


  • Arun Gupta Monday, August 10, 2009

    Which GlassFish build did you try ?


  • Keith Tuesday, August 11, 2009

    Glassfish v3.0 Preview (build 47.4)


  • Keith Tuesday, August 11, 2009

    madness, complete madness!

    Cleared out all my deployed apps, restarted the PC, rebuilt the EAR and redeployed and now it works...

    Was up 'til 2am last night with this, now after 30 mins it just decides it feels like working!

    :-D

    I do find this v3 GlassFish very flakey, I knows it's a preview version, but there are a lot of issues with the 'undeploy', 'redeploy' and sometimes just deploying funtionality (got a NullPointer the first time I tried to deploy the EAR, second time it was fine)


  • Arun Gupta Tuesday, August 11, 2009

    Keith,

    Sorry for the frustration. Can you please file a bug if you are able to reproduce the issue ?

    With GlassFish v3, you can just remove the "glassfishv3" directory and it's as if it was never installed.


  • Keith Wednesday, August 12, 2009

    Glassfish v3 is only a preview version so I can cope with the flakey bits,

    The issue I had has returned, it's an issue with my persistent layer and the DB by the looks of it.

    I had this working running on a previous version of Glassfish but for v3 it's a no goer.

    I have my persistence.xml using Toplink for now with a datasource called JDBC/Test.

    I have the connpool and JDBC conn created in Glassfish and a test of the 'ping' function works.

    I have the mysql-connector-java-5.0.5-bin.jar in the //glassfish/domains/domain1/lib/ext

    but as soon as I get to method to execute the persistent layer I get this error.


  • Arun Gupta Wednesday, August 12, 2009

    Keith,

    GlassFish v3 comes bundled with EclipseLink and your application is using TopLink. Could that be a problem ? It may be a fake error message.

    I'll try something similar on the lines you mentioned above and describe in a blog.


  • Arun Gupta Wednesday, August 12, 2009

    Keith,

    Scheduled a blog for tomorrow morning showing how to create a simple JPA/EclipseLink application using NetBeans 6.8 M1 and deploy on GlassFish build 58. Let me know if that'll be helpful.


  • Keith Wednesday, August 12, 2009

    Good news!

    Dropped build build 47.4 and replaced it with GlassFish v3.0-b58 (build 58) and it worked!

    Same app, same config as I've mentioned above works under this build.


  • Arun Gupta Wednesday, August 12, 2009

    Congratulations!

    I was pretty amazed that my simple app worked without any issue as well :)


  • Arun Gupta's Blog Thursday, August 13, 2009
    [Trackback] 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...
  • Keith Wednesday, September 2, 2009

    Hi Arun,

    Thatnks for your help on all this, however I have another question.

    I recently had to replace my HD as the last died, I have reinstalled GF b_58 and have an old copy of my previous EAR file, but now when I deploy I get the folowing error:

    # Cannot load com.sun.enterprise.webservice.apt.WebServiceRefAp$ServiceRefVisitor reason : com.sun.enterprise.webservice.apt.WebServiceRefAp$ServiceRefVisitor

    # java.lang.ClassNotFoundException: com.sun.enterprise.webservice.apt.WebServiceRefAp$ServiceRefVisitor

    What could be causing this, do you know?

    Thanks


  • Keith Wednesday, September 2, 2009

    Scrap that last question, using the b58 exe rather than b58 zip and have now got it working.


  • Arun Gupta Wednesday, September 2, 2009

    Cool!


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.