July 27, 2012

Java EE 6 Annotations - JSR 250: Common Annotations

In my previous blog I was writing about the CDI annotation in EE 6, in this blog I will write about the The Common Annotations, namely:

Resource Injection:
Lifecycle:
Managed Bean:

javax.annotation.Resource and javax.annotation.Resources

The @Resource and @Resources are shortcut for doing jndi lookup, e.g. new new InitialContext().lookup(name).

javax.annotation.PostConstruct and javax.annotation.PreDestroy

The @PostConstruct and @PreDestroy are neat annotation to do initialization and clean up in a standardized way. I would recommend to use these annotation even if you are not deploying to an enterprise environment. The above annotation can be used on any bean, such EJB, MDB, Managed Bean, but if you annotate a POJO, you need to fetch that POJO with @Inject to make the PostConstruct and PreDestroy be called.

javax.annotation.ManagedBean

This annotation should NOT be mixed up with javax.faces.bean.ManagedBean or JMX Managed Bean. It is a lightweight component that enables resource injection, lifecycle callbacks and interceptors. I my self is not totally sure where this component fits in, but it's there.

Java EE 6 Annotations - JSR 299: Contexts and Dependency Injection - Part 2

In my previous blog http://magnus-k-karlsson.blogspot.se/2012/07/java-ee-6-annotations-jsr-299-contexts.html I wrote about the new CDI annotation in EE 6 and now you would probably want to test them. You can of course package your archive and deploy it to your a EE container, but that is clumsy, tedious and harder to debug. What you rather want to is to write a JUnit test cases and with that be able to debug/run it from your IDE. There are several way to do that, but two major solution are:

In this blog I will show how to do that with JBoss Arquillian, but Apache OpenEJB is also a good solution.

There is a rather good getting started guide at http://arquillian.org/guides/getting_started/, which I encourage you to read and here I will give you a shorthand version, but also give some more clarification about the Arquillian Maven dependency.

First add JBoss Maven User repository, which is described here, https://community.jboss.org/wiki/MavenGettingStarted-Users.

Then create an empty maven project. Modify your pom.xml accordingly

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

 <modelVersion>4.0.0</modelVersion>
 <groupId>se.msc.examples</groupId>
 <artifactId>cdi-tutorial</artifactId>
 <version>1.0.0-SNAPSHOT</version>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.build.outputEncoding>UTF-8</project.build.outputEncoding>
 </properties>

 <dependencyManagement>
  <dependencies>
   <dependency>
    <groupId>org.jboss.arquillian</groupId>
    <artifactId>arquillian-bom</artifactId>
    <version>1.0.1.Final</version>
    <scope>import</scope>
    <type>pom</type>
   </dependency>
  </dependencies>
 </dependencyManagement>

 <dependencies>
  <dependency>
   <groupId>org.jboss.spec</groupId>
   <artifactId>jboss-javaee-6.0</artifactId>
   <version>1.0.0.Final</version>
   <type>pom</type>
   <scope>provided</scope>
  </dependency>

    <!-- Test Support -->
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.8.1</version>
   <scope>test</scope>
  </dependency>

    <!-- Arquillian JUnit Integration -->
  <dependency>
   <groupId>org.jboss.arquillian.junit</groupId>
   <artifactId>arquillian-junit-container</artifactId>
   <scope>test</scope>
  </dependency>

    <!-- Arquillian container adapter for the target container -->
  <dependency>
   <groupId>org.jboss.arquillian.container</groupId>
   <artifactId>arquillian-weld-ee-embedded-1.1</artifactId>
   <version>1.0.0.CR3</version>
   <scope>test</scope>
  </dependency>
  
  <!-- Target Container - Weld EE Container -->
  <dependency>
   <groupId>org.jboss.weld</groupId>
   <artifactId>weld-core</artifactId>
   <version>1.1.5.Final</version>
   <scope>test</scope>
  </dependency>
  
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-simple</artifactId>
   <version>1.6.4</version>
   <scope>test</scope>
  </dependency>
 </dependencies>

 <build>
  <finalName>cdi-tutorial</finalName>

  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
     <source>1.6</source>
     <target>1.6</target>
    </configuration>
   </plugin>

   <plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.12</version>
   </plugin>
  </plugins>
 </build>
</project>

There are two importing thing to stress here. First we need to understand one imported design goal with Arquillian and that is it was meant to be conainer neutral, i.e. the Arquillian test should not be affected if you decided to run your EE test on a different EE Container. And this design goal is reflected in the  Arquillian Maven dependency module.

So with that in mind, the first dependency arquillian-weld-ee-embedded-1.1 is only an adapter and does not contain any real CDI implementation code, which is in this case the Weld implementation code.

The second imported thing to understand is that Weld does not support EJB or any other similar EE modules, it only supports CDI.

If you want more container support look at the following pom, https://raw.github.com/arquillian/arquillian-examples/master/arquillian-tutorial/pom-no-container-profiles.xml.

Java EE 6 Annotations - JSR 299: Contexts and Dependency Injection - Part 1

Introduction

One of the maybe biggest new feature in EE 6 is the Dependency Injection, DI, support. Many of you are already familiar with the this concept after been using Spring, Guice or other DI framework. But now these feature are standardized in the EE 6 specification via the following Annotations:

Overview

Core DI package [http://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html]
"Annotations and interfaces relating to scopes and contexts." [http://docs.oracle.com/javaee/6/api/javax/enterprise/context/package-summary.html]
  • javax.enterprise.context.ApplicationScoped
  • javax.enterprise.context.SessionScoped
  • javax.enterprise.context.ConversationScoped
  • javax.enterprise.context.RequestScoped
  • javax.enterprise.context.Dependent
"Annotations relating to bean and stereotype definition, built-in qualifiers, and interfaces and classes relating to programmatic lookup." [http://docs.oracle.com/javaee/6/api/javax/enterprise/inject/package-summary.html]

javax.inject.Named

The @Named annotation is used for alternative lookup id. Example
@Named("cart") public class ShoppingCart { 
    public String getHello() { return "Hello"; }
}
And the JSF/JSP page:
<h:outputText value="#{cart.total}" />

javax.inject.Qualifier

The @Qualifier is used to qualify injection if there are multiple candidate in the classpath. Example a bean @Inject an interface but there are several implementation of that interface in the classpath.

javax.enterprise.context

You might think the above scooping Annotation are only used with JSF, but in fact these Annotation can be used on any Bean, for example try to annotate a POJO with @ApplicationScope and then grab it with the @Inject annotation in a Bean.

javax.enterprise.inject.Alternative

The @Alternative annotation is used for annotating a class to be ignored for @Inject lookup, and to enable must it be declared in META-INF/beans.xml. Example:
public interface IFoo {
    public String getHello();
}

public class FooImpl implements IFoo {
    @Override public String getHello() { return "Hello"; }
}

@javax.enterprise.inject.Alternative
public class FooAlternativeImpl implements IFoo {
    @Override public String getHello() { return "Alternative Hello"; }
}
META-INF/beans.xml
<?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">
    <alternatives>
        <class>se.msc.example.cdi.alternative.FooAlternativeImpl</class>
    </alternatives>
</beans>
And now can @Alternative be used with @Inject
public class IFooService {
    @Inject IFoo iFoo;
}

javax.enterprise.inject.New

The @New annotation creates a new inject instance of Object, good example is shown in EE API, http://docs.oracle.com/javaee/6/api/javax/enterprise/inject/New.html.

javax.enterprise.inject.Any

“The @Any qualifier allows an injection point to refer to all beans or all events of a certain bean type.” [http://docs.oracle.com/javaee/6/api/javax/enterprise/inject/Any.html]

javax.enterprise.inject.Produces

The @Produces annotation can be seen as a factory. Good example can be seen here http://code.google.com/p/jee6-cdi/wiki/DependencyInjectionAnIntroductoryTutorial_Part1#Using_simple_@Produces.

javax.enterprise.inject.Disposes

And the @Disposes is the cleanup method for factory @Produces.

Now I presume that you are eager to get started testing these and annotation and that I will describe in my next blog http://magnus-k-karlsson.blogspot.se/2012/07/java-ee-6-annotations-jsr-299-contexts_27.html.