Monday Nov 26, 2012

What's new in EJB 3.2 ? - Java EE 7 chugging along!


EJB 3.1 added a whole ton of features for simplicity and ease-of-use such as @Singleton, @Asynchronous, @Schedule, Portable JNDI name, EJBContainer.createEJBContainer, EJB 3.1 Lite, and many others. As part of Java EE 7, EJB 3.2 (JSR 345) is making progress and this blog will provide highlights from the work done so far. This release has been particularly kept small but include several minor improvements and tweaks for usability.

  • More features in EJB.Lite
    • Asynchronous session bean
    • Non-persistent EJB Timer service

      This also means these features can be used in embeddable EJB container and there by improving testability of your application.
  • Pruning - The following features were made Proposed Optional in Java EE 6 and are now made optional.
    • EJB 2.1 and earlier Entity Bean Component Contract for CMP and BMP
    • Client View of an EJB 2.1 and earlier Entity Bean
    • EJB QL: Query Language for CMP Query Methods
    • JAX-RPC-based Web Service Endpoints and Client View

      The optional features are moved to a separate document and as a result EJB specification is now split into Core and Optional documents. This allows the specification to be more readable and better organized.
  • Updates and Improvements
    • Transactional lifecycle callbacks in Stateful Session Beans, only for CMT. In EJB 3.1, the transaction context for lifecyle callback methods (@PostConstruct, @PreDestroy, @PostActivate, @PrePassivate) are defined as shown.


      @PostConstruct @PreDestroy
      @PrePassivate
      @PostActivate
      Stateless
      Unspecified
      Unspecified N/A
      N/A
      Stateful
      Unspecified Unspecified Unspecified Unspecified
      Singleton
      Bean's transaction
      management type
      Bean's transaction
      management type
      N/A
      N/A

      In EJB 3.2, stateful session bean lifecycle callback methods can opt-in to be transactional. These methods are then executed in a transaction context as shown.


      @PostConstruct @PreDestroy
      @PrePassivate
      @PostActivate
      Stateless
      Unspecified
      Unspecified N/A
      N/A
      Stateful
      Bean's transaction
      management type
      Bean's transaction
      management type
      Bean's transaction
      management type
      Bean's transaction
      management type
      Singleton
      Bean's transaction
      management type
      Bean's transaction
      management type
      N/A
      N/A

      For example, the following stateful session bean require a new transaction to be started for @PostConstruct and @PreDestroy lifecycle callback methods.

      @Stateful
      public class HelloBean {
         @PersistenceContext(type=PersistenceContextType.EXTENDED)
         private EntityManager em;
         @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
         @PostConstruct
         public void init() {
              myEntity = em.find(...);
         }

         @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)    @PostConstruct    public void destroy() {        em.flush();    }
      }

      Notice, by default the lifecycle callback methods are not transactional for backwards compatibility. They need to be explicitly opt-in to be made transactional.
    • Opt-out of passivation for stateful session bean - If your stateful session bean needs to stick around or it has non-serializable field then the bean can be opt-out of passivation as shown.

      @Stateful(passivationCapable=false)
      public class HelloBean {
          private NonSerializableType ref = ...

      . . .

      }
    • Simplified the rules to define all local/remote views of the bean. For example, if the bean is defined as:
      @Stateless
      public class Bean implements Foo, Bar {
          . . .
      }
      where Foo and Bar have no annotations of their own, then Foo and Bar are exposed as local views of the bean. The bean may be explicitly marked @Local as
      @Local
      @Stateless
      public class Bean implements Foo, Bar {
          . . .
      }

      then this is the same behavior as explained above, i.e. Foo and Bar are local views.

      If the bean is marked @Remote as:
      @Remote
      @Stateless
      public class Bean implements Foo, Bar {
          . . .
      }
      then Foo and Bar are remote views. If an interface is marked @Local or @Remote then each interface need to be explicitly marked explicitly to be exposed as a view. For example:

      @Remote
      public interface Foo { . . . }

      @Stateless
      public class Bean implements Foo, Bar {
          . . .
      }
      only exposes one remote interface Foo.

      Section 4.9.7 from the specification provide more details about this feature.
    • TimerService.getAllTimers is a newly added convenience API that returns all timers in the same bean. This is only for displaying the list of timers as the timer can only be canceled by its owner.
    • Removed restriction to obtain the current class loader, and allow to use java.io package. This is handy if you want to do file access within your beans.
    • JMS 2.0 alignment - A standard list of activation-config properties is now defined
      • destinationLookup
      • connectionFactoryLookup
      • clientId
      • subscriptionName
      • shareSubscriptions
    • Tons of other clarifications through out the spec. Appendix A provide a comprehensive list of changes since EJB 3.1.
    • ThreadContext in Singleton is guaranteed to be thread-safe.
    • Embeddable container implement Autocloseable.

A complete replay of Enterprise JavaBeans Today and Tomorrow from JavaOne 2012 can be seen here (click on CON4654_mp4_4654_001 in Media).

The specification is still evolving so the actual property or method names or their actual behavior may be different from the currently proposed ones.

Are there any improvements that you'd like to see in EJB 3.2 ? The EJB 3.2 Expert Group would love to hear your feedback. An Early Draft of the specification is available. The latest version of the specification can always be downloaded from here.

These features will start showing up in GlassFish 4 Promoted Builds soon.

Wednesday Apr 13, 2011

JAX London Spring 2011 Trip Report

Sebastian Meyen, the chair of worldwide JAX Conference kick started JAX London 2011 with a very passionate opening session highlighting that JAX is all about Java, that they are comitted to Java, and not going to dilute the content. This is the 10th year of JAX conferences. Even though originally the word JAX was coined as an acronym for "Java Apache XML" indicating the open source nature and everything XML around Java but now its more popularly known as JAX.

The successful recipe for the JAX conference is "passion for the Java platform & ecosystem" and "a pramatic mix with development, architecture, agile, and other concepts around Java". In Sebastien's words "Java is a huge stake, heavily growing, innovating and worth focusing on it" and is a "rich environment for innovation". The JAX Innovation Awards giving $10,000 for the most innovative contributions to Java further proves their commitment to Java. Do you have the most innovative Java technology, most innovative Java company, and the top Java ambassador to recommend ? Submit now!

The first keynote of the day was by Dan North on the "Patterns of Effective Delivery". He highlighted several design patterns and the key ones were:

  • Spike and Stabilise - "Spike" is the non-TDD code written during the development cycle and then TDD applied to stabilise it for production.
  • Ginger Cake - About me legitimizing copy/paste, look for abstractions afterwards. Start WET and then DRY it.
  • Create Urgency - Create lots of instances where you are surprised, optimize for deliberate learning than for deliberate practice. Create an urgency for yourself for technologies that are genuinely useful. Difficult to change your thinking consciously, need a crisis.
  • Socratic Testing - Using the process of automated tests to draw out knowledge about the code.
  • Fits In My Head - Keeping the design small enough such that the entire design fits in your head, then you can reason the whole thing.

Being the chair of Java EE track, I spent most of my day attending the sessions there. The first session by Ales Justin explained how to run a Java EE application on Google App Engine. His slides are available below:

Ales explained his experience of building a sample application using JPA2, JSF2, Bean Validation, delpoing on GAE. The slides very well capture the restrictions of the platform and how he worked around them. The GAE API was even abstracted such that a pure Java EE application can be written and thus be portable across multiple application servers.

David Blevins's session on Fun with EJB 3.1 and Open EJB was indeed a lot of fun. He provided a good history of how the EJB and OpenEJB have evolved over years. There were lots of code samples highlighting the ease-of-use improvements done in EJB 3.1such as @Stateless, @Schedule, @Asynchronous, @Singleton, Embeddable EJB API and many others. I particularly loved his statement:

People who complain about EJB are stuck in 2005 and believe ignorance is my pride.  Its testable, light, and pretty great!

Seriously, if you complain about EJB being heavy, non-functional, incomplete, the following code fragment is all it takes to create an EJB:

@Stateless
public class MyEJB {
    public String myMethod(...) { }
}

and that too packaged in a WAR file, no deployment descriptors or any special packaging. Do you still think its heavy weight ? Think again!

David's slides are available below:

Doug Clarke talked about "Java Persistence API 2.0 with EclipseLink", Joseph Shum talked about "Integrating Enterprise Applications into Liferay Portal", and then Dan Allen talked about "Using CDI Extensions to make a better Java EE". Dan showed several examples of how CDI extensions can be authored easily to extend capabilites of the existing platform. Their slides will be available on jaxlondon.com.

And I also gave two presentations:

  • GlassFish 3.1 - Simplifying your Java EE 6 Development and Deployment
  • OSGi-enabled Java EE Applications using GlassFish (in the OSGi track)

The first talk explained how several features in GlassFish 3.1 such as:

  • Deploy-on-Save (in NetBeans and Eclipse)
  • Active Redeploy (preserve sessions across re-deploys at CLI or NetBeans and Eclipse)
  • 29% better startup/deploy/redeploy cycle
  • Application runner (java -jar glassfish.jar foo.war)
  • Maven integration (mvn gf:run, gf:start, gf:deploy, etc)
  • Embedded GlassFish

and many other features make GlassFish an extremely productive development environment for your Java EE 6 applications. And then features like:

  • High Availability, Clustering
  • Centralized Administration
  • Application-scoped Resources
  • Application Versioning
  • 33% better High Availability performance
  • Better scalability - upto 100 instances per domain
  • RESTful monitoring and management

make it an equally compelling deployment platform. The slides with all the details are available below:

Where are you deploying your Java EE 6 applications ?

The second talk explained the why/how of OSGi-enabled Java EE applicatins. The slides are available below:

The first few slides are OSGi introductory so jump ahead to slide #22 for all the interesting stuff. The screencast #38 showcase how to build an OSGi-enabled Java EE Applications using Eclipse and GlassFish and comes with the complete and detailed instructions. The screencast #32 shows the same using NetBeans.

The day ended with a 1.5 hrs interactive Java EE 6 hackathon and more details on that in a later blog.

Here are some pictures captured from the London visit:

And the complete album is available:

Technorati: conf jaxlondon javaee6 osgi glassfish cdi gae google ejb openejb liferay

Tuesday Oct 19, 2010

TOTD #146: Understanding the EJB 3.1 Timer service in Java EE 6 - Programmatic, Deployment Descriptor, @Schedule

EJB 3.1 has greatly simplified the ability to schedule events according to a calendar-based schedule, at a specified time, after a specified elapsed duration, or at a specific recurring intervals.

There are multiple ways events can be scheduled:

  • Programmatically using Timer service
  • Automatic timers based upon the metadata specified using @Schedule
  • Deployment Descriptor

This Tip Of The Day (TOTD) will show code samples on how timer-based events can be created in EJBs.

Lets start with programmatic creation of timers first.

The Timer Service allows for programmatic creation and cancellation of timers. Programmatic timers can be created using createXXX methods on "TimerService". The method to be invoked at the scheduled time can be any of the flavors mentioned below:

  1. EJB implementing "javax.ejb.TimedObject" interface that has a single method "public void ejbTimeout(Timer timer)". For example:
    @Singleton
    @Startup
    public class DummyTimer2 implements TimedObject {
     
     @Resource TimerService timerService;
     
     @PostConstruct
     public void initTimer() {
       if (timerService.getTimers() != null) {
         for (Timer timer : timerService.getTimers()) {
           if (timer.getInfo().equals("dummyTimer2.1") ||
               timer.getInfo().equals("dummyTimer2.2")) 
             timer.cancel();
           }
       }
     
       timerService.createCalendarTimer(
           new ScheduleExpression().
               hour("\*").
               minute("\*").
               second("\*/10"), new TimerConfig("dummyTimer2.1", true));
       timerService.createCalendarTimer(
           new ScheduleExpression().
               hour("\*").
               minute("\*").
               second("\*/45"), new TimerConfig("dummyTimer2.2", true));
     }
    
     @Override
     public void ejbTimeout(Timer timer) {
       System.out.println(getClass().getName() + ": " + new Date());
     }
    }
    
    

    The "initTimer" method is a lifecycle callback method and cleans up any previously created timers and then create new timers that triggers every 10th and 45th second. The "ejbTimeout" method, implemented from "TimedObject" interface is invoked everytime the timeout occurs. The "timer" parameter in the "ejbTimeout" method can be used to cancel the timer, get information on when the next timeout will occur, get information about the timer and other relevant data.

    Notice, there is a @Startup class-level annotation which ensures that bean is eagerly loaded, lifecycle callback methods invoked and thus timers are created before the bean is ready.
  2. At most one method tagged with "@Timeout". Methods annotated with @Timeout must have one of the following signature:
    1. void <METHOD>()
    2. void <METHOD>(Timer timer)

    The second method signature gives you the ability to cancel the timer and obtain metatdata about the timer. These methods may be public, private, protected, or package level access. For example:
    @Singleton
    @Startup
    public class DummyTimer3 {
      @Resource TimerService timerService;
     
      @PostConstruct
      public void initTimer() {
        if (timerService.getTimers() != null) {
          for (Timer timer : timerService.getTimers()) {
            if (timer.getInfo().equals("dummyTimer3.1") ||
                timer.getInfo().equals("dummyTimer3.2")) 
              timer.cancel();
          }
        }
        timerService.createCalendarTimer(
          new ScheduleExpression().
              hour("\*").
              minute("\*").
              second("\*/10"), new TimerConfig("dummyTimer3.1", true));
        timerService.createCalendarTimer(
          new ScheduleExpression().
              hour("\*").
              minute("\*").
              second("\*/45"), new TimerConfig("dummyTimer3.2", true));
      }
      @Timeout
      public void timeout(Timer timer) {
        System.out.println(getClass().getName() + ": " + new Date());
      }
    }
    

    Here again, the "initTimer" method is used for cleaning / initializing timers. The "timeout" method is marked with "@Timeout" annotation is the target method that is invoked when the timer expires.

Read more details about Timer Service in the Java EE Tutorial.

Lets see how this similar functionality can be achieved using deployment descriptor (ejb-jar.xml). Basically a simple method in the POJO class given below:

public class DummyTimer4 {
  public void timeout(Timer timer) {
    System.out.println(getClass().getName() + ": " + new Date());
  }
}

can be converted into a timer method by adding the following "ejb-jar.xml" in WEB-INF directory of WAR file:

<?xml version="1.0" encoding="UTF-8"?>

<ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee"
  version = "3.1"
  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/ejb-jar_3_1.xsd">
  <enterprise-beans>
    <session>
      <ejb-name>DummyTimer4</ejb-name>
      <ejb-class>org.glassfish.samples.DummyTimer4</ejb-class>
      <session-type>Stateless</session-type>
      <timer>
        <schedule>
          <second>\*/10</second>
          <minute>\*</minute>
          <hour>\*</hour>
          <month>\*</month>
          <year>\*</year>
        </schedule>
        <timeout-method>
          <method-name>timeout</method-name>
          <method-params>
            <method-param>javax.ejb.Timer</method-param>
          </method-params>
       </timeout-method>
     </timer>
   </session>
 </enterprise-beans>
</ejb-jar>

Multiple <schedule>s can be added to create multiple timers.

But all this is too much. EJB 3.1 adds @Schedule annotation that automatically creates timers based upon the metadata specified on a method, such as:

@Singleton
public class DummyTimer {

  @Schedules({
    @Schedule(hour="\*", minute="\*", second="\*/10"),
    @Schedule(hour="\*", minute="\*", second="\*/45")
  })
  public void printTime() {
    System.out.println(getClass().getName() + ": " + new Date());
  }
}

EJB 3.1 container reads the @Schedule annotations and automatically create timers. Notice, there is no need for a @Startup annotation here as lifecycle callback methods are not required. Each re-deploy of application will automatically delete and re-create all the schedule-based timers ... really clean and simple! No messing around with deployment descriptors too :-)

Interval timers created using TimerService can be easily created by using "ScheduleExpression.start()" and "end()" methods. The single-action timer can be easily created by specifying fixed values for each field:

@Schedule(year="A", month="B", dayOfMonth="C", hour="D", minute="E", second="F")

Optionally, you can also pass a "Timer" object to the methods annotated with @Schedule such as:

@Schedules({
  @Schedule(hour="\*", minute="\*", second="\*/10", info="every tenth"),
  @Schedule(hour="\*", minute="\*", second="\*/45", info="every 45th")
})
public void printTime(Timer timer) {
  System.out.println(getClass().getName() + ": " +
      new Date() + ":" +
      timer.getInfo());
}

The "timer" object contains information about the timer that just expired. Note that "info" is passed to each @Schedule annotation and "timer.getInfo()" can be used in "printTime" method to find out which of the timers expired.

The complete source code used in this blog can be downloaded here.

Here are some other points to be noted:

  • Timers can be created in stateless session beans, singleton session beans, MDBs but not for stateful session beans. This functionality may be added to a future version of the specification.
  • Timers are persistent by default, need to made non-persistent programmatically (TimerConfig.setPersistent(false)) or automatically (by adding persistent=false on @Schedule)
  • Schedule-based timers may be optionally associated with a timezone.
  • The user code has no control over the timers created using @Schedule and thus cannot be canceled after creation.
  • Timers are not for real time as the container interleaves the calls to a timeout callback method with the calls to the business methods and the lifecycle callback methods of the bean. So the timed out method may not be invoked exactly at the time specified at timer creation.

This blog is derived from the whiteboard discussion with Linda as captured below and numerous emails with Marina for helping me understand the concepts.

Ah, the joys of sitting a few feet away from most of the Java EE 6 spec leads :-)

Here is one tweet that I saw recently on EJB timers ...

Never wrote a Timer faster in #java ...really like it #ejb3.1 #glassfish http://j.mp/d1owSM

I love the simplicity and power provided by @Schedule, how do you create timers in your enterprise applications ?

Technorati: totd javaee6 glassfish ejb timer deploymentdescriptor schedule annotations

Tuesday May 18, 2010

TOTD #137: Asynchronous EJB, a light-weight JMS solution - Feature-rich Java EE 6

One of the new features introduced in Enterprise Java Beans 3.1 (JSR 318)  is asynchronous invocation of a business method. This allows the control to return to the client before the container dispatches the instance to a bean. The asynchronous operations can return a "Future<V>" that allow the client to retrieve a result value, check for exceptions, or attempt to cancel any in-progress invocations.

The "@Asynchronous" annotation is used to mark a specific (method-level) or all (class-level) methods of the bean as asynchronous. Here is an example of a stateless session bean that is tagged as asynchronous at the class-level:

@Stateless
@Asynchronous
public class SimpleAsyncEJB {

    public Future<Integer> addNumbers(int n1, int n2) {
        Integer result;

        result = n1 + n2;
        try {
            // simulate JPA queries + reading file system
            Thread.currentThread().sleep(2000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

        return new AsyncResult(result);
    }
}

The method signature returns "Future<Integer>" and the return type is "AsyncResult(Integer)". The "AsyncResult" is a new class introduced in EJB 3.1 that wraps the result of an asynchronous method as a Future object. Under the covers, the value is retrieved and sent to the client. Adding any new methods to this class will automatically make them asynchronous as well.

The 2 second sleep simulates server side processing of the response which may involve querying the database or reading some information from the filesystem.

This EJB can be easily injected in a Servlet using the normal way:

@EJB SimpleAsyncEJB ejb;

This business method can be invoked in the "doGet" method of a Servlet as:

PrintWriter out = response.getWriter();
try {
    Future<Integer> future = ejb.addNumbers(10, 20);
    print(out, "Client is working ...");
    Thread.currentThread().sleep(1000);

    if (!future.isDone()) {
        print(out, "Response not ready yet ...");
    }

    print(out, "Client is working again ...");
    Thread.currentThread().sleep(1000);

    if (!future.isDone()) {
        print(out, "Response not ready yet ...");
    }

    print(out, "Client is still working ...");
    Thread.currentThread().sleep(1000);

    if (!future.isDone()) {
        print(out, "Response not ready yet ...");
    } else {
        print(out, "Response is now ready");
    }

    Integer result = future.get();

    print(out, "The result is: " + result);
} catch (InterruptedException ex) {
    ex.printStackTrace();
} catch (ExecutionException ex) {
    ex.printStackTrace();
} finally { 
    out.close();
}

The control is returned to the client right after the the EJB business method is invoked and does not wait for the business method execution to finish. The methods on "Future" API are used to query if the result is available. The "Thread.sleep()" for 1 second simulate that client can continue working and possibly check for results at a regular interval. The "print" is a convenience method that prints the string to "response.getWriter" and flushes the output so that it can be instantly displayed instead of getting buffered. Invoking this "doGet" shows the following output:

1274142978365: Client is working ...
1274142979365: Response not ready yet ...
1274142979365: Client is working again ...
1274142980366: Response not ready yet ...
1274142980366: Client is still working ...
1274142981366: Response is now ready
1274142981366: The result is: 30

The client transaction context does not and security context do propagate from the client to the asynchronous business method.

Up until now, any kind of asynchrony in the EJB required to use the Message Driven Beans which in turn required some JMS setup. Introduction of this feature allows you to easily incorporate asynchrony in your EJB applications.

Try this and other Java EE 6 features in GlassFish Server Open Source Edition 3 or Oracle GlassFish Server today!

The complete source code used in this blog can be downloaded here.

Technorati: totd javaee ejb asynchronous glassfish v3

Monday May 10, 2010

TOTD #134: Interceptors 1.1 in Java EE 6 - What and How ?

TOTD #129 explained Managed Beans 1.0, this Tip Of The Day (TOTD) attempts to explain the basics of Interceptors 1.1 - a "new" specification introduced in the Java EE 6.

The specification is not entirely new as the concept is borrowed from the EJB 3.0 specification and abstracted at a higher level so that it can be more generically applied to a broader set of specifications in the platform. Interceptors do what they say - they intercept on invocations and lifecycle events on an associated target class. Basically, interceptor is a class whose methods are invoked when business methods on the target class are invoked and/or lifecycle events such as methods that create/destroy the bean occur. Interceptors are typically used to implement cross-cutting concerns like logging, auditing, and profiling.

Contexts and Dependency Injection (CDI, aka JSR 299) uses the concept defined by Interceptors 1.1 and adds the notion of interceptors binding.

Let see some code to make it all clear.

Each interceptor require at least one interceptor binding to associate with the target class. An interceptor binding is defined as:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;

@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyInterceptorBinding {
}

And then the interceptor is defined as:

import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;

@Interceptor
@MyInterceptorBinding
public class MyInterceptor {

    @AroundInvoke
    public Object intercept(InvocationContext context) throws Exception {
        System.out.println("before interception");
        Object result = context.proceed();
        System.out.println("after interception");

        return result;
    }
}

The "@AroundInvoke" annotation (can be only one per interceptor) on a method in the interceptor class ensures that this method is invoked around the business method interception. This will be more clear after the program flow is explained later. Multiple interceptors can be chained and the flow/outcome may be diverted in any of them using "InvocationContext".

The associated target bean looks like:

. . .
import javax.interceptor.Interceptors;

@ManagedBean(value="mybean")
@Interceptors(MyInterceptor.class)
public class MyManagedBean {
    @PostConstruct
    public void setupResources() {
        // setup your resources
        System.out.println("Setting up resources ...");
    }

    . . .

}

The only missing part on the server-side is enabling bean discovery by adding an empty "beans.xml" as:

<?xml version="1.0" encoding="UTF-8"?>
<beans 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/beans_1_0.xsd">
</beans>

Notice, there is no need to explicitly mention <interceptors> in "beans.xml". Multiple interceptors on a bean can be easily defined as:

@ManagedBean(value="mybean")
@Interceptors({MyInterceptor.class, MyInterceptor2.class})
public class MyManagedBean {

Lets see how this bean and interceptor can be used. Create a Servlet as:

@WebServlet(name="TestServlet", urlPatterns={"/TestServlet"})
public class TestServlet extends HttpServlet {

Inject a bean as ...

@Inject
MyManagedBean bean;

and then invoke the bean's method in "doGet" or "doPost" methods of the servlet as:

String result = bean.sayHello("Duke");

Notice that @Inject is used to inject the managed bean and bean discovery is enabled by adding an empty "beans.xml". This ensures that CDI inject works as expected and all the interceptors are invoked as well. Another alternative is to inject the bean using @Resource but "beans.xml" need to be removed in order for the interceptors to be invoked. So inject your bean using @Inject + "beans.xml" or @Resource. The recommended approach is to use @Inject + "beans.xml" as CDI might be used in other parts of your applications as well.

If 2 interceptors, each with a separate interceptor binding, managed bean class, and the servlet is included in a web application then the directory structure will look like:

./META-INF
./META-INF/MANIFEST.MF
./WEB-INF
./WEB-INF/beans.xml
./WEB-INF/classes
./WEB-INF/classes/server
./WEB-INF/classes/server/MyInterceptor.class
./WEB-INF/classes/server/MyInterceptor2.class
./WEB-INF/classes/server/MyInterceptorBinding.class
./WEB-INF/classes/server/MyInterceptorBinding2.class
./WEB-INF/classes/server/MyManagedBean.class
./WEB-INF/classes/server/TestServlet.class

If there are "System.out.println"s inserted at relevant positions in the interceptor and the Servlet code, then the code flow looks like:

Before Intercept
Before Intercept2
sayHello
After Intercept2
After Intercept
processRequest

"Before XXX" messages are printed by a method from the interceptors, in the order of chaining, before "context.proceed" is invoked in all the interceptors. "sayHello" method is invoked from the "doGet" or "doPost" method in the Servlet. "After XXX" messages are printed from the interceptors after "context.proceed" method is invoked, this time in the reverse order of chain. And finally "processRequest" method is invoked again from the "doGet" or "doPost" method in the Servlet.

The complete source code for the sample explained above can be downloaded here.

Technorati: javaee glassfish v3 managedbeans interceptors cdi ejb servlet

Sunday Apr 18, 2010

TOTD #129: Managed Beans 1.0 in Java EE 6 - What and How ?

Two new specifications released as part of the Java EE 6 platform are Managed Beans 1.0 and Interceptors 1.1. This Tip Of The Day (TOTD) attempts to explain the basics of Managed Beans 1.0. A later blog will explain the what/how of Interceptors 1.1.

A short definition for a managed bean - its a POJO that is treated as managed component by the Java EE container.

There are several component specifications in the Java EE platform that annotates a POJO to achieve the desired functionality. For example, adding "@Stateful" annotation to a POJO makes it a stateful EJB. Similarly adding "@javax.faces.bean.ManagedBean" to a POJO makes it a JSF managed bean. Java EE 6 introduces a new specification - "Managed Beans 1.0" that provides a common foundation for the different kinds of component that exist in the Java EE platform. In addition, the specification also defines a small set of basic services:

  • Resource Injection
  • Lifecycle callbacks
  • Interceptors

The different component specifications can then add other characteristics to this managed bean. The specification even defines well known extension points to modify some aspects. For example CDI/JSR 299 relaxes the requirement to have a POJO with no-args constructor and allow constructor with more complex signatures. CDI also adds support for lifecycle scopes and events. Similarly EJB is a managed bean and adds support for transactions and other services.

A managed bean is created by adding "javax.annotation.ManagedBean" annotation as:

@javax.annotation.ManagedBean(value="mybean")
public class MyManagedBean {
  ...
}

The standard annotations "javax.annotation.PostConstruct" and "javax.annotation.PreDestroy" from the JSR 250 can be applied to any methods in the managed bean to perform any resource initialization or clean up by the managed bean. A bean with lifecycle callbacks can look like:

@ManagedBean(value="mybean")
public class MyManagedBean {
  @PostConstruct
  public void setupResources() {
    // setup your resources
    System.out.println("Setting up resources ...");
  }

  @PreDestroy
  public void cleanupResources() {
     // collect them back here
    System.out.println("Collecting them back ...");
  }

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

This bean can be injected in a Servlet or any other managed component in three different ways:

  1. Using @Resource annotation as:

    @Resource
    MyManagedBean bean;
  2. Using "@Inject" annotation as:

    @Inject
    MyManagedBean bean;
  3. Using the JNDI reference "java:app/ManagedBean/mybean" or "java:module/mybean" where "ManagedBean" is name of the deployed archive (WAR in this case), shown as:

    InitialContext ic = new InitialContext();
    MyManagedBean bean = (MyManagedBean)ic.lookup("java:module/mybean");


    Its important to provide a name to the managed bean, as there is no default name, for the JNDI reference to work. EJB and CDI specifications extend this rule and provide default naming rules.

Once the bean is injected then its business methods can be invoked directly.

As part of Java EE 6, all EJB and CDI beans are defined as managed beans and so:

@Stateless
public class FooBean {
    . . .
}

and

@Named
public class BarBean {
    . . .
}

are implicitly managed beans as well.

No other beans in the Java EE platform are currently implicitly defined as managed beans. However JAX-RS resources can also be defined as EJB and CDI beans in which case the JAX-RS resources will be implicit managed beans as well. A future version of different component specifications may discuss if it makes sense to align other Java EE POJO elements to align with Managed Beans specification.

Technorati: javaee glassfish v3 managedbeans cdi ejb servlet jndi

Tuesday Apr 13, 2010

TOTD #128: EJBContainer.createEJBContainer: Embedded EJB using GlassFish v3

This blog has been in my Drafts folder for quite some time now, needed some final tweaks, and finally pushing it out.

Chapter 22 of Enterprise JavaBeans 3.1 specification (released as part of Java EE 6) describes "Embeddable Usage" as:

Unlike traditional Java EE server-based execution, embeddable usage allows client code and its corresponding enterprise beans to run within the same JVM and class loader. This provides better support for testing, offline processing (e.g. batch), and the use of the EJB programming model in desktop applications.

Earlier blogs already described the steps in detail but I had to try this stuff myself :-) And moreover this Tip Of The Day (TOTD) shows, as always, complete detailed steps to get you going from scratch.

Lets see how such an embeddable EJB application can be easily created.

  1. Create a Maven project as:
    mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=org.glassfish.embedded.samples -DartifactId=ejb31
    
    
  2. Add the following fragments to "pom.xml" to ensure right set of JARs are pulled in:
    <repositories>
      <repository>
      <id>download.java.net</id>
      <name>Java.net Maven Repository</name>
      <url>http://download.java.net/maven/2</url>
      </repository>
    </repositories>
    . . .
    
    <dependency>
      <groupId>org.glassfish.extras</groupId>
      <artifactId>glassfish-embedded-all</artifactId>
      <version>3.0</version>
      <scope>compile</scope>
    </dependency>
    . . .
    
    <build>
      <defaultGoal>install</defaultGoal>
      <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. Change the generated "src/main/java/org/glassfish/embedded/samples/App.java" to:
    package org.glassfish.embedded.samples;
    
    import javax.ejb.Stateless;
    
    /\*\*
     \* Hello world!
     \*/
    @Stateless
    public class App {
        public static String sayHello(String name) {
            return "Hello " + name;
        }
    }
    

    This creates our trivial Enterprise JavaBean.
  4. Change the generated "src/test/java/org/glassfish/embedded/samples/AppTest.java" to (taking the code snippet from Adam's blog and slightly altering it):
    public void testEJB() throws NamingException {
            EJBContainer ejbC = EJBContainer.createEJBContainer();
    
            Context ctx = ejbC.getContext();
    
            App app = (App) ctx.lookup("java:global/classes/App");
    
            assertNotNull(app);
    
            String NAME = "Duke";
    
            String greeting = app.sayHello(NAME);
    
            assertNotNull(greeting);
    
            assertTrue(greeting.equals("Hello " + NAME));
    
            ejbC.close();
        }
    

    This is a simple test that looks up the bean using portable JNDI name, more explanation on JNDI name below.
  5. Run the tests by giving the following standard command in the Maven project:
    ~/samples/v3/embedded/ejb31 >mvn clean test
    [INFO] Scanning for projects...
    [INFO] ------------------------------------------------------------------------
    [INFO] Building ejb31
    [INFO]    task-segment: [clean, test]
    [INFO] ------------------------------------------------------------------------
    [INFO] [clean:clean {execution: default-clean}]
    [INFO] Deleting directory /Users/arungupta/samples/v3/embedded/ejb31/target
    
    . . .
    
    -------------------------------------------------------
     T E S T S
    -------------------------------------------------------
    Running org.glassfish.embedded.samples.AppTest
    Apr 9, 2010 3:48:16 PM org.glassfish.ejb.embedded.EJBContainerProviderImpl getValidFile
    SEVERE: ejb.embedded.location_not_exists
    Apr 9, 2010 3:48:19 PM com.sun.enterprise.v3.server.AppServerStartup run
    INFO: GlassFish v3 (74.2) startup time : Embedded(1180ms) startup services(1523ms) total(2703ms)
    Apr 9, 2010 3:48:20 PM com.sun.enterprise.transaction.JavaEETransactionManagerSimplified initDelegates
    INFO: Using com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate as the delegate
    Apr 9, 2010 3:48:21 PM org.glassfish.admin.mbeanserver.JMXStartupService$JMXConnectorsStarterThread run
    INFO: JMXStartupService: JMXConnector system is disabled, skipping.
    Apr 9, 2010 3:48:21 PM AppServerStartup run
    INFO: [Thread[GlassFish Kernel Main Thread,5,main]] started
    Apr 9, 2010 3:48:30 PM com.sun.enterprise.security.SecurityLifecycle INFO: security.secmgroff
    Apr 9, 2010 3:48:31 PM com.sun.enterprise.security.ssl.SSLUtils checkCertificateDates
    SEVERE: java_security.expired_certificate
    Apr 9, 2010 3:48:31 PM com.sun.enterprise.security.SecurityLifecycle onInitialization
    INFO: Security startup service called
    Apr 9, 2010 3:48:31 PM com.sun.enterprise.security.PolicyLoader loadPolicy
    INFO: policy.loading
    Apr 9, 2010 3:48:32 PM com.sun.enterprise.security.auth.realm.Realm doInstantiate
    INFO: Realm admin-realm of classtype com.sun.enterprise.security.auth.realm.file.FileRealm successfully created.
    Apr 9, 2010 3:48:32 PM com.sun.enterprise.security.auth.realm.Realm doInstantiate
    INFO: Realm file of classtype com.sun.enterprise.security.auth.realm.file.FileRealm successfully created.
    Apr 9, 2010 3:48:32 PM com.sun.enterprise.security.auth.realm.Realm doInstantiate
    INFO: Realm certificate of classtype com.sun.enterprise.security.auth.realm.certificate.CertificateRealm successfully created.
    Apr 9, 2010 3:48:32 PM com.sun.enterprise.security.SecurityLifecycle onInitialization
    INFO: Security service(s) started successfully....
    Apr 9, 2010 3:48:33 PM com.sun.ejb.containers.BaseContainer initializeHome
    INFO: Portable JNDI names for EJB App : [java:global/classes/App!org.glassfish.embedded.samples.App, java:global/classes/App]
    Apr 9, 2010 3:48:34 PM org.glassfish.admin.mbeanserver.JMXStartupService shutdown
    INFO: JMXStartupService and JMXConnectors have been shut down.
    Apr 9, 2010 3:48:34 PM com.sun.enterprise.v3.server.AppServerStartup stop
    INFO: Shutdown procedure finished
    Apr 9, 2010 3:48:34 PM AppServerStartup run
    INFO: [Thread[GlassFish Kernel Main Thread,5,main]] exiting
    Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 18.61 sec
    
    Results :
    
    Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
    
    
    
    The key log messages are highlighted in bold and are described:
    1.  "mvn clean test" builds the project and runs the test.
    2. The server started in under 3 seconds, 2703 ms to be precise.
    3. The portable JNDI name for the EJB is "java:global/classes/App" (convenience name for a bean with one view) and the fully-qualified notation is "java:global/classes/App!org.glassfish.embedded.samples.App". The convenience name is constructed in the "global" namespace + the unqualified name of the directory + bean name. The later is created by adding the fully-qualified name of the interface to the former.
    4. The server shuts down after the tests are run, shows that 2 tests (one default + one newly added) ran, and both passed.

So no explicit GlassFish downloading and/or configuring, just deployed a simple EJB, and ran the tests - everything within one VM.

A future blog will show how to add other Java EE functionality to this app.

Technorati: totd embedded ejb glassfish javaee v3

Friday Feb 05, 2010

TOTD #120: Deployment Descriptor-free Java EE 6 application using JSF 2.0 + EJB 3.1 + Servlets 3.0

Here is trivial Java EE 6 application that is keeping you away from any deployment descriptors. It uses Java Server Faces 2.0, Enterprise Java Beans 3.1, and Servlet 3.0. This application shows the following Java EE 6 features:

  1. No-interface view for EJB
  2. EJBs packaged in a WAR file
  3. Optional "faces-config.xml" for Java Server Faces
  4. FacesServlet registered using Servlet 3.0 programmatic registration APIs
  5. Java Server Faces navigation rules using convention-over-configuration
  6. Optional "web.xml" for Servlets 3.0

The WAR file structure is:

./index.jsp
./index.xhtml
./META-INF
./show.xhtml
./WEB-INF
./WEB-INF/classes
./WEB-INF/classes/org
./WEB-INF/classes/org/glassfish
./WEB-INF/classes/org/glassfish/samples
./WEB-INF/classes/org/glassfish/samples/SimpleBean.class
./WEB-INF/classes/org/glassfish/samples/SimpleEJB.class
./WEB-INF/classes/org/glassfish/samples/SimpleServlet.class

Look ma, no deployment descriptors!

So how do you create this application:

mvn archetype:create -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=org.glassfish.samples -DartifactId=simplewebapp

This application is purposely not generated as a web application (missing "-DarchetypeArtifactId=maven-archetype-webapp"). If you specify this property then it will generate "WEB-INF/web.xml" which we don't intend to use.

Change "pom.xml" to:

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.glassfish.samples</groupId>
   <artifactId>simplewebapp</artifactId>
   <packaging>war</packaging>
   <version>1.0-SNAPSHOT</version>
   <name>simplewebapp</name>
   <url>http://maven.apache.org</url>
   <repositories>
     <repository>
       <id>glassfish-repository</id>
       <name>Java.net Repository for Glassfish</name>
       <url>http://download.java.net/maven/glassfish</url>
     </repository>
   </repositories>
   <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>
       <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>
   <dependencies>
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <version>3.8.1</version>
       <scope>test</scope>
     </dependency>
    <dependency>
       <groupId>javax</groupId>
       <artifactId>javaee-api</artifactId>
       <version>6.0</version>
       <scope>provided</scope>
    </dependency>
   </dependencies>
</project>

In the above code:
  • "maven-compiler-plugin" needs to be specified as the default source level for Maven compile plugin is JDK 1.3. It's been over 9 years JDK 1.3 was released, not even listed on Java SE standard downloads page, EOLed many years ago. Vote/Comment for the issue MCOMPILER-80 if you'd like this bug to be fixed.
  • Adding "failOnMissingWebXml" ensures that Maven packages the WAR file even though no "web.xml" is present.
  • The complete list of Maven coordinates for GlassFish are available here.

Create the directory structure as:

./src/main
./src/main/java
./src/main/java/org
./src/main/java/org/glassfish
./src/main/java/org/glassfish/samples
./src/main/java/org/glassfish/samples/SimpleBean.java
./src/main/java/org/glassfish/samples/SimpleEJB.java
./src/main/java/org/glassfish/samples/SimpleServlet.java
./src/main/webapp
./src/main/webapp/index.jsp
./src/main/webapp/index.xhtml
./src/main/webapp/show.xhtml

Once again, there are no deployment descriptors, just plain Java files and XHTML/JSP pages.

Here are the different source files with explanation after each one of them:

SimpleBean.java
package org.glassfish.samples;

import javax.faces.bean.ManagedBean;

@ManagedBean(name="simplebean")
public class SimpleBean {
    private String name;
    private int age;

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
}

This is currently a simple JSF managed bean. TOTD #109 explains how to convert a JSF managed bean to use CDI. A future blog will show how to convert this sample to use CDI.

SimpleEJB.java

package org.glassfish.samples;

import javax.ejb.Stateless;

@Stateless
public class SimpleEJB {
    public String sayHello(String name) {
        return "Hello " + name + "!!!";
    }
}

The session bean has no interface, just the @Stateless annotation.

SimpleServlet.java

package org.glassfish.samples;

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

/\*\*
 \* Hello world!
 \*/
@WebServlet(urlPatterns={"/SimpleServlet"})
public class SimpleServlet extends HttpServlet {
    @EJB SimpleEJB bean;

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        out.println("<h2>Serving at: " + request.getContextPath() + "</h2>");
        out.println("<h2>Invoking EJB: " + bean.sayHello("Duke") + "</h2>");
        out.println("</body></html>");
    }
}

The servlet injects the EJB in the application, display the servlet context and the result of invoking the business operation of the EJB.


index.jsp

<html>
<body>
<h2>Hello World!</h2>
Invoke the Servlet by clicking <a href="SimpleServlet">here</a>.
</body>
</html>

This is just a placeholder for invoking the servlet.

index.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtm
l1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:ui="http://java.sun.com/jsf/facelets"
 xmlns:h="http://java.sun.com/jsf/html">
 <h:head>
 <title>Enter Name &amp; Age</title>
 </h:head>
 <h:body>
 <h1>Enter Name &amp; Age</h1>
<h:form>
 <h:panelGrid columns="2">
 <h:outputText value="Name:"/>
 <h:inputText value="#{simplebean.name}" title="name" id="name" required="true"/>
 <h:outputText value="Age:"/>
 <h:inputText value="#{simplebean.age}" title="age" id="age" required="true"/>
 </h:panelGrid>
 <h:commandButton action="show" value="submit"/>
 </h:form>
 </h:body>
</html>


JSF 2 uses Facelets as viewing technology and so an ".xhtml" file is used for all the JSF tags. This page is intentionally kept simple and not using any templating, composition, or any other features of Facelets. This page renders an HTML form with two text boxes and a command button, binds the value of text box to the managed bean, and displays the page "show.xhtml" when the command button is clicked. The default JSF 2 navigation handler try to match a view on the disk ("show.xhtml" in this case) based upon the "action" attribute.

show.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtm
l1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:h="http://java.sun.com/jsf/html">
 <h:head>
 <title>Show Name &amp; Age</title>
 </h:head>
 <h:body>
 <h1>Show Name &amp; Age</h1>
<h:form action="show">
 <h:panelGrid columns="2">
 <h:outputText value="Name:"/>
 <h:outputText value="#{simplebean.name}" />
 <h:outputText value="Age:"/>
 <h:outputText value="#{simplebean.age}" />
 </h:panelGrid>
 </h:form>
 </h:body>
</html>

This page reads the bean properties (stored from previous page) and displays them on the page.

How do you build this entire application ?

mvn clean package

Lets deploy the application on a Java EE 6 compliant application server, GlassFish v3 (download here):

./bin/asadmin deploy --force=true ~/samples/javaee6/simplewebapp/target/simplewebapp-1.0-SNAPSHOT.war

And now your application is accessible at "http://localhost:8080/simplewebapp-1.0-SNAPSHOT/index.jsp" and looks like:

Clicking on "here" looks like:

The JSF page is accessible at "http://localhost:8080/simplewebapp-1.0-SNAPSHOT/index.jsf" and looks like (after entering the values):

Notice that even though the page is named "index.xhtml", it's accessed as "index.jsf". This is because the JSF specification provides recommended mapping for FacesServlet to "\*.faces" and "/faces/\*". In addition, Mojarra (Reference Implementation of JSF2 in GlassFish) also adds a mapping to "\*.jsf". Any views using these URL pattersn are routed through FacesServlet. So alternative URLs for our page are "http://localhost:8080/simplewebapp-1.0-SNAPSHOT/index.faces" and "http://localhost:8080/simplewebapp-1.0-SNAPSHOT/faces/index.xhtml".

Clicking on "Submit" shows the following page:



That's it!

Here are several other useful entries:

  • TOTD #109 : How to convert a JSF managed bean to JSR 299 bean (Web Beans) ?
  • TOTD #108 : Java EE 6 web application (JSF 2.0 + JPA 2.0 + EJB 3.1) using Oracle, NetBeans, and GlassFish
  • TOTD #102 : Java EE 6 (Servlet 3.0 and EJB 3.1) wizards in Eclipse
  • TOTD #99 : Creating a Java EE 6 application using MySQL, JPA 2.0 and Servlet 3.0 with GlassFish Tools Bundle for Eclipse
  • TOTD #98 : Create a Metro JAX-WS Web service using GlassFish Tools Bundle for Eclipse
  • 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 #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 : Getting Started with Java EE 6 using NetBeans 6.8 M1 & GlassFish v3 - A simple Servlet 3.0 + JPA 2.0 app

The next follow up blog will show "Hello World"s of Context & Dependency Injection, Bean Validation, Java API for Restful Web services, Java Persistence API, Interceptors, and other Java EE 6 specifications in this application.

Technorati: totd javaee glassfish v3 javaserverfaces servlet3 ejb maven

Thursday Oct 01, 2009

TOTD #108: Java EE 6 web application (JSF 2.0 + JPA 2.0 + EJB 3.1) using Oracle, NetBeans, and GlassFish

TOTD #106 explained how to install Oracle database 10g R2 on Mac OS X. TOTD #107 explained how to connect this Oracle database using NetBeans. This Tip Of The Day will explain how to use the sample HR database (that comes with Oracle database server) to write a simple Java EE 6 application.

This application will use Java Server Faces 2.0 for displaying the results, Enterprise Java Beans 3.1 + Java Persistence API 2.0 for middle tier, and Oracle database server + GlassFish v3 as the backend. The latest promoted build (65 of this writing) will not work because of the issue #9885 so this blog will use build 63 instead.

Several improvements have been made over NetBeans 6.8 M1 build and this blog is using the nightly build of 9/27. The environment used in this blog is:

  • NetBeans 9/27 nightly
  • GlassFish v3 build 63
  • Oracle database server 10.2.0.4.0 R2 on Mac OS X
  • Oracle JDBC Driver type 4 (ojdbc6.jar)

Lets get started!

  1. Configure GlassFish v3 with JDBC connection
    1. Download and unzip build 63.
    2. Download ojdbc6.jar and copy to "glassfishv3/glassfish/domains/domain1/lib/ext" directory.
    3. Start the Application Server as:
      ./bin/asadmin start-domain --verbose &
      
    4. Create a JDBC connection pool as:
      ./bin/asadmin create-jdbc-connection-pool --datasourceclassname oracle.jdbc.pool.OracleDataSource --restype javax.sql.DataSource --property "User=hr:Password=hr:URL=jdbc\\:oracle\\:thin\\:@localhost\\:1521\\:orcl" jdbc/hr
      

      and verify the connection pool as:
      ./bin/asadmin ping-connection-pool jdbc/hr
      
    5. Create a JDBC resource as:
      ./bin/asadmin create-jdbc-resource --connectionpoolid jdbc/hr jdbc/hr
      
  2. Configure GlassFish v3 build 63 in NetBeans
    1. In NetBeans IDE "Services" panel, right-click on "Servers" and click on "Add Server...". Choose "GlassFish v3" and provide a name as shown below:


    2. Click on "Next >" and specify the unzipped GlassFish location as:



      and click on "Finish".
  3. Create the Java EE 6 application
    1. In "Projects" pane, right-click and select "New Project...".
    2. Choose "Java Web" and "Web Application" and click on "Next". Choose the project name as "HelloOracle":



      and click on "Next >".
    3. Select the recently added GlassFish v3 server and choose "Java EE 6 Web" profile:



      and click on "Next >". Notice "Java EE 6 Web" profile is chosen as the Java EE version.
    4. Select "JavaServer Faces" on the frameworks page:



      and click on "Finish". Notice the JSF libraries bundled with the App Server are used.
  4. Create the Java Persistence Unit
    1. Right-click on the project, select "New", "Entity Classes from Database...":


    2. From the Data Source, select "jdbc/hr" as shown:



      This is the same JDBC resource created earlier. Select "EMPLOYEES" from the Available Table, click on "Add >" to see the output as:



      The related tables are automatically included. Click on "Next >".
    3. Click on "Create Persistence Unit ..." and take all the defaults and click on "Create".
    4. Specify the package name as "model":



      and click on "Finish". This generates a JPA-compliant POJO class that provide access to tables in the underlying Oracle database. The class name corresponding to each table is shown in the wizard.
  5. Create Enterprise Java Beans
    1. Right-click on the project and select "New Class...".
    2. Specify the class name as "EmployeesBean" and package as "controller", click on "Finish".
    3. Annotate the class to make it an Enterprise Java Bean and a JSF Managed Bean as:
      @javax.ejb.Stateless
      @javax.faces.bean.ManagedBean
      


      Notice, the EJB is bundled in the WAR file and no special type of modules are required. Java EE 6 provides simplified packaging of EJB which makes it really ease to use.

      Also this application is currently using JSF managed bean but will use JSR 299 (aka Web Beans) in a future blog.
    4. Inject the Persistence Unit by adding the following variable:
      @PersistenceUnit
      EntityManagerFactory emf;
      
    5. Add a new method to retrieve the list of all employees as:
      public List getEmployees() {
       return em.createNamedQuery("Employees.findAll").getResultList();
      }
      

      "Employees.findAll" is a default NamedQuery generated by NetBeans and makes it easy to query the database. Several other queries are generated for each mapped JPA class, such as "Employees.findByEmployeeId" and "Employees.findByFirstName". Custom queries can also be created and specified on the POJO class.

      The completed class looks like:
      @Stateless
      @ManagedBean
      public class EmployeesBean {
      
       public List getEmployees() {
       return emf.createEntityManager().createNamedQuery("Employees.findAll").getResultList();
       }
      }
      
  6. Use EJB in the generated JSF page
    1. JSF 2 uses Facelets as the templating mechanism and NetBeans generate a simple "index.xhtml" file to start with. Expand "Web Pages" and open "index.xhtml".
    2. Replace the body template with:
      <h1>First Java EE 6 app using Oracle database</>
      <h:dataTable var="emp" value="#{employeesBean.employees}" border="1">
       <h:column><h:outputText value="#{emp.lastName}"/>, <h:outputText value="#{emp.firstName}"/></h:column>
       <h:column><h:outputText value="#{emp.email}"/></h:column>
       <h:column><h:outputText value="#{emp.hireDate}"/></h:column>
       </h:dataTable>
      

      It uses JSF value expressions to bind the Enterprise Java Bean and dumps the HTML formatted name, email, and hire date of each employee in the database.
  7. Run the project: Right-click on the project and select "Run" to see the output at "http://localhost:8080/HelloOracle/" as:

So we can easily create a Java EE 6 application using NetBeans, Oracle, and GlassFish.

A complete archive of all the TOTDs is available here.

This and other similar applications will be demonstrated at the upcoming Oracle Open World.

Technorati: totd oracle database glassfish v3 javaee javaserverfaces ejb jpa netbeans oow

Sunday Sep 13, 2009

TOTD #102: Java EE 6 (Servlet 3.0 and EJB 3.1) wizards in Eclipse

The Eclipse community's WTP release with Java EE 6 support has been delayed to Jun 2010. So how do you do Java EE 6 development in Eclipse until then ?

The GlassFish team is trying to bridge the gap by adding new Java EE 6 wizards that allows you to create Servlet 3.0- (JSR 315) and EJB 3.1- (JSR 318) compliant artifacts. So for the first time, in Eclipse, a Java EE 6 application can be created using the GlassFish plugin for Eclipse (ver 1.0.32)! GlassFish v3 is the Java EE 6 in making and so Eclipse and GlassFish v3 together provides you a good environment for your Java EE 6 development.

This Tip Of The Day (TOTD) explains how to use those wizards using Eclipse 3.4.2. If you have an earlier version of plugin already installed then update it as described in TOTD #66. Make sure to use ver 1.0.33 (recently released) if you are using Eclipse 3.5.x. If you have an earlier version of GlassFish plugin installed, then you may have to start Eclipse with "-clean" flag, basically as "eclipse -clean", after updating the plugin. This will allow the environment to detect the new plugins.

  1. Using Eclipse 3.4.2, install the latest GlassFish Eclipse plugin (ver 1.0.32 or higher) in "Eclipse IDE for Java EE developers" as explained in screencast #28. The correct version snapshot is shown below:



    Install latest GlassFish v3 promoted build (62 as of this writing):



    specify the location:



    and click on "Finish" to complete the install. Make sure to select "JVM 1.6.0" as the Java Runtime Environment as that is the minimum requirement for GlassFish v3.
  2. Create a new "Dynamic Web Project" named "ee6".
  3. Add Servlet 3.0 using wizard
    1. Right-click on the project, select "New", "Other ...", expand the "GlassFish" section and select "Web Servlet (Java EE 6)" as shown below:



      and click on "Next >".
    2. Specify the package name as "server" and servlet name as "HelloServlet" as shown below:



      and click on "Finish".
    3. The generated code looks like as shown:



      Notice the usage of "javax.servlet.annotation.WebServlet" annotation to specify the servlet name and url pattern. Also note that no new entries are made in "WEB-INF/web.xml".
    4. Add a new method in the code as:
      protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws IOException {
              ServletOutputStream out = response.getOutputStream(); 
              out.print("<html><body>");
              out.print("Request received at: " + request.getContextPath());
              out.print("</body></html>");
        }
      


      and invoke this method from both doGet(...) and doPost(...).
    5. Right-click the project, select "Run As", "Run on Server" and select the recently added GlassFish server as shown below:



      and click on "Finish". This shows the default page "http://localhost:8080/index.jsp". Change the URL to "http://localhost:8080/ee6/HelloServlet" to see the output as:

    6. The "web.xml" and "sun-web.xml" can be conveniently deleted from "WebContent", "WEB-INF" and the deployed page will continue to function as expected because all the information is captured in annotations instead of the deployment descriptors.
  4. Add an EJB 3.1-compliant session bean
    1. Select "New", "Other ...", expand the "GlassFish" section and select "Session Bean (Java EE 6)" as shown below:



      The important difference to note is that using this new wizard an EJB can now be packaged in a Web project instead of creating a separate "EJB Project".
    2. Specify the package name as "server" and class name as "HelloBean" as shown below:



      The bean type can be chosen from "Stateless", "Stateful" or "Singleton" and appropriate annotations are added accordingly and click on "Finish".
    3. Add a simple method to the generated bean as:
      public String sayHello(String name) {
              return "Hello " + name;
      }
      
    4. Inject a client in the servlet as:
      @EJB HelloBean bean;
      

      and call the business method on EJB as:
      protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws IOException {
              ServletOutputStream out = response.getOutputStream();
              out.print("<html><body>");
              out.print("Request received at: " + request.getContextPath());
              out.print("<br>" + bean.sayHello("Duke"));
              out.print("</body></html>");
       }
      

      and see the response as:



      This new EJB wizard is different from the one that already exists in Eclipse in the following ways:
      1. Singleton session bean can be created
      2. Local interface is off by default
      3. Allows a session bean in a Web project
      4. Simplified wizard flow

So we built a Java EE 6 application using the newly added Servlet 3.0 and EJB 3.1 wizards in GlassFish Plugin for Eclipse.

Please send your feedback and questions to users@glassfishplugins.dev.java.net. Let us know what other Java EE 6 features you'd like to see in Eclipse.

A complete archive of all the tips is available here.

Technorati: totd glassfish v3 eclipse javaee servlet3 ejb

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