Miles to go …

March 15, 2010

TOTD #124: OSGi Declarative Services in GlassFish – Accessed from a Java EE client

Filed under: glassfish, javaee — arungupta @ 6:54 am

The OSGi R4 compendium specification enables declaration of "Declarative Services" in configuration files. The specification says:

The service component model uses a declarative model for publishing, finding and binding to OSGi services. This model simplifies the task of authoring OSGi services by performing the work of registering the service and handling service dependencies.

There are several advantages of OSGi declarative services and they are well defined in the specification.

Neil Bartlett provided history and introduction to Declarative Services. Jerome blogged about OSGi Declarative Services in GlassFish v3 a while back. As mentioned in his post, this "curious reader" decided to experiment with adding more than one service implementation.

This Tip Of The Day shows how to use Maven Bundle Plugin and Maven SCR Plugin to create an OSGi bundle with two declarative services. Then it shows how to create a Java EE client, inject the declared services, and invoke them.

Lets get started!

For those who want want to see the results first:

  • Download service project and build as "mvn clean install"
  • Download client project and build as "mvn clean package"
  • Deploy the client to GlassFish v3 as "asadmin deploy target/helloclient-1.0-SNAPSHOT.war"
  • Invoke the client as "curl http://localhost:8080/helloclient-1.0-SNAPSHOT/HelloClient"

Now lets try to understand and create the projects from scratch.

First, create the service project as:

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

Lets first look at the completed project structure:

pom.xml
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/osgi
src/main/java/org/glassfish/samples/osgi/helloservice
src/main/java/org/glassfish/samples/osgi/helloservice/api
src/main/java/org/glassfish/samples/osgi/helloservice/api/HelloService.java
src/main/java/org/glassfish/samples/osgi/helloservice/impl
src/main/java/org/glassfish/samples/osgi/helloservice/impl/HelloImpl.java
src/main/java/org/glassfish/samples/osgi/helloservice/impl/HowdyImpl.java

The three source files are one service API and two implementations.

HelloService.java

package org.glassfish.samples.osgi.helloservice.api;

/**
 * @author arungupta
 */
public interface HelloService {
  public String sayHello(String name);
}

A very simple interface with one method that takes a String parameter and returns a String response.

HelloImpl.java

package org.glassfish.samples.osgi.helloservice.impl;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.glassfish.samples.osgi.helloservice.api.HelloService;

/**
 * @author arungupta
 */
@Component(name="hello-service")
@Service
public class HelloImpl implements HelloService {

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

This class is an implementation of the service interface. Notice this class is in "impl" package, different from the "api" package where interface was defined.

The business method implementation appends the greeting "Hello " to name parameter and generates the response message. The @Component and @Service annotations help in generation of the component descriptors as defined by the Maven SCR Plugin. This plugin provides many other annotations to customize the generation of metadata in "OSGI-INF/servicesComponent.xml". The "name" attribute will be used later by the Java EE client to access this service.

HowdyImpl.java

package org.glassfish.samples.osgi.helloservice.impl;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.glassfish.samples.osgi.helloservice.api.HelloService;

/**
 * @author arungupta
 */
@Component(name="howdy-service")
@Service
public class HowdyImpl implements HelloService {

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

Another implementation of HelloService interface and uses "Howdy " for the greeting. Notice the name attribute has a different value.

Here is the complete pom.xml:

<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.osgi.helloservice</groupId>
  <artifactId>helloservice</artifactId>
  <packaging>bundle</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>helloservice</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.felix</groupId>
      <artifactId>org.apache.felix.scr.annotations</artifactId>
      <version>1.2.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-bundle-plugin</artifactId>
        <version>2.0.1</version>
        <extensions>true</extensions>
        <configuration>
          <instructions>
            <Export-Package>${pom.groupId}.api</Export-Package>
            <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
          </instructions>
        </configuration>
      </plugin>
    <plugin>
      <groupId>org.apache.felix</groupId>
      <artifactId>maven-scr-plugin</artifactId>
      <executions>
        <execution>
          <id>generate-scr-scrdescriptor</id>
          <goals>
            <goal>scr</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
 </build>
</project>

Maven SCR Plugin generates the descriptor file using the metadata specified by the @Component and @Service annotation in service implementations. If this plugin is used with Maven Bundle Plugin then it also adds the generated descriptor (OSGI-INF/serviceComponents.xml) to the bundle and set the required "Service-Component" manifest header.

Giving "mvn clean install" generates "target/helloservice-1.0-SNAPSHOT.jar" and installs the bundle in the local repository. This JAR is used later in the client project for importing the service API definition. The generated JAR has the following manifest:

Manifest-Version: 1.0
Export-Package: org.glassfish.samples.osgi.helloservice.api
Service-Component: OSGI-INF/serviceComponents.xml
Built-By: arungupta
Tool: Bnd-0.0.357
Bundle-Name: helloservice
Created-By: Apache Maven Bundle Plugin
Build-Jdk: 1.6.0_17
Bundle-Version: 1.0.0.SNAPSHOT
Bnd-LastModified: 1268374529666
Bundle-ManifestVersion: 2
Import-Package: org.glassfish.samples.osgi.helloservice.api
Bundle-SymbolicName: helloservice

The key thing to notice is that only "api" package is exported. The generated component descriptor in "OSGI-INF/serviceComponents.xml" looks like:

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
  <scr:component enabled="true" name="hello-service">
    <implementation class="org.glassfish.samples.osgi.helloservice.impl.HelloImpl"/>
    <service servicefactory="false">
      <provide interface="org.glassfish.samples.osgi.helloservice.api.HelloService"/>
    </service>
    <property name="service.pid" value="hello-service"/>
  </scr:component>
  <scr:component enabled="true" name="howdy-service">
    <implementation class="org.glassfish.samples.osgi.helloservice.impl.HowdyImpl"/>
    <service servicefactory="false">
     <provide interface="org.glassfish.samples.osgi.helloservice.api.HelloService"/>
    </service>
    <property name="service.pid" value="howdy-service"/>
  </scr:component>
</components>

Notice that the "Service-Component" manifest header is pointing to this generated descriptor. And so the two declared services "hello-service" and "howdy-service" are available for consumption by other clients.

There are several ways to manage OSGi runtime bundle in GlassFish as described in TOTD #118. Simply copying the bundle to "glassfish/domains/domain1/autodeploy/bundles" is sufficient in this case, so lets do that.

The remote telnet shell (accessible using "telnet localhst 6666") shows status of the deployed bundle and associated service as:

-> find hello
START LEVEL 1
 ID State Level Name
[ 221] [Active ] [ 1] helloservice (1.0.0.SNAPSHOT)
-> scr list 221
 Id State Name
[ 2] [active ] hello-service
[ 3] [active ] howdy-service
-> scr info 2
ID: 2
Name: hello-service
Bundle: helloservice (221)
State: active
Default State: enabled
Activation: delayed
Services: org.glassfish.samples.osgi.helloservice.api.HelloService
Service Type: service
Properties:
 component.id = 2
 component.name = hello-service
 service.pid = hello-service
-> scr info 3
ID: 3
Name: howdy-service
Bundle: helloservice (221)
State: active
Default State: enabled
Activation: delayed
Services: org.glassfish.samples.osgi.helloservice.api.HelloService
Service Type: service
Properties:
 component.id = 3
 component.name = howdy-service
 service.pid = howdy-service

Maven SCR Plugin provides several other annotations to change the default value for each service.

Now create a Java EE client project to invoke the service as:

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

Lets look at the completed project structure:

pom.xml
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/osgi
src/main/java/org/glassfish/samples/osgi/HelloClient.java

There is only one source file which is the Servlet client and looks like:

package org.glassfish.samples.osgi;

import java.io.IOException;
import java.io.PrintWriter;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.glassfish.samples.osgi.helloservice.api.HelloService;

/**
 * Hello world!
 */
@WebServlet(urlPatterns={"/HelloClient"})
public class HelloClient extends HttpServlet {

  @Resource(mappedName="hello-service")
  HelloService helloService;

  @Resource(mappedName="howdy-service")
  HelloService howdyService;

  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException {
    PrintWriter out = response.getWriter();
    out.println(helloService.sayHello("Duke"));
    out.println(howdyService.sayHello("Duke"));
  }
}

This is a Java EE 6-style Servlet, using @WebServlet annotation, and will be accessible at "/HelloClient". The two OSGi services are injected using @Resource annotation and using the name specified in the "OSGI-INF/serviceComponents.xml" descriptor earlier.

pom.xml

<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.osgi</groupId>
  <artifactId>helloclient</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>helloclient</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish.samples.osgi.helloservice</groupId>
      <artifactId>helloservice</artifactId>
      <version>1.0-SNAPSHOT</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>6.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <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>
</project>

Note that the previously generated service bundle is added as a dependency in the "provided" scope as its already deployed to GlassFish.

"mvn clean package" generates "target/helloclient-1.0-SNAPSHOT.war" Deploy this WAR file to GlassFish as:

asadmin deploy target/helloclient-1.0-SNAPSHOT.war

And finally invoke the client as:

curl http://localhost:8080/helloclient-1.0-SNAPSHOT/HelloClient

to see the output as:

Hello Duke
Howdy Duke

This is the expected output after invoking the two services.

So there you go, this blog demonstrated how to access a OSGi declarative service from a Java EE client – both deployed on GlassFish v3.

Are you using OSGi Declarative Services ? How ?

Technorati: totd osgi glassfish javaee declarative service maven bundle bnd scr component dependencyinjection

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

March 11, 2010

DevNexus 2010 Trip Report

Filed under: eclipse, glassfish, javaee, netbeans — arungupta @ 9:20 pm
As mentioned earlier, I presented on Java E 6 & GlassFish v3 at DevNexus earlier this week. This is an annual conference by Atlanta Java Users Group and had three parallel tracks.

The conference was a sold out and the attendees packed Cobb Galleria conference rooms on both the days.

Anyway, the slides from my session are available below:

The speaking slots were bigger than normal, 70 minutes as opposed to normally 45 or 50 minutes. So that allowed to spend more time on the demos and show all the simplicity and ease-of-use with Java EE 6.  Optional "web.xml" is particularly well appreciated :-) And the attendees were hopeful that other vendors will start supporting Java EE 6 soon. For the record – Caucho, Geronimo, JBoss, and WebLogic have announced plans to be Java EE 6 compliant.

If you are interested in learning about Java EE (and several other topics), then GCA.net offers several of them all over the country. You can even avail a 10% on any class by registering at gca.net/devnexus. And if you are interested in specific learning paths on Java EE 6, then Oracle University has well designed courses.

Personally, I got to meet Dan Allen, Burr Sutter, James Ward, Venkat Subramaniam and many others. Burr is always an energetic personality and was live tweeting photographs of all the speakers. I loved his opening statement that DevNexus is about people who do what needs to be done, not who thinks what needs to be done. Basically he was joking on differences between "architects" and "developers" ;-) I also had some brief discussions with Dan on how Java EE adoption is important for the enterprise. His presentation on Contexts & Dependency Injection explained the concepts in simple manner. HIs slides should be soon available on Seam Wiki. Venkat’s keynote on Tuesday morning on "Facts and Fallacies of Software Development" was quite animated and simply superb. Here are some quotes from his talk:

  • A professional who doesn’t learn to fail, fails to learn
  • If a language is more typed, you type less (e.g. Scala). If a language is less typed, you type more (e.g. Java)
  • Standardization before innovation is a bad idea, that’s why EJB 1.0 suck so bad
  • It’s the lack of clear business objective, not lack of money & time that leads to failure
  • Passion, Competency, Responsibility – 3 things that can make your company succeed

I’m certainly looking forward to his keynote at Spark IT 2010 next week.

Finally some pictures from the conference:

And the complete album is available at:

Here is a brief number summary of the 2-week conference circuit starting next week:

  • 3 conferences
  • 8 sessions + 1 hands-on workshop
  • 2 cities
  • 6 days
  • 3 Hotels
  • 3 Airlines
  • Infinite meet/greet sessions

And then of course there is another one on Java EE 6 & GlassFish in Dallas on April 5, thank you GCA :-)

Technorati: conf glassfish v3 javaee atlanta devnexus ajug gca

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

March 3, 2010

Java EE 6 & GlassFish – Spark IT 2010, Ruby Conf India 2010, Tech Days 2010

Filed under: eclipse, glassfish, javaee, netbeans — arungupta @ 10:19 am

Java EE 6 & GlassFish are swimming across the globe to participate in three different conferences in March 2010.

Spark IT 2010 is an inaugural conference and a joint initiative of CIOL, India’s largest IT portal and PCQuest, India’s leading magazine for IT professionals. You’ll hear about:

  • Java EE 6 & GlassFish (12:05 – 12:50pm, Mar 18)
  • Improving engineering process through Hudson (3:30 – 4:15pm, Mar 18)
  • GlassFish Toolapalooza (2:40 – 3:25pm, Mar 19)
  • Rails on GlassFish workshop (Mar 19)

Check Spark IT 2010 website for the latest updates. See the Agenda, Speakers, Venue Layout, follow the updates on @sparkit2010 and register now!

Ruby Conf India 2010 is India’s first RubyConf and is presented by Ruby community in India (which seems to be growing) and supported by RubyCentral. There are lots of great speakers Matz, Chad, Obie, Nick, and Ola. And of course, you’ll hear about:

  • GlassFish supports multiple Ruby frameworks … really ? (2:00 – 2:45pm, Mar 21)

Check Ruby Conf 2010 website for the latest updates. See the Agenda, Venue (Royal Orchid Hotel), follow the updates on @rubyconfindia and register now!

Don’t miss out on Sambar/Dosa and Mavalli Tiffin Room while in Bangalore :-)

Tech Days 2010 at Hyderabad is biggest of all the Tech Days events. Other than Dum Biryani, Minarets, and Pearls, you’ll hear about Java EE 6 platform and toolshow, OSGi, and Java Persistence API 2. The Agenda (to be updated) has all the details and James Gosling is going to be there as well!

Check Tech Days 2010 website for the latest updates. The venue (Hyderabad International Convention Center) is indeed very impressive so don’t miss out and register now!

Check out reports from Tech Days 2009 (1, 2) and Tech Days 2008 (1, 2, 3, 4, 5, 6, 7).

Here is the current speaking schedule:

And as always, feel free to join me for a run :-)

Technorati: conf glassfish javaee bangalore hyderabad sparkit2010 rubyconfindia techdays hudson

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

February 27, 2010

Oracle at EclipseCon 2010 – Java EE 6, OSGi, GlassFish, EclipseLink, JPA 2.0/Dali, …

Filed under: eclipse, glassfish, javaee, running — arungupta @ 6:34 am
EclipseCon 2010 Oracle is a strategic developer & board member of the Eclipse Foundation and is a gold sponsor of Eclipse Con 2010. See the complete list of Eclipse projects at Oracle.

When ? Mar 22nd – 25th, 2010
Where ? Santa Clara, California
How to register ? Register Now – Use the coupon code ORACLE10 (before Mar 2) for 10% off registration.
What ? Program Schedule

Oracle certainly has a lot to talk about Java EE 6, OSGi/GlassFish, JPA 2.0 and Dali, Future of App Servers, Future of Enterprise Java, Eclipse RT and WTP Reloaded tutorials and many other sessions. See the complete details about Oracle’s participation here.

Also don’t miss the keynote by Steve Harris and Jeet Kaul on Community and Adaptation. Hear these two industry leaders and prolific speakers talk about how Java has empowered community, engendered new forms of adaptation and will continue to blaze the trails.

And then there is Members and Committers reception on Monday evening sponsored by Oracle. Visit us at booth #8 to speak with technical experts, see demos and get information about Oracle’s Eclipse technology and Project participation.

OSGi DevCon 2010 is happening on the same dates/venue and is covered with Eclipse Con registration.

And last, but not the least, let that runner in you have some fun and run with fellow attendees. Yep, there are even prizes!

Keep checking eclipsecon.org for the latest updates.

Unfortunately, I’ll be speaking elsewhere in a different part of the world during exact same dates and so will miss all the fun. More on that later but here are some key members of the Eclipse Foundation:

Feel free to greet and thank them for running the show :-)

Read about 2009 participation here.

Technorati: conf oracle glassfish javaee oepe eclipsecon santaclara

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

February 26, 2010

Oracle GlassFish Server 3 – New Datasheet available

Filed under: glassfish, javaee — arungupta @ 3:04 pm
Oracle announced a new datasheet for "Oracle GlassFish Server 3", yep no "v"!

Here are some key points from the datasheet:

BENEFITS

  • Light weight and flexibility, with fast startup of only those services required by deployed applications
  • Support available from Oracle’s world-class services organization
  • Easy-to-use administration console and command-line tool
  • Microsoft .NET interoperability
  • Compatibility with the Java EE 6 and Java EE 6 Web Profile, improving application portability and developer productivity
  • Tomcat developers’ ability to begin with the more capable Java EE 6 Web Profile and then grow to a more feature-rich, standardized platform as needed, using only the resources necessary

. . .

Oracle GlassFish Server is the world’s first implementation of the  Java Platform, Enterprise Edition (Java EE) 6 specification. Built with the open source GlassFish Project reference implementation, Oracle GlassFish Server is a flexible, lightweight, and extensible Java EE 6–compatible server. Completely supported for commercial  deployment and available standalone or packaged with other Oracle Fusion Middleware offerings, Oracle GlassFish Server delivers a small-footprint, fully featured Java EE application server.

. . .

Oracle GlassFish Server is part of the Oracle Fusion Middleware application grid portfolio and is ideally suited for applications requiring lightweight infrastructure with the most up-to-date implementation of enterprise Java, Java EE 6, and Java Web services. Oracle GlassFish Server complements Oracle WebLogic Server, which is designed to run the broader portfolio of Oracle Fusion Middleware and large-scale enterprise applications.

. . .

Please visit oracle.com/sun or call +1.800.786.0404 to speak to an Oracle representative.

Lot more details in the datasheet, download now! More details about Oracle GlassFish Server are on oracle.com. A Java EE 6 whitepaper is also available on oracle.com.

Additionally, you can watch the webcast on GlassFish Strategy by Oracle or attend a Oracle+Sun welcome event in a city near you.

Technorati: oracle glassfish javaee datasheet

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

February 24, 2010

Java EE 6 & GlassFish swimming to DevNexus/Atlanta – Mar 8/9 & Dallas – Apr 5

Filed under: glassfish, javaee — arungupta @ 6:08 am

Here is an opportunity to hear the latest & greatest about Java EE 6 & GlassFish in Atlanta and Dallas.

Where ? When ? Participate ?
Atlanta Mar 8/9, 2010 DevNexus
Dallas Apr 5, 2010 FREE Invite
The Atlanta event is happening at DevNexus, a developer conference organized by the Atlanta Java Users Group. The topics in this year’s conference range from Java EE 6, Spring 3.0, Grails, Google App Engine, Google Wave, Context & Dependency Injection, Hudson and many others.

See the complete list of speakers and schedule. Seats are limited and pre-registration is required, so register now! Follow @devnexus for more details.

The Dallas event is organized by Oracle University in association with GCA.net Technology Services and is dedicated to Java EE 6 & GlassFish.

Register today!

In both the events, you’ll learn how Java EE 6 provides a flexible technology stack, takes ease-of-development to a new level by following convention-over-configuration and using defaults, improves developer productivity by intuitive tooling, new/updated specifications in the platform and many other features.

The talk will be accompanied by numerous live code samples showing the benefits of Java EE 6 platform and GlassFish.

More details about both the events are available here.

Technorati: javaee glassfish atlanta dallas conf

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

February 19, 2010

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

Filed under: glassfish, javaee — arungupta @ 5:57 am

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

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

February 16, 2010

Latest features of Java Persistence 2.0 with MySQL – FREE webinar, Feb 23, 2010

Filed under: glassfish, javaee — arungupta @ 10:14 am

Want to learn the latest features of Java Persistence 2.0 (JSR 317) with MySQL ?

JPA 2 provides an object/relational mapping facility for the Java application developer using a Java domain model to manage a relational database. JPA got a major facelift as part of Java EE 6 specification and has been expanded to include several key new features – improved object/relational mapping and modeling additions, the query language facilities, the new criteria API, pessimistic locking, and support for validation.

Learn what these features mean in context of MySQL in an upcoming webinar on Feb 23, 2010.

Linda DeMichiel (specification lead of JPA2) and I will be talking about them and showing live code samples to get you started.

Register now!

Technorati: jpa mysql webinar glassfish netbeans

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

February 12, 2010

TOTD #123: f:ajax, Bean Validation for JSF, CDI for JSF and JPA 2.0 Criteria API – all in one Java EE 6 sample application

Filed under: glassfish, javaee — arungupta @ 9:22 am

Taking TOTD #120 forward, we’ll add the following features to our application:

  • 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

Lets get started!

  1. Use the Maven project created in TOTD #120 and update the directory such that it looks like:

    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/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/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 key differences are:

    1. "beans.xml" is an empty file to enable Context & Dependency Injection bean discovery.
    2. The JPA Persistence Unit is copied and installed in local Maven repository as explained in TOTD #122.
    3. "web.xml" is added to bootstrap the Java Server Faces runtime. This is required because "@ManagedBean" annotation on "SimpleBean" class is now changed to "@javax.inject.Named". The JSF runtime is automatically registered and booted if any bean in the webapp is annotated with "@ManagedBean" or one of the JSF common classes (such as Converter, Validator, or Renderer) is implemented or extended. If none of these "hints" are available in the application, and it’s required, then it needs to enabled explicitly.

Here are the updated files, changes are highlighted in bold and explained after each fragment:

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="3">
 <h:outputText value="Name:"/>
 <h:inputText value="#{simplebean.name}" title="name" id="name" required="true"/>
 <h:message for="name" style="color: red"/>
 <h:outputText value="Age:"/>
 <h:inputText value="#{simplebean.age}" title="age" id="age" required="true"/>
 <h:message for="age" style="color: red"/>
 </h:panelGrid>
 <h:commandButton action="show" value="submit"/>
 </h:form>
 </h:body>
</html>

Changed the panelGrid from "2" columns to "3". This allows for any validation messages to be displayed right next to the source. Also added "<h:message …/>" to display the validation messages.

SimpleBean.java

package org.glassfish.samples;

import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.validation.constraints.Min;

@Named("simplebean")
@RequestScoped
public class SimpleBean {
 @NotNull
 @Size(min=2, message="Name must be at least 2 characters")
 private String name;

 @NotNull
 @Min(5)
 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; }
}

The changes to the above code are listed below:

  • Replaced "@ManagedBean" with "@Named" annotation defined in JSR 330 and used by CDI.
  • Using constraints defined by Bean Validation APIs (JSR 303) to check for

    • Both bean properties to be non-null
    • Name to be at least 2 characters
    • A minimum age of 5
    • There are several other pre-defined constraints in "javax.validation.constraints" package and new constraints can be easily defined as well.

SakilaBean.java

package org.glassfish.samples;

import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.faces.event.ActionEvent;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceUnit;
import javax.persistence.EntityManagerFactory;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import sakila.Actor;

@Named("sakilabean")
@RequestScoped
public class SakilaBean {
 @PersistenceUnit(unitName="SakilaPU")
 EntityManagerFactory emf;

 private List<Actor> actors;
 private int length;
 private int totalActors;

 // getters & setters
 public List<Actor> getActors() { return actors; }
 public void setActors(List<Actor> actors) { this.actors = actors; }
 public int getLength() { return length; }
 public void setLength(int length) { this.length = length; }
 public int getTotalActors() { return totalActors; }
 public void setTotalActors(int totalActors) { this.totalActors = totalActors; }

 public void findActors(ActionEvent evt) {
   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.select(actor);

   // WHERE clause
   criteria.where(cb.greaterThan(
     cb.length(actor.get("firstName").as(String.class)), length));

   // FIRE
   actors = em.createQuery(criteria).getResultList();
   totalActors = actors.size();
 }
}

The key points:

  • This is a CDI bean marked by @Named and used in the JSF view (shown next), with the name "sakilabean"
  • EntityManagerFactory is injected using @PersistenceUnit
  • "findActors" method builds the query using Criteria API. Returns actors’ names limited by the number of characters in their first name.
  • Queries "Actor" table from the database and set bean properties "actors" and "totalActors".
  • Uses "length" bean property (set from the JSF view) to restrict the number of characters in the name.

sakila.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:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html">
  <h:head>
    <title>Sakila - Actors Listing</title>
  </h:head>
  <h:body>
    <h1>Sakila - Actors Listing</h1>
    <h:form>
    <h:outputText value="Show actors with first name's length &lt;"/>
    <h:inputText value="#{sakilabean.length}" id="length" required="true" size="5"/>
    <h:commandButton actionListener="#{sakilabean.findActors}" value="submit">
      <f:ajax execute="length" render="actorTable totalActors"/>
    </h:commandButton><br/>
     Total actors found: <h:outputText value="#{sakilabean.totalActors}" id="totalActors"/><p/>
     <h:dataTable var="actor" value="#{sakilabean.actors}" border="1" id="actorTable">
       <h:column><h:outputText value="#{actor.firstName}"/>, <h:outputText value="#{actor.lastName}"/></h:column>
     </h:dataTable>
   </h:form>
 </h:body>
</html>

Key points:

  • This JSF view shows a form that accepts a number used for restricting the length of actors’ first name. The value of this attribute is bound to "length" property of the underlying bean.
  • Command Button is tied to a JSF Action Listener which is then bound to "findActors" method in the bean. This method executes the JPA query explained above.
  • "f:ajax" is a newly introduced tag in JSF 2.0 and means an Ajax request is performed on the "onClick" event of the rendered button, "findActors" method in the bean in this case. The tag also specifies other tags in the page, "actorTable" and "totalActors" in this case, that needs to be rendered after the request is completed. The input parameter to the Ajax request is specified using "execute" attribute. Read more about this tag here or section 10.4.1.1 of the JSF 2 specification.

Package and deploy the application as:

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

The application is now accessible at "http://localhost:8080/simplewebapp-1.0-SNAPSHOT/sakila.jsf" and looks like:

Enter a value of "4" in the text box and hit "Submit":

Only the HTML table of names and the total count of actors is refreshed showcasing partial page refresh.

Now enter a value of "8" and hit "Submit":

Enjoy!

More Java EE 6 features to be shown in subsequent blogs.

Technorati: totd javaee glassfish v3 javaserverfaces ajax jpa cdi beanvalidation

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

February 10, 2010

Oracle+Sun Welcome Events

Filed under: glassfish — arungupta @ 11:30 am

Want to learn how Oracle+Sun are transforming the industry ? What the combination means to you ?

Hear from Oracle and Sun executives in multiple cities all around the world and learn the strategy.

Here is an email flier from my inbox showing some of the North America cities, more cities are being added every day.

Oracle+Sun Welcome Events

In the meanwhile, check out:

Technorati: oracle sun welcome

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot
Older Posts »

Powered by WordPress