Hi,

Here we are going to see the usecase of EE6 specific javax.annotation.Resource annotation in JBoss AS7, The Resource annotation marks a resource that is needed by the application. This annotation may be applied to an application component class, or to fields or methods of the component class. When the annotation is applied to a field or method, the container will inject an instance of the requested resource into the application component when the component is initialized. If the annotation is applied to the component class, the annotation declares a resource that the application will look up at runtime.

More informations about this annotation can be found in the following link: http://download.oracle.com/javaee/6/api/javax/annotation/Resource.html#lookup() . Here we will discuss a very common issue related to the usecase of this annotation because most of the developers fall into Compilation issue while using this annotation inside their application code. As following:

build:
    [mkdir] Created dir: /home/userone/TestEE6FeatureApp/tmp/WEB-INF/classes
    [javac] Compiling 1 source file to /home/userone/TestEE6FeatureApp/tmp/WEB-INF/classes
    [javac] /home/userone/TestEE6FeatureApp/src/TestServlet.java:8: cannot find symbol
    [javac] symbol  : method lookup()
    [javac] location: @interface javax.annotation.Resource
    [javac]        @Resource(lookup="java:app/env/testing")
    [javac]                  ^
    [javac] 1 error

OR

TestServlet.java:8: cannot find symbol
symbol  : method lookup()
location: @interface javax.annotation.Resource
       @Resource(lookup="java:app/env/testing")

NOTE: the compile time issue occurs because the JDK API’s “javax.annotation.Resource” annotation does not contain any attribute with name “lookup”. So we need to make sure that you include the “jboss-annotations-api_1.1_spec-1.0.0.Final.jar” location in the “-endorseddirs” endorsed directory argument of the Java Comiler because the JDK APIs also contains the annotation “@javax.annotation.Resource”..but the JDK APIs do not have the “lookup” attribute in ther annotations.

Location of the JAR in JBoss AS7:
/home/userone/jboss-as-7.0.1.Final/modules/javax/annotation/api/main/jboss-annotations-api_1.1_spec-1.0.0.Final.jar

Example of Compilation:
javac -endorseddirs /home/userone/boss-as-7.0.1.Final/modules/javax/annotation/api/main -d . TestServlet.java

Here we will see how to compile and test the same application using ANT script in JBoss AS7.
Step1). Create a directory somewhere in your file system like “/home/userone/TestEE6FeatureApp”

Step2). Now create a directory with name “src” inside the “/home/userone/TestEE6FeatureApp” and then place the following kind of “web.xml” file inside the “src” folder.

<?xml version="1.0"?>
<web-app version="2.5"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
   <servlet>
       <servlet-name>TestServlet</servlet-name>
       <servlet-class>servlets.TestServlet</servlet-class>
   </servlet>
   <servlet-mapping>
       <servlet-name>TestServlet</servlet-name>
       <url-pattern>/TestServlet</url-pattern>
   </servlet-mapping>

   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>

   <env-entry>
      <description>Application Log Directory and fileName</description>
      <env-entry-name>java:app/env/testing</env-entry-name>
      <env-entry-type>java.lang.String</env-entry-type>
      <env-entry-value>/home/userone/TestApp/app.log</env-entry-value>
   </env-entry>
</web-app>

Step3). Now write a Servlet where we will try to lookup the mentioned in the above web.xml file. So we will create a Servlet with name “TestServlet.java” inside “/home/userone/TestEE6FeatureApp/src” directory as following:

package servlets;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import javax.annotation.Resource;
public class TestServlet extends HttpServlet
  {
       @Resource(lookup="java:app/env/testing")
       private String logFile;
       public void service(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException
        {
            PrintWriter out=response.getWriter();
            out.println("@javax.annotation.Resource(lookup="java:app/env/testing") ");
            out.println("private String logFile;");
            out.println("Got the logFile = "+logFile);
        }
  }

/*
How to compile above program ?
Make sure that you include the "jboss-annotations-api_1.1_spec-1.0.0.Final.jar" location in the "-endorseddirs" endorsed directory argument of the Java Comiler because the JDK APIs also contains the annotation "@javax.annotation.Resource"..but the JDK APIs do not have the "lookup" attribute in ther annotations.

Location of the JAR:
/home/userone/jboss-as-7.0.1.Final/modules/javax/annotation/api/main/jboss-annotations-api_1.1_spec-1.0.0.Final.jar

Example:
javac -endorseddirs /home/userone/boss-as-7.0.1.Final/modules/javax/annotation/api/main -d . TestServlet.java
*/

Step4). Now we will simply write a Simle JSP “index.jsp” to invoke this Servlet. Place the following JSP file inside “/home/userone/TestEE6FeatureApp/src”

<html>
<body>
<center><h1> Welcome Page </h1>
<h3><font color=maroon><a href="TestServlet">Click Here to Access TestServlet</a>
To check following code is working or not</font></h3>
</center>

<BR>
@javax.annotation.Resource(lookup="java:app/env/testing");
<BR>
private String logFile;
</body>
</html>

Step5). Now we will write a Simple ANT Build script “build.xml” file to build the WAR file and then to deploy the application on JBoss AS7. place the following “build.xml” file inside “/home/userone/TestEE6FeatureApp”

<project name="SingletonStartupService" default="deploy">
<property name="jboss.home" value="/home/userone/boss-as-7.0.1.Final" />
<property name="jboss.module.dir" value="${jboss.home}/modules" />
<property name="basedir" value="." />
<property name="tmp.dir" value="tmp" />
<property name="output.dir" value="build" />
<property name="src.dir" value="src" />
<property name="war.name" value="TestEE6Feature.war" />

   <path id="jboss.classpath">
     <fileset dir="${jboss.module.dir}">
        <include name="**/*.jar"/>
     </fileset>
   </path>

        <target name="init">
           <delete dir="${output.dir}" />
           <mkdir dir="${output.dir}" />
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}" />
        </target>

        <target name="build" depends="init">
           <mkdir dir="${tmp.dir}/WEB-INF/classes"/>
           <javac srcdir="${src.dir}" destdir="${tmp.dir}/WEB-INF/classes"  includes="*.java" classpathref="jboss.classpath">
                <compilerarg value="-Djava.endorsed.dirs=${jboss.module.dir}/javax/annotation/api/main"/>
               <!--
                NOTE:
                   Make sure that you include the "jboss-annotations-api_1.1_spec-1.0.0.Final.jar" location in the
                   "-endorseddirs" endorsed directory argument of the Java Comiler because the JDK APIs also contains
                   the annotation "@javax.annotation.Resource"..but the JDK APIs do not have the "lookup" attribute in ther annotations.

                   Location of the JAR:
                   jboss-as-7.0.1.Final/modules/javax/annotation/api/main/jboss-annotations-api_1.1_spec-1.0.0.Final.jar

                   Example:
                   javac -endorseddirs /home/userone/boss-as-7.0.1.Final/modules/javax/annotation/api/main -d . TestServlet.java
               -->
           </javac>

           <copy todir="${tmp.dir}/WEB-INF">
                <fileset dir="${src.dir}/">
                  <include name="web.xml"/>
                </fileset>
           </copy>
          <copy file="${src.dir}/index.jsp" tofile="${tmp.dir}/index.jsp"/>
          <copy file="${src.dir}/TestServlet.java" tofile="${tmp.dir}/WEB-INF/classes/TestServlet.java"/>
           <copy todir="${tmp.dir}/WEB-INF">
                <fileset dir="${src.dir}/">
                  <include name="web.xml"/>
                </fileset>
           </copy>
           <jar jarfile="${tmp.dir}/${war.name}" basedir="${tmp.dir}" compress="true" />
           <copy file="${tmp.dir}/${war.name}" tofile="${output.dir}/${war.name}"/>
           <delete includeEmptyDirs="true">
              <fileset dir="${tmp.dir}"/>
           </delete>
        </target>

        <target name="deploy" depends="build">
            <echo message="*******************  Deploying the WAR file ${war.name} *********************" />
            <echo message="********** ${output.dir}/${war.name} to ${jboss.home}/standalone/deployments **********" />
            <copy todir="${jboss.home}/standalone/deployments/">
                <fileset dir="${output.dir}/">
                  <include name="${war.name}"/>
                </fileset>
            </copy>
            <echo message="*******************  Deployed Successfully   *********************" />
        </target>
</project>

NOTICE: In the above ANT script we have set the Compiler argument with the endorsed directory PATH as <compilerarg value=”-Djava.endorsed.dirs=${jboss.module.dir}/javax/annotation/api/main”/>

Step6). Now open a Shell prompt and then set the PATH pointing to the ANT bin directory and the JDK bin directory … like following and the just run the “ant” command:

For Unix Based OS:
export PATH=/home/userone/jdk1.6.0_21/bin:/home/userone/org.apache.ant_1.6.5/bin:$PATH

OR

For Windows Based OS:
set PATH=C:/jdk1.6.0_21/bin;C:/org.apache.ant_1.6.5/bin;%PATH%

[userone@localhost TestEE6Feature]$ ant
Buildfile: build.xml

init:
   [delete] Deleting directory /home/userone/TestEE6FeatureApp/build
    [mkdir] Created dir: /home/userone/TestEE6FeatureApp/build
    [mkdir] Created dir: /home/userone/TestEE6FeatureApp/tmp

build:
    [mkdir] Created dir: /home/userone/TestEE6FeatureApp/tmp/WEB-INF/classes
    [javac] Compiling 1 source file to /home/userone/TestEE6FeatureApp/tmp/WEB-INF/classes
     [copy] Copying 1 file to /home/userone/TestEE6FeatureApp/tmp/WEB-INF
     [copy] Copying 1 file to /home/userone/TestEE6FeatureApp/tmp
     [copy] Copying 1 file to /home/userone/TestEE6FeatureApp/tmp/WEB-INF/classes
      [jar] Building jar: /home/userone/TestEE6FeatureApp/tmp/TestEE6Feature.war
     [copy] Copying 1 file to /home/userone/TestEE6FeatureApp/build
   [delete] Deleting 5 files from /home/userone/TestEE6FeatureApp/tmp
   [delete] Deleted 4 directories from /home/userone/TestEE6FeatureApp/tmp

deploy:
     [echo] *******************  Deploying the WAR file TestEE6Feature.war *********************
     [echo] ********** build/TestEE6Feature.war to /home/userone/boss-as-7.0.1.Final/standalone/deployments **********
     [copy] Copying 1 file to /home/userone/boss-as-7.0.1.Final/standalone/deployments
     [echo] *******************  Deployed Successfully   *********************

BUILD SUCCESSFUL
Total time: 2 seconds

The only change you will need to make is to change the “jboss.home” value in the above ANT build.xml file to point to your own JBoss AS& directory.

Step7). Start the JBoss AS& like following from inside your “/home/userone/jboss-as-7.0.1.Final/bin” directory.

   ./standalone.sh --server-config standalone-preview.xml

.
.
Thanks
Middleware Magic Team

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.