Wednesday Jul 24, 2013

BeanManager: Obtain Contextual Reference to Beans (TOTD #215)


javax.enterprise.inject.spi.BeanManager allows to programmatically obtain contextual references to beans. Even though the primary purpose is to allow a portable extension to interact directly with the container, it can be used by any Java EE component as well.

There are three ways to obtain BeanManager:
  • @Inject BeanManager bm;
  • BeanManager bm = CDI.current().getBeanManager();
  • BeanManager bm = null;
    try {
        InitialContext context = new InitialContext();
        bm = (BeanManager)context.lookup("java:comp/BeanManager");
    } catch (NamingException | NullPointerException ex) {
        Logger.getLogger(TestServlet.class.getName()).log(Level.SEVERE, null, ex);
        ex.printStackTrace(out);
    }

The instance is with the scope @Dependent and qualifier @Default. It can be used to programmatically obtain the list of beans that are available for injection such as:

Set<Bean<?>> beans = bm.getBeans(Greeting.class);

BeanManager has lots of other useful methods to, for example to obtain a contextual reference, an injectable reference, and non-contextual instance. Go read the javadocs.

Check out the complete sample source code at:

https://github.com/arun-gupta/javaee7-samples/tree/master/cdi/beanmanager

How would you use BeanManager in your applications ?

Sunday Apr 24, 2011

TOTD #161: Java EE 6 CDI Qualifiers explained - @Default, @Any, @New, @Named

The CDI specification (JSR-299) defines "Qualifer" as a means to uniquely identify one of the multiple implementations of the bean type to be injected. The spec defines certain built-in qualifiers (@Default, @Any, @Named, @New) and new qualifiers can be easily defined as well. This Tip Of The Day (TOTD) discusses the in-built qualifiers and how they can be used.

The @Named qualifier makes a bean EL-injectable, that's it!

The @Default qualifier, appropriately called as "default qualifier", exists on all beans without an explicit qualifer, except @Named. Consider the following bean type and implementation:

public interface Greeting {
    public String greet(String name);
}


public class SimpleGreeting implements Greeting {
    public String greet(String name) {
        return "Hello " + name;
    }
}

So SimpleGreeting defined above is equivalent to:

@Default
public class SimpleGreeting implements Greeting {
    . . .
}

Similarly

@Named
public class SimpleGreeting implements Greeting {
    . . .
}

is equivalent to:

@Named
@Default
public class SimpleGreeting implements Greeting {
    . . .
}

The default qualifier works for the type injection as well. So

@Inject Greeting greeting;

and

@Inject @Default Greeting greeting;

are equivalent. However it is not recommended to use @Named as injection point qualifier, except in the case of integration with legacy code that uses string-based names to identify beans.

@Any is another in-built qualifier on all beans, including the ones with implicit or explicit @Default qualifier, except @New qualified beans (more on this later). So the SimpleGreeting implementation is equivalent to:

@Default @Any
public class SimpleGreeting implements Greeting {
    . . .
}

And can be injected as:

@Inject @Any Greeting greeting;

or even

@Inject @Any @Default Greeting greeting;

Now lets add a new implementation of the Greeting as:

public class FancyGreeting implements Greeting {
    public String greet(String name) {
        return "Nice to meet you, hello " + name;
    }
}

Now all of the following injections fail:

@Inject Greeting greeting;
@Inject @Default Greeting greeting;
@Inject @Any Greeting greeting;
@Inject @Default @Any Greeting greeting;

with the "ambiguous dependencies" error because both the implementations now have @Default and @Any qualifiers.

This can be resolved by adding a new qualifier called @Fancy to the FancyGreeting implementation as:

@Fancy
public class FancyGreeting implements Greeting {
    . . .
}

which is also equivalent to:

@Fancy @Any
public class FancyGreeting implements Greeting {
    . . .
}

Now all the following inject statements:

@Inject Greeting greeting;
@Inject @Default Greeting greeting;
@Inject @Any @Default Greeting greeting;

will inject the SimpleGreeting implementation. However

@Inject @Any Greeting greeting;

will throw an "ambiguous dependency" error because now there are two implementations with that qualifier. The right implementation can be picked by specifying the additional qualifier such as:

@Inject @Any @Default Greeting greeting;

will inject the SimpleGreeting implementation and

@Inject @Any @Fancy Greeting greeting;

will inject the FancyGreeting implementation. The following injection will work anyway:

@Inject @Fancy Greeting greeting;

Lastly

@Inject @Default @Fancy Greeting greeting;

will give an "unsatisfied dependency" error because any bean with an explicit qualifier, except @Named, does not have the @Default qualifier.

@Any may also be used to add qualifiers programmatically such as:

@Inject @Any Instance<Greeting> greeting;
greeting.select(new AnnotationLiteral<Fancy>(){}).get();

will return a Greeting implementation with @Fancy qualifier. Here the "javax.enterprise.inject.Instance" and "javax.enteprise.util.AnnotationLiteral" classes are defined by the CDI spec.

@Any may also be used to iterate over all Greeting implementations such as:

@Inject @Any Instance<Greeting> greeting;
for (Greeting g : greeting) {
    // do something with g
}

The @New qualifier allows to obtain a depdendent object of a specified class, independent of the declared scope. So if SimpleGreeting is defined as:

@RequestScoped
public class SimpleGreeting implements Greeting {
    . . .
}

and injected as:

@Inject Greeting greeting;

then a request-scoped Greeting implementation (SimpleGreeting in this case) is injected. However if it is injected as:

@Inject @New Greeting greeting;

then the injected SimpleGreeting is in the @Dependent scope and only has @New qualifier (neither @Default or @Any).

I tried all of this using GlassFish 3.1 and NetBeans 7.0 that provides complete development and fully-clustered deployment environment for your Java EE 6 applications. Where are you deploying your Java EE 6 apps ?

Technorati: totd cdi qualifier javaee6 glassfish

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

Saturday Dec 04, 2010

Rich Web Experience 2010 Trip Report

The Rich Web Experience 2010 concluded earlier this week in Fort Lauderdale. In a typical No Fluff Just Stuff fashion, it was truly a rich experience starting from the location (hotel, city, and weather), food, content, speakers, 90-minute sessions, schwag, and many other items. There were about 350 attendees with topics ranging from HTML5, CSS3, NodeJS, GWT, iPad / iPhone / Android development, Grails, Git, Hudson, and pretty much all over the landscape. I gave three sessions on:
  1. Java EE 6 = Less Code + More Power
  2. Java EE 6 Toolshow
  3. Using Contexts and Dependency Injection in the Java EE 6 Ecosystem
The first session explained the three themes of Java EE 6 (light-weight, extensibility, and ease-of-use), explained newly introduced and updated specifications in the platform, and finally the modular, hybrid OSGi/Java EE host, embeddable, extensible, and high-availability nature of GlassFish. The attendance was light but audience was interactive.

The second session was a no-slides session and used NetBeans and Eclipse to demonstrate the following Java EE 6 features:
  1. @WebServlet
  2. @Stateless, No-interface view, EJB 3.1 in a WAR
  3. Embeddable EJB (unit test)
  4. @Schedule
  5. @PersistenceUnit in @WebServlet, @PersistenceContext in @Stateless
  6. Facelets templating
  7. CDI stereotypes @Model, @Qualifier
  8. RESTful Web services from Entity classes
The code build during the talk can be downloaded here.

The third session on CDI was a revision of my JavaOne session with a lot more context and code samples added. The talk explained CDI key concepts like type-safe dependency injection, Qualifiers, Stereotypes, Producer/Disposer, Alternative, Interceptor, Decorators, Scopes, CDI tooling, and other topics.

The slides for both the sessions are now available:






On a personal front, I totally enjoyed coming from a 40 degrees weather in San Jose to 70 degrees in Ft Lauderdale and that too with hotel right on the beach. I had couple of great runs by the Atlantic Ocean and a good walk along the beach.



Thursday had 2 hours dedicated for beach activity but I had to leave to catch my flight to Washington DC :( The dinner, lunch, and breakfast as part of the conference was healthy with a good mix of salads + carbs + proteins. The lemon tea + honey allowed me to deliver three 90 minute sessions in one day. And lastly enjoyed catching up with Venkat, Matthew McCullough, Kohsuke, Ben Ellingson and many other friends.

Here are some pictures:



And the complete album:




Next stop as part of No Fluff Just Stuff will be UberConf, Jul 12-16, 2011, mark your dates!

Technorati: conf glassfish javaee6 netbeans eclipse cdi weld rwx2010 richwebexperience florida

Sunday Nov 21, 2010

TOTD #151: Transactional Interceptors using CDI - Extensible Java EE 6

One of the questions often asked in recently, and I've been wondering too, is how to enable transactions using CDI Interceptors. This Tip Of The Day (TOTD) will share some basic piece of code on how to author a CDI interceptor that enable transactions. TOTD #134 provide more details about interceptors. Weld documentation certainly provide good details about how all the pieces fit together.

Lets jump to the code straight away. Lets look at the transaction interceptor binding code:

package org.glassfish.samples;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;

@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface TxInterceptorBinding {
}

And the actual interceptor:

package org.glassfish.samples;

import javax.annotation.Resource;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
import javax.transaction.UserTransaction;

@TxInterceptorBinding @Interceptor
public class TxInterceptor {
    @Resource UserTransaction tx;
    
    @AroundInvoke
    public Object manageTransaction(InvocationContext context) throws Exception {
        tx.begin();
        System.out.println("Starting transaction");
        Object result = context.proceed();
        tx.commit();
        System.out.println("Committing transaction");
        
        return result;
    }
}

This interceptor is injecting a "UserTransaction" and sandwiching the business method invocation between start and end of trnasaction. This interceptor is not dealing with any rollback scenarios or exception handling and so will need to be modified for a real-life scenario.

"beans.xml" looks like:

<?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">
  <interceptors>
    <class>org.glassfish.samples.TxInterceptor</class>
  </interceptors>
</beans>

This basically enables the interceptor.

With all the plumbing code now ready, lets use this interceptor on our application code as:

package org.glassfish.samples;

@TxInterceptorBinding
public class ShoppingCart {
    public void checkOut() {
        System.out.println("Checking out");
    }
}

The important part is "@TxInterceptorBinding" as a class-level annotation. Now this ShoppingCart can be injected in any Java EE resource such as:

@Inject ShoppingCart shoppingCart;

such as in a Servlet. Now invoking the servlet shows the following sequence of code in the server log:

INFO: Starting transaction
INFO: Checking out
INFO: Committing transaction

That's it folks!

The code for this sample application can be downloaded from here. Just download and unzip the code, open the project in NetBeans (tried with 7.0 beta) and run it on GlassFish or any other Java EE 6-compliant container.

If you are using EJBs in a WAR, which is now allowed per Java EE 6, then you can certainly leverage all the annotation-driven transactions within your web application instead of maintaining your own interceptor-driven transactions. A similar approach can be used for security as well.

How are you dealing with transactions in your web application - using CDI-based interceptors or let the container manage it all for you ?

Technorati: totd cdi javaee6 glassfish interceptors transactions

Tuesday Oct 05, 2010

TOTD #145: CDI Events - a light-weight producer/consumer in Java EE 6

Contexts & Dependency Injection (JSR 299) defines a standards-based type-safe Dependency Injection mechanism in the Java EE 6 platform. The type-safety comes from the fact that no String-based identifiers are used to identify the dependencies and instead all the information is specified using the Java object model. The loose coupling is possible because the bean requesting injection need not be aware of the lifecycle, concrete implementation, threading model and similar details of the injected bean. The CDI runtime automatically figures out the right bean in the right scope and context and then injects it correctly for the requestor.

CDI Events take loose coupling to the next level by following the Observer pattern. Event producers raise events that are consumed by observers. The event object carries state from producer to consumer.

Code is king, so lets understand the above text with a simple sample. Consider the following POJO that captures the state showing how many pages have been printed:

public class PrintEvent {
    private int pages;

    public PrintEvent(int pages) {
        this.pages = pages;
    }

    public int getPages() {
        return pages;
    }
}

A producer of this event will look like:

@Inject Event printEvent;

public void print() {
    printEvent.fire(new PrintEvent(5));
}

Inject a "PrintEvent" using @Inject and "fire" the event with the payload and state. And the consumer of this event will look like:

public void onPrint(@Observes PrintEvent event) {
    System.out.println(event.getPages() + " pages printed");
}

Any method with "@Observes" and the observed event type as parameter will receive the event. In this case, this method will observe all the events. However the observer can specify qualifiers to narrow the set of event notifications received. So lets create a CDI qualifier as:

package com.example.events;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.inject.Qualifier;

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface ShortPrintJob {
}

and create two more similar qualifiers as "MediumPrintJob" and "LongPrintJob". The "producer" can then look like:

@Inject @ShortPrintJob Event shortPrint;
@Inject @MediumPrintJob Event mediumPrint;
@Inject @LongPrintJob Event longPrint;

public void print2() {
    shortPrint.fire(new PrintEvent(5));
    mediumPrint.fire(new PrintEvent(30));
    longPrint.fire(new PrintEvent(80));
}

The consumer can then look like:

public void onShortPrint(@Observes @ShortPrintJob PrintEvent event) {
    System.out.println(event.getPages() + " pages printed (short)");
}

public void onMediumPrint(@Observes @MediumPrintJob PrintEvent event) {
    System.out.println(event.getPages() + " pages printed (medium)");
}

public void onLongPrint(@Observes @LongPrintJob PrintEvent event) {
    System.out.println(event.getPages() + " pages printed (long)");
}

Notice how qualifiers are specified in each method to narrow the set of event notifications. This will print the output as:

INFO: 5 pages printed (short)
INFO: 30 pages printed (medium)
INFO: 80 pages printed (long)

In the above case, "producer" is "qualified" by annotating at the Event inject point. CDI also allows for the qualifiers to be dynamically specified. So

@Inject @ShortPrintJob Event shortPrint;
shortPrint.fire(new PrintEvent(5));

can be replaced with

@Inject Event printEvent;
printEvent.select(new AnnotationLiteral<ShortPrintJob>(){}).fire(new PrintEvent(10));

Now, if we kept our original method "onPrint" in the consumer as well then each fired event will be delivered to this common method and the "qualified" method.

CDI also defines "Transactional observer methods" that receive event notifications during the different phases of a transaction in which the event was fired. There are pre-defined phases IN_PROGRESS, BEFORE_COMPLETION, AFTER_COMPLETION, AFTER_FAILURE, and AFTER_SUCCESS that allows you to receive and track events and take actions, if any, based upon the result. One use case is to keep the cache updated after receiving events when products are added / deleted from the database. Another use case is to it push data to the front end after a long-running transaction is successful.

You can certainly try all of this in GlassFish and NetBeans provides extensive tooling around CDI and broader Java EE 6. Check out screencast #30 for the complete Java EE 6 tooling using NetBeans.

How are you using CDI events ?

Technorati: totd javaee6 cdi events producer consumer glassfish netbeans

Monday Aug 23, 2010

TOTD #144: CDI @Produces for container-managed @Resource

Contexts & Dependency Injection (CDI) in Java EE 6 provides type-safe dependency injection. The type-safety part comes from the fact that no String-based identifiers are used for dependency injection. Instead CDI runtime uses the typing information that is already available in the Java object model.

Java EE 5 already had resource injection available in terms of PersistenceContext, PersistenceUnit, Resource, and others. But they require String-based identifiers to identify the resource to be injected. For example:

  • @PersistenceUnit(unitName="SOME_NAME")
  • @Resource(name="JNDI_NAME")
  • @WebServiceRefs(lookup="JNDI_NAME_OF_WEB_SERVICE_REF")

The main proposition of CDI is type-safety. This Tip Of The Day explains how @Produces annotation provided by CDI can be used to centralize all these String-based resource injection and add a facade of type-safety on them. Specifically, it shows how type-safety can be achieved for @PersistenceUnit. A similar approach can be taken for other String-based resource injections as well.

  1. Create a Singleton-scoped bean or Application-scoped bean as:
    import javax.inject.Singleton;
    
    @Singleton
    public class ApplicationResources {
    
    }
    

    All the Java EE component environment references can be centralized in this bean.
  2. If the PersistenceUnit is currently initialized as:
    @PersistenceUnit(unitName="StatesPU") EntityManagerFactory statesEMF;
    

    in other Java EE components, such as Servlet, then it can be alternatively defined in the type-safe manner using the following steps:
    1. Define a new Qualifier as:
      import static java.lang.annotation.ElementType.TYPE;
      import static java.lang.annotation.ElementType.FIELD;
      import static java.lang.annotation.ElementType.PARAMETER;
      import static java.lang.annotation.ElementType.METHOD;
      import static java.lang.annotation.RetentionPolicy.RUNTIME;
      import java.lang.annotation.Retention;
      import java.lang.annotation.Target;
      import javax.inject.Qualifier;
      
      @Qualifier
      @Retention(RUNTIME)
      @Target({METHOD, FIELD, PARAMETER, TYPE})
      public @interface StatesDatabase {
      }
      
    2. Add the type-safe definition of "EntityManagerFactory" in "ApplicationResources" bean (defined above) as:
      @Produces @PersistenceUnit(unitName="StatesPU") @StatesDatabase EntityManagerFactory statesEMF;
      

    3. The "EntityManagerFactory" can now be injected in the Servlet in a type-safe manner as:
      @Inject @StatesDatabase EntityManagerFactory emf;
      

This procedure can be repeated for other String-based resources as well and thus centralize all of them at one place. And now your application becomes more type-safe! With this TOTD, you can use @Inject for injecting your container- and application-managed resources easily.

Read the latest documentation on Weld (Reference Implementation for CDI and included in GlassFish) for more details.

Technorati: totd cdi javaee6 glassfish weld produces typesafety

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

Thursday Feb 18, 2010

TOTD #124: Using CDI + JPA with JAX-RS and JAX-WS

This is a follow up blog to TOTD #120 and TOTD #123. These two blogs together have created a simple Java EE 6 application and showed the following features so far:

  • No-interface view for EJB
  • EJBs packaged in a WAR file
  • Optional "faces-config.xml" for Java Server Faces
  • FacesServlet registered using Servlet 3.0 programmatic registration APIs
  • Java Server Faces navigation rules using convention-over-configuration
  • Optional "web.xml" for Servlets 3.0
  • Add database access using Java Persistence API 2.0
  • Show type-safe Criteria API from JPA 2.0
  • Use Context & Dependency Injection for JSF managed beans
  • Add Ajax effects from Java Server Faces 2.0
  • Add Bean Validation to the JSF managed bean

GlassFish v3 is the Java EE 6 Reference Implementation and comes bundled with a complete SOAP Web services stack (Metro/JAX-WS) and a RESTful stack (JAX-RS/Jersey). This blog will update the previously created Maven project with:

  • A SOAP Web service using JAX-WS
  • A RESTful Web service using JAX-RS
  • Use Context & Dependency Injection with JAX-WS and JAX-RS
  • Query the database using JPA 2 based upon criteria from the Web service invocation

Lets get started!

  1. Use the Maven project from TOTD #123 and update the directory structure as follows:
    src
    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/ActorResource.java
    src/main/java/org/glassfish/samples/RESTApplication.java
    src/main/java/org/glassfish/samples/SakilaBean.java
    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/java/org/glassfish/samples/SOAPService.java
    src/main/resources
    src/main/webapp
    src/main/webapp/index.jsp
    src/main/webapp/index.xhtml
    src/main/webapp/sakila.xhtml
    src/main/webapp/show.xhtml
    src/main/webapp/WEB-INF
    src/main/webapp/WEB-INF/beans.xml
    src/main/webapp/WEB-INF/web.xml
    

    The changes are:
    • "ActorResource.java" is added for the RESTful representation of Actor table.
    • "SOAPSevice.java" is added to invoke the SOAP-based Web service.
    • "SakilaBean.java" is updated to query the database for an Actor identified by "id".
  2. The updated files are explained below.
    • A new method is added to SakilaBean.java as shown below:
       public Actor findActorById(int id) {
          EntityManager em = emf.createEntityManager();
      
          CriteriaBuilder cb = emf.getCriteriaBuilder();
          CriteriaQuery<Actor> criteria = cb.createQuery(Actor.class);
      
          // FROM clause
          Root<Actor> actor = criteria.from(Actor.class);
      
          // SELECT clause
          criteria.multiselect(actor.<Short>get("actorId"),
                               actor.<String>get("firstName"),
                               actor.<String>get("lastName"));
      
          // WHERE clause
           criteria.where(cb.equal(actor.<Short>get("actorId"), id));
      
          Query q = em.createQuery(criteria);
          ((org.eclipse.persistence.jpa.JpaQuery)q).getDatabaseQuery().dontMaintainCache();
      
          return (Actor)q.getResultList().get(0);
      }
      

      This method queries the database for an actor by his id and uses the typesafe Criteria API to achieve the purpose. The FROM, SELECT, and WHERE clause are highlighted in the code. A cast to EclipseLink specific class is required because of the bug #303205.
    • SOAPService.java
      package org.glassfish.samples;
      
      import javax.inject.Inject;
      import javax.jws.WebService;
      import sakila.Actor;
      
      @WebService
      public class SOAPService {
          @Inject SakilaBean bean;
      
          public String sayHello(int id) {
              Actor a = bean.findActorById(id);
              return "Hello " + a.getFirstName();
          }
      }
      

      The key points in the code are:
      • Standard JAX-WS annotations from "javax.jws.\*" package are used to represent the Web service.
      • The Web service has only one method "sayHello" that concatenates the string "Hello" with the first name of "Actor" identified by "id".
      • No deployment descriptor modifications are required to publish this Web service.
      • "SakilaBean" is injected using @Inject annotation and used to query the database. This allows to encapsulate all the database details in one class and injected in a typesafe manner.
    • RESTApplication.java
      package org.glassfish.samples;
      
      import javax.ws.rs.ApplicationPath;
      import javax.ws.rs.core.Application;
      
      @ApplicationPath("/sakila")
      public class RESTApplication extends Application {
      }
      

      This is a marker class to inform Jersey of the root resource to be registered. By default, all classes with @Path and @Provider annotations are included. It also specifies the base path at which all resources are accessible.

      An alternative to this class is to specify the required information in "web.xml" as:
      <servlet>
           <servlet-name>Jersey Web Application</servlet-name>
           <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
       </servlet>
      
       <servlet-mapping>
           <servlet-name>Jersey Web Application</servlet-name>
           <url-pattern>/sakila/\*</url-pattern>
       </servlet-mapping>
      

      So only one of RESTApplication.java or changes in "web.xml" are required.
    • ActorResource.java
      package org.glassfish.samples;
      
      import javax.enterprise.context.RequestScoped;
      import javax.inject.Inject;
      import javax.ws.rs.GET;
      import javax.ws.rs.Path;
      import javax.ws.rs.Produces;
      import javax.ws.rs.PathParam;
      import sakila.Actor;
      
      @Path("/actor/{id}")
      @RequestScoped
      public class ActorResource {
          @Inject SakilaBean sakila;
      
          @GET
          @Produces("application/json")
          public Actor getActor(@PathParam("id") int id) {
              return sakila.findActorById(id);
          }
      }
      
      The key points in the code are:
      • Standard JAX-RS annotations from "javax.ws.rs" package are used to represent the RESTful resource.
      • "getActor" method is invoked when the resource is accessed using HTTP GET.
      • The resource is accessible at "/actor/{id}" URL where "{id}" is mapped to the "id" parameter of "getActor" method.
      • SakilaBean is injected in a typesafe manner using @Inject annotation. This bean is then used to query the database using the "id" parameter.
      • "getActor" method produces JSON representation, as defined by the "@Produces" annotation. This is easily achieved by updating our Persistence Unit (PU) created in TOTD #122 and adding "@javax.xml.bind.annotation.XmlRootElement" as the class level annotation on "sakila.Actor" class. Make sure to install the updated PU to your local Maven repository.

Package and deploy the application as:
mvn clean package
./bin/asadmin deploy --force=true ~/samples/javaee6/simplewebapp/target/simplewebapp-1.0-SNAPSHOT.war

Now the SOAP web service is accessible at "http://localhost:8080/simplwebapp-1.0-SNAPSHOT/SOAPServiceService" and looks like:


Notice, the URL in your case may be different if the Web service class name was different. The default URL is "http://<HOST>:<PORT>/<CONTEXT ROOT><WEB SERVICE CLASS NAME>Service".

This Web service can be easily tested by using the in-built tester accessible at "http://localhost:8080/simplwebapp-1.0-SNAPSHOT/SOAPServiceService?tester" and looks like:

The WSDL describing the Web service can be seen by clicking on the "WSDL File" link. The Web service method can be invoked by entering a value ("id" of the Actor) in the text box and clicking on "sayHello" button. Here is a sample run:

Clicking on "Submit" invokes the Web service which then uses the injected "SakilaBean" to query the database using the parameter specified. The first name from the response from the database is then extracted, concatenated with the string "Hello" and returned as Web service response.

The RESTful resource is accessible at "http://localhost:8080/simplwebapp-1.0-SNAPSHOT/sakila/actor/5" and looks like:

As in the SOAP-based Web service, the "5" in the URL is mapped to a parameter in the "ActorResource.java", the injected "SakilaBean" is then used to query the database and returns the JSON representation. Specifying a different number in the URL will show the RESTful JSON representation for that particular actor.

More Java EE 6 features will be covered in subsequent blogs. Are you interested in any particular ones ?

Technorati: jaxws metro webservices jaxrs rest jersey glassfish v3 cdi jsr299 weld

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