Thursday Feb 07, 2013

Jfokus 2013 Trip Report - A Magnificent Spectacle


This was my third consecutive year (2012, 2011) at Jfokus and the organizing committee, and Mattias Karlsson in particular, continue to amaze me every year! As one of my colleague mentioned, it truly has become a "magnificent spectacle".

With the conference sold out 2 weeks before the official start, 1550 attendees from 20+ countries were delighted by a barrage of international speakers. This was the biggest Jfokus ever and the bar has always gone higher from the previous years.

The conference kickstarted with a guided tour of Old Town Stockholm and was a good way to get familiar with history of the city.






The conference had hands-on lab on the first day and technical sessions, BoFs, HackerGarten, NightHacking, Swedish massage by Mejsla and other activities on day 2 and 3. Even though the conference had several tracks but the best track is always the "hallway track" which gives you the unique opportunity to engage with other attendees of the conference.

Markus and I delivered a lab on "Developing JAX-RS Web Applications Utilizing Server-sent Events and WebSockets". Geertjan also showed up at the lab and helped out with general NetBeans questions. The lab guide is available and the complete source code can be downloaded here. Note, the lab works on GlassFish 4.0 build 57 for now because of the pending bugs in SSE implementation in Jersey.

The last 45 minutes of the lab had a different section covering some other Java EE 7 technologies. The lab guide is available at bit.ly/javaee7-hol (PDF) and the starting code is available at bit.ly/javaee7-hol-code (ZIP). For now, this particular lab covers:

This lab is a work in progress and a more comprehensive feature set will be integrated and shared at future conferences (yes, several are already planned!). Let me know if you'll be interested in reviewing the contents and providing feedback.

Here are some pics from the lab session:






The conference also had its first #GeekRun. 7 of us ran in sub-zero temperature in the dark around the island and it was a great experience!



Here is the running route:



The evening concluded with an outstanding speakers' dinner at F12. The hospitality of the restaurant, warmth of the Jfokus events team, and company of some of the finest geeks in the world made the evening memorable. Some pics from the dinner ...






I delivered a session on The Java EE 7 Platform: Productivity++ and Embracing HTML5. There were about 100+ attendees for the 9am session. It gave a quick overview of the features coming in Java EE 7:
  • Java API for WebSocket
  • Java API for JSON Processing
  • Concurrency Utilities for Java EE
  • Batch Applications for Java Platform
  • JAX-RS 2.0
  • JMS 2

And several other technologies which are getting an update. The complete slides are available:

 

The session also showed a quick demo of the latest NetBeans build supporting Java EE 7.

In How to participate in the future of Java, I talkd about how several JUGs are contributing to Adopt-a-JSR efforts around Java EE 7. There are 19 JUGs from around the world that are participating in this effort. What is your JUG waiting for ? Join the momentum now!

Here are some more pictures from the conference:







The conference collected feedback for each talk using green, red, and yellow cards, a concept first found in Oredev. As explained in the opening keynote, the rule is getting green cards is good, yelllow card means so so and red card means the speaker is not coming back to the conference. Here are the cards that I received after my talk on Java EE 7:



I've heard the rumor that Nordic conferences don't like to repeat speakers for more than 2-3 years in a row. This was my third year but hey, the cards are all green. I'm keeping my fingers crossed for next year ;-)

Anyway, congratulations once again Mattias and team for a job very well done!

And the complete photo album:

Friday Feb 01, 2013

Java EE 7 Maven Archetype - Available in NetBeans (TOTD #201)


Want to create a Java EE 7 application using Maven ?

mvn -DarchetypeGroupId=org.codehaus.mojo.archetypes -DarchetypeArtifactId=webapp-javaee7 -DarchetypeVersion=0.1-SNAPSHOT -DarchetypeRepository=https://nexus.codehaus.org/content/repositories/snapshots/ -DgroupId=org.glassfish -DartifactId=javaee7-sample -Dversion=1.0-SNAPSHOT -Dpackage=org.glassfish.javaee7-sample -Darchetype.interactive=false --batch-mode --update-snapshots archetype:generate
[INFO] Scanning for projects...
Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml
Downloading: http://repo1.maven.org/maven2/org/codehaus/mojo/maven-metadata.xml
Downloaded: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml (11 KB at 42.6 KB/sec)
Downloaded: http://repo1.maven.org/maven2/org/codehaus/mojo/maven-metadata.xml (22 KB at 65.6 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-archetype-plugin/maven-metadata.xml
Downloaded: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-archetype-plugin/maven-metadata.xml (701 B at 4.3 KB/sec)
[INFO]                                                                        
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
Downloading: http://repo1.maven.org/maven2/org/codehaus/mojo/maven-metadata.xml
Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml
Downloaded: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-metadata.xml (11 KB at 64.9 KB/sec)
Downloaded: http://repo1.maven.org/maven2/org/codehaus/mojo/maven-metadata.xml (22 KB at 77.8 KB/sec)
Downloading: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-archetype-plugin/maven-metadata.xml
Downloaded: http://repo1.maven.org/maven2/org/apache/maven/plugins/maven-archetype-plugin/maven-metadata.xml (701 B at 3.1 KB/sec)
[INFO]
[INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom <<<
[INFO]
[INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Batch mode
[INFO] Archetype defined by properties
Downloading: https://nexus.codehaus.org/content/repositories/snapshots/org/codehaus/mojo/archetypes/webapp-javaee7/0.1-SNAPSHOT/maven-metadata.xml
Downloaded: https://nexus.codehaus.org/content/repositories/snapshots/org/codehaus/mojo/archetypes/webapp-javaee7/0.1-SNAPSHOT/maven-metadata.xml (786 B at 0.5 KB/sec)
Downloading: https://nexus.codehaus.org/content/repositories/snapshots/org/codehaus/mojo/archetypes/webapp-javaee7/0.1-SNAPSHOT/maven-metadata.xml
Downloaded: https://nexus.codehaus.org/content/repositories/snapshots/org/codehaus/mojo/archetypes/webapp-javaee7/0.1-SNAPSHOT/maven-metadata.xml (786 B at 2.0 KB/sec)
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: webapp-javaee7:0.1-SNAPSHOT
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: org.glassfish
[INFO] Parameter: artifactId, Value: javaee7-sample
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: org.glassfish.javaee7-sample
[INFO] Parameter: packageInPathFormat, Value: org/glassfish/javaee7-sample
[INFO] Parameter: package, Value: org.glassfish.javaee7-sample
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: groupId, Value: org.glassfish
[INFO] Parameter: artifactId, Value: javaee7-sample
[INFO] project created from Archetype in dir: /Users/arungup/code/workspaces/tmp/javaee7-sample
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.703s
[INFO] Finished at: Sat Feb 02 07:31:54 EET 2013
[INFO] Final Memory: 11M/125M
[INFO] ------------------------------------------------------------------------

That's it!

NetBeans Development Builds allows to create a Maven-based Java EE 7 web application now. wiki.netbeans.org/JavaEE7 provide a complete list of planned features. TOTD #199 provide some more details on the features currently working. Of course, this application will get deployed to GlassFish 4.

Tuesday Jan 29, 2013

Java EE 7 and NetBeans IDE - Early Support Available (TOTD #199)


NetBeans IDE provides the best out-of-the-box experience for Java EE development, deployment, and debugging. Early builds of NetBeans have already started providing support for Java EE 7 features such as
  • Registering GlassFish 4
  • Creating Java EE 7 application
  • Wizard for JAX-RS 2 Filters/Interceptors
  • Initial support for Faces Flow
  • Loading templates from a resource library
  • Non-persistent EJB timers in Web profile
  • Wizard for WebSocket endpoints
wiki.netbeans.org/JavaEE7 provide a complete list of features slated for the release and the builds can be downloaded from bertram2.netbeans.org:8080/job/web-main-javaee7. Here are some snapshots of the work completed so far.

Creating a Java EE 7 Web application and using GlassFish 4 server


Creating a WebSocket endpoint



Wizard for creating WebSocket endpoint


The generated code looks like:

@WebSocketEndpoint("/endpoint")
public class NewWSEndpoint {

@WebSocketMessage
public String onMessage(String message) {
return null;
}

}

Creating a JAX-RS 2 Filter


Wizard for creating a JAX-RS 2 Filter


By default it is a server-side filter but can be made client-side filter too.

Wizard for creating a JAX-RS 2 Interceptor



Creating a RESTful Java Client using JAX-RS 2 Client APIs



Wizard for creating a JAX-RS 2 Client


This is a very early work-in-progress so any feedback is welcome.

Download GlassFish 4.0 promoted build, register it with NetBeans IDE and take it for a test drive!

Monday Jan 28, 2013

JSF 2.2 Faces Flow - @FlowScoped, #{flowScope}, @FlowDefinition (TOTD #198)


JavaServer Faces 2.2 is more evolutionary than it is revolutionary. This is by design as JSF 2.0 added a whole bunch of new features as part of the Java EE 6 platform. The Preface 1 from the JSF 2.2 Public Review specification provides a list of changes between JSF 2.1 and 2.2. There are several changes coming in JSF 2.2 but the big ticket items are:
  • Faces Flow
  • Resource Library Contract
  • HTML5 Friendly Markup
This Tip Of The Day (TOTD) will explain Faces Flow. Section 7.5 and 11.4.3 in the specification introduce the feature.

Faces Flow provides an encapsulation of related views/pages with an application defined entry and exit points. For example, a check out cart can consist of cart page, credit card details page, shipping address page, and confirmation page. All these pages, along with required resources and beans, can be packaged together as a module which can then be reused in other applications.

Each flow has a well-defined entry and exit point that have been assigned some application specific meaning by the developer. Usually the objects in a faces flow are designed to allow the user to accomplish a task that requires input over a number of different views. In our case, the navigation between pages for selecting items, entering shipping address, credit card details, and confirmation page would make a flow. All the pages and objects that deal with the checking out process can be composed as modules. An application thus become a collection of flows instead of just views.

It takes the best part of other flow-based technologies such as ADF Task Flow, Spring Web Flow, and Apace MyFaces CODI and standardizes in JSF 2.2.

What is the need ?

Imagine a multi-page shopping cart with one page for selecting the items, a second page for shipping options, a third page for entering credit card details, and a fourth page for final confirmation. Managed Beans can be used to capture the data, session scope variables pass information between pages, button clicks can be used to invoke the business logic in backing EJBs, and (conditional) navigation rules can be defined to go from one page to another. There are a few issues with this approach:
  • This flow of sequence will typically be part of a bigger application. However an application, typically with several pages, is one large flow and everything is visible with no logical partitioning.
  • The flow of pages or views cannot be encapsulated as a logical unit and thus cannot be reused, e.g. incorporated into another bigger flow easily.
  • The lowest logical granularity is a page. The only way to invoke application logic is to tie it to a UI component activated by the user in a page. Business logic cannot be invoked without any user initiated action.
  • Same flow cannot be opened in multiple windows because session scoped variables are used to pass information between pages. CDI defines @ConversationScoped but that is only part of the solution.
  • There is no scope defined that can span multiple pages but less than a session.
Faces Flow provide a solution to the issues mentioned above.

What's new in JSF 2.2 for flows ?

The flow of application is no longer restricted to flow between pages but instead defined as flow between "nodes". There are five different types of nodes:
  • View: Any JSF page in the application
  • Method Call: Invoke application logic from flow graph via an EL
  • Switch: Navigation decisions in the flow graph based on boolean EL
  • Flow Call: Call another flow with parameters and receive return values
  • Flow Return: Return to the calling flow
The nodes define the entry and exit points of a flow.

Two new annotations are introduced:
  • @FlowScoped is a CDI scope that defines the scope of bean in the specified flow. This enables automatic activation/passivation of the bean when the scope is entered/exited.
  • @FlowDefinition is a class level annotation that allows the flow definition to be defined using the fluent FlowBuilder API.
A new EL object, #{flowScope}, for flow local storage is also introduced. This maps to facesContext.getApplication().getFlowHandler().getCurrentFlowScope().

How are flows packaged ?

Flows can be packaged in JAR files or in directories.

JAR packaging requires flows to be explicitly declared in META-INF/faces-config.xml in the JAR file. Flow nodes are packaged in META-INF/flows/<flowname> where <flowname> is a JAR directory entry whose name is identical to that of a flow id in the corresponding faces-config.xml. @FlowScoped and @FlowDefinition beans must be packaged in the JAR file and accompanied by META-INF/beans.xml.

A sample JAR file looks like:

META-INF/faces-config.xml
META-INF/flows/flow1/entry.xhtml
META-INF/flows/flow1/next.xhtml
META-INF/flows/flow1/end.xhtml
META-INF/flows/flow2/start.xhtml
META-INF/flows/flow2/next.xhtml
META-INF/flows/flow2/end.xhtml
META-INF/beans.xml
org/glassfish/sample/MyFlow1Bean.class
org/glassfish/sample/MyFlow2Bean.class
org/glassfish/sample/MyFlowDefintion.class
Flows packaged in directories use convention-over-configuration. The conventions are:
  • Every View Declaration Language file in that directory is a view node of that flow.
  • The start node of the flow is the view whose name is the same as the name of the flow.
  • Navigation among any of the views in the directory is considered to be within the flow.
  • Navigation to a view outside of that directory is considered to be an exit of the flow.
  • Optional <flowname>-flow.xml that represents the flow definition. The rules in this file overrides the conventions described above.

A sample directory looks like:

flow1/flow1.xhtml
flow1/flow1a.xhtml
flow1/flow1b.xhtml
flow2/flow2-flow.xml
flow2/flow2.xhtml
flow2/flow2a.xhtml
flow2/flow2b.xhtml
WEB-INF/...
Show me the code!

Lets try a sample now!

The source code for the two samples explained below can be downloaded here. A complete explanation of the sample including the code walk-through is shown in the video:



This will run on GlassFish 4.0 b72. For now, you'll need to replace glassfish/modules/javax.faces.jar with javax.faces-2.2.0-SNAPSHOT.jar and replacing glassfish/modules/javax.el.jar with javax-el-3.0-b03.jar. This JARs will soon be integrated in the GlassFish build. Ah, the joys of bleeding edge development!

Saturday Jan 26, 2013

Java EE 7 Maven Application (TOTD #197)

Did you know that Java EE 7 APIs are now published in maven ?

The complete set of coordinates are described here. So how do you build a simple Java EE 7 maven application ?

  1. Generate the ususal Java EE 6 maven application as:

    mvn -DarchetypeGroupId=org.codehaus.mojo.archetypes -DarchetypeArtifactId=webapp-javaee6 -DarchetypeVersion=1.5 -DarchetypeRepository=http://repo.maven.apache.org/maven2 -DgroupId=org.glassfish -DartifactId=hello-javaee7 -Dversion=1.0-SNAPSHOT -Dpackage=org.glassfish.hellojavaee7 -Darchetype.interactive=false --batch-mode archetype:generate
  2. In the generated pom.xml, replace
    <dependencies>
    <dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-web-api</artifactId>
    <version>6.0</version>
    <scope>provided</scope>
    </dependency>
    </dependencies>

    with

    <repositories>
    <repository>
    <id>Java EE 7</id>
    <url>https://maven.java.net/content/groups/promoted/</url>
    </repository>
    </repositories>

    <dependencies>
    <dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0-b72</version>
    </dependency>
    </dependencies>

    Notice, there is a new <version> of dependency for each GlassFish 4 promoted build. This may be simplified in the coming builds.

    The <artifactId> can be changed to javaee-web-api if your application requires Java EE 7 Web Profile API only.

And now all Java EE 7 APIs so far integrated in GlassFish are available in your application.

You can also include specific API JAR files explicitly in your project directly. The latest APIs are available in the format:

In general, you can replace "b72" in the URL with the latest promoted build number to get the latest artifacts. A simplified URL for the latest set of these artifacts is in the works!

What next ? Maven archetype and support in NetBeans coming soon!

Tuesday Jan 22, 2013

Default DataSource in Java EE 7: Lesser XML and More Defaults (TOTD #196)


Section E.5.5.20 in the Java EE 7 Platform specification defines a new Default Data Source that must be provided by a Java EE 7-compliant runtime. This pre-configured data source can be used by application for accessing the associated database. It is accessible to the application under the JNDI name:
java:comp/DefaultDataSource

This can be accessed in the application as:
@Resource(name="myDataSource", lookup="java:comp/DefaultDataSource")
DataSource myDS;

If the binding is not specified, the mapping of the reference will default to this default data source. So the above fragment is equivalent to:
@Resource(name="myDataSource")
DataSource myDS;

Section 8.2.1.5 in the JPA 2.1 specification says

If neither jta-data-source and non-jta-data-source elements are specified, the deployer must specify a JTA data source at deployment or a JTA data source must be provided by the container, and a JTA EntityManagerFactory will be created to correspond to it.

Per.book
This means a Java EE 7 application can have the following persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="myPU" transaction-type="JTA">
<jta-data-source>java:comp/DefaultDataSource</jta-data-source>
</persistence-unit>
</persistence>

This is semantically equivalent to:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="movieplex7PU" transaction-type="JTA"/>
</persistence>

Notice, no jta-data-source.

In both cases, the default data source will be provisioned and available to the application. In GlassFish 4, this is bound to the JDBC resource jdbc/__default.

And this can be verified by giving the command:
./bin/asadmin list-jdbc-resources
jdbc/sample
jdbc/__TimerPool
jdbc/__default
Command list-jdbc-resources executed successfully.

Lesser XML and more defaults makes Java EE 7 more lightweight and user friendly!

Download GlassFish 4.0 promoted build and try it today!

Friday Jan 18, 2013

JPA 2.1 Implementation - EclipseLink M6 integrated in GlassFish 4 (TOTD #195)

As TOTD #187 explained, one of the new features in JPA 2.1 is Schema Generation. It refers to generation of database artifacts like tables, indexes, and constraints in a database schema. Read TOTD #187 for more details. This Tip Of The Day (TOTD) will explain how to use this feature in GlassFish 4.

JPA 2.1 is implemented in EclipseLink and the status shows that a decent progress is made. EclipseLink Milestone builds shows the dates when milestones are released. It typically takes a few days for the milestone to be integrated in GlassFish 4 after the release.

How do you know which milestone is integrated in GlassFish 4 ?

Issue the following commmand in glassfish/modules directory:
unzip -p org.eclipse.persistence.core.jar META-INF/MANIFEST.MF | grep Bundle-Version
to see an output as:
Bundle-Version: 2.5.0.v20130110-d839ca4
If we break the version string then it shows this is version 2.5.0 and dated 20130110 in the format YYYYMMDD, that would be Jan 10, 2013. Based upon the milestone release dates, this indicates M6 is integrated.

I tried this with the latest nightly build (dated Jan 18). By the time you read this blog, a newer version may be integrated and so the version string may look different.

Now lets see this in action!

The sample code explained below can be downloaded here and run on GlassFish 4 1/17 nightly. A promoted build after this nightly should work too.

Create an Entity class as:
@Entity
@Table
@NamedQueries({
@NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e")
})
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

@Column(length=40)
private String name;
This is a simple Employee entity that has two fields id and name. A trivial @NamedQuery is defined to retrieve the list of employees.

The associated persistence.xml looks like:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="MyPU" transaction-type="JTA">
<jta-data-source>jdbc/sample</jta-data-source>
<properties>
<property name="javax.persistence.schema-generation-action" value="drop-and-create"/>
<property name="javax.persistence.schema-generation-target" value="database"/>
<property name="eclipselink.deploy-on-startup" value="true"/>
</properties>
</persistence-unit>
</persistence>

Other than the usual elements like <persistence-unit> and <jta-data-source>, the newly introduced properties - javax.persistence.schema-generation-action and javax.persistence.schema-generation-target define the action and target for the schema generation. The action is to drop and create the tables. The target defines to perform the action in the database. These properties control the behavior of schema generation and their meaning is defined in TOTD #187. Notice, the third property is EclipseLink specific and is specified to eagerly initialize the Persistence Unit. This will ensure that the schema is generated during the application deployment itself. Otherwise it is generated when the PU is first accessed.

This will generate the table in the database defined by jdbc/sample JDBC resource. This resource is pre-defined for JavaDB that is already bundled with GlassFish 4.

After this, you can write a simple EJB as:

@Stateless
public class EmployeeBean {

@PersistenceContext
EntityManager em;

public void persist(Employee e) {
em.persist(e);
}

public List<Employee> get() {
return em.createNamedQuery("Employee.findAll", Employee.class).getResultList();
}
}

And invoke it from a Servlet as:

for (int i=0; i<5; i++) {
bean.persist(new Employee("Name" + i));
}
for (Employee e : bean.get()) {
out.println(e.getName() + "<br>");
}

A different set of properties may be specified as:

<properties>
<property name="javax.persistence.schema-generation-action" value="drop-and-create"/>
<property name="javax.persistence.schema-generation-target" value="scripts"/>
<property name="javax.persistence.ddl-create-script-target" value="createfoo.sql"/>
<property name="javax.persistence.ddl-drop-script-target" value="dropfoo.sql"/>
<property name="eclipselink.deploy-on-startup" value="true"/>
<property name="eclipselink.application-location" value="/tmp"/>
</properties>
These properties specify the action as "drop-and-create", i.e. drop and create the tables. The target specifies the the action to be performed in a script. The *.script-target property specifies the name of the files for create and drop DDL. The following scripts are generated:

more /tmp/createfoo.sql 
CREATE TABLE EMPLOYEE (ID INTEGER NOT NULL, NAME VARCHAR(40), PRIMARY KEY (ID))
CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT DECIMAL(15), PRIMARY KEY (SEQ_NAME))
INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0)
CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT DECIMAL(15), PRIMARY KEY (SEQ_NAME))
INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0)

more /tmp/dropfoo.sql
DROP TABLE EMPLOYEE
DELETE FROM SEQUENCE WHERE SEQ_NAME = 'SEQ_GEN'

By default, the scripts are generated in glassfish/domains/domain1 directory. In this case, an EclipseLink-specific property to identify the base location of the generated files is specified.

As TOTD #187 explains, you can bundle DDL and DML scripts to generate and populate the database. Are you ready to test drive JPA 2.1 implemented using EclipseLink 2.5 in GlassFish 4 ?

JPA 2.1 Public Review specification has been available for a few days now. The Appendix A in the specification provide revision history in case you want to focus on the newly added features only.  If you are a JUG member, you may consider adopting this JSR and provide feedback!

Friday Jan 11, 2013

JAX-RS Client API and GlassFish 4 - Logging HTTP messages (TOTD #194)


One of the main features added in JAX-RS 2 is Client API. This API is used to access Web resources and provides integration with JAX-RS Providers. Without this API, the users need to use a low-level HttpUrlConnection to access the REST endpoint.

If the resource looks like:

@Path("/fruit")
public class MyResource {

@GET
public String get() {

then, before this API, the endpoint can be accessed as:

URL url = new URL("http://. . ./webresources/fruit");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.setDoOutput(false);
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
    //. . .
}
With this newly introduced API, the endpoint can be accessed as:

Client client = ClientFactory.newClient();
WebTarget target = client.target("http://. . ./webresources/fruit");
String response = target.request().get(String.class);
Client is the entry point to the Client API and is used to build and execute client requests and consume responses returned. The default instance of Client can be obtained by calling ClientFactory.newClient. Using this we can create a WebTarget by specifying URI of the web resource. These targets are then used to prepare client request invocation by specifying additional query or matrix parameters and resolving the URI template for different names. Finally, one of the HTTP methods is invoked on the prepared client.

The fluency of the API hides the complexity but a better understanding of the flow allows to write better code.

All the classes introduced in the specification are available in javax.ws.rs.client package.

Lets take a look at a complete sample. The complete source code can be downloaded here.

For a resource defined as:

@Path("/fruit")
public class MyResource {

@GET
public String get() {
return Database.getAll();
}

@GET
@Path("{name}")
public String get(@PathParam("name")String payload) {
return Database.get(payload);
}

@POST
public void post(String payload) {
Database.add(payload);
}

@PUT
public void put(String payload) {
Database.add(payload);
}

@DELETE
public void delete(String payload) {
Database.delete(payload);
}
}

A Client invoking all the HTTP methods look like:

Client client = ClientFactory.newClient();
WebTarget target = client.target("http://"
+ request.getServerName()
+ ":"
+ request.getServerPort()
+ request.getContextPath()
+ "/webresources/fruit");

// POST
target.request().post(Entity.text("apple"));

// PUT
target.request().put(Entity.text("banana"));

// GET (all)
String r = target.request().get(String.class);

// GET (one)
r = target.path("apple").request().get(String.class);

// DELETE
target.path("banana").request().delete();

// GET (all)
r = target.request().get(String.class);

And here are the message dumps:

INFO: 1 * LoggingFilter - Request received on thread http-listener-1(5)
1 > POST http://localhost:8080/endpoint/webresources/fruit
1 > Content-Type: text/plain
apple

INFO: 2 * LoggingFilter - Response received on thread http-listener-1(5)
2 < 204
2 < Date: Fri, 11 Jan 2013 22:21:23 GMT
2 < Server: GlassFish Server Open Source Edition 4.0
2 < X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7)

INFO: 3 * LoggingFilter - Request received on thread http-listener-1(5)
3 > PUT http://localhost:8080/endpoint/webresources/fruit
3 > Content-Type: text/plain
banana

INFO: 4 * LoggingFilter - Response received on thread http-listener-1(5)
4 < 204
4 < Date: Fri, 11 Jan 2013 22:21:23 GMT
4 < Server: GlassFish Server Open Source Edition 4.0
4 < X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7)

INFO: 5 * LoggingFilter - Request received on thread http-listener-1(5)
5 > GET http://localhost:8080/endpoint/webresources/fruit

INFO: 6 * LoggingFilter - Response received on thread http-listener-1(5)
6 < 200
6 < Date: Fri, 11 Jan 2013 22:21:23 GMT
6 < Content-Length: 15
6 < Content-Type: text/html
6 < Server: GlassFish Server Open Source Edition 4.0
6 < X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7)
[apple, banana]

INFO: 7 * LoggingFilter - Request received on thread http-listener-1(5)
7 > GET http://localhost:8080/endpoint/webresources/fruit/apple

INFO: 8 * LoggingFilter - Response received on thread http-listener-1(5)
8 < 200
8 < Date: Fri, 11 Jan 2013 22:21:23 GMT
8 < Content-Length: 5
8 < Content-Type: text/html
8 < Server: GlassFish Server Open Source Edition 4.0
8 < X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7)
apple

INFO: 9 * LoggingFilter - Request received on thread http-listener-1(5)
9 > DELETE http://localhost:8080/endpoint/webresources/fruit/banana

INFO: 10 * LoggingFilter - Response received on thread http-listener-1(5)
10 < 204
10 < Date: Fri, 11 Jan 2013 22:21:23 GMT
10 < Server: GlassFish Server Open Source Edition 4.0
10 < X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7)

INFO: 11 * LoggingFilter - Request received on thread http-listener-1(5)
11 > GET http://localhost:8080/endpoint/webresources/fruit

INFO: 12 * LoggingFilter - Response received on thread http-listener-1(5)
12 < 200
12 < Date: Fri, 11 Jan 2013 22:21:23 GMT
12 < Content-Length: 7
12 < Content-Type: text/html
12 < Server: GlassFish Server Open Source Edition 4.0
12 < X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7)
[apple]

This has been tested on GlassFish 4 build 70 with the following dependencies:

<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0-m10</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.0-m10</version>
<type>jar</type>
</dependency>

Here are some more pointers to follow:

Provide feedback on Jersey 2 to users@jersey.java.net and JAX-RS specification to users@jax-rs-spec.java.net.


Wednesday Jan 02, 2013

Batch Applications in Java EE 7 - Undertanding JSR 352 Concepts: TOTD #192


Batch processing is execution of series of "jobs" that is suitable for non-interactive, bulk-oriented and long-running tasks. Typical examples are end-of-month bank statement generation, end-of-day jobs such as interest calculation, and ETL (extract-transform-load) in a data warehouse. These tasks are typically data or computationally intensive, execute sequentially or in parallel, and may be initiated through various invocation models, including ad-hoc, scheduled, and on-demand.

JSR 352 will define a programming model for batch applications and a runtime for scheduling and executing jobs. This blog will explain the main concepts in JSR 352.

The diagram below highlight the key concepts of a batch processing architecture.



  • A Job is an instance that encapsulates an entire batch process. A job is typically put together using a Job Specification Language and consists of multiple steps. The Job Specification Language for JSR 352 is implemented with XML and is referred as "Job XML".
  • A Step is a domain object that encapsulates an independent, sequential phase of a job. A step contains all of the information necessary to define and control the actual batch processing.
  • JobOperator provides an interface to manage all aspects of job processing, including operational commands, such as start, restart, and stop, as well as job repository commands, such as retrieval of job and step executions.
  • JobRepository holds information about jobs current running and jobs that run in the past. JobOperator provides access to this repository.
  • Reader-Processor-Writer pattern is the primary pattern and is called as Chunk-oriented processing. In this, ItemReader reads one item at a time, ItemProcessor processes the item based upon the business logic, such as calculate account balance and hands it to ItemWriter for aggregation. Once the 'chunk' number of items are aggregated, they are written out, and the transaction is committed.

    JSR 352 also defines roll-your-own batch pattern, called as Batchlet. This batch pattern is invoked once, runs to completion, and returns an exit status. This pattern must implement and honor a "cancel" callback to enable operational termination of the Batchlet.
A Job XML for a chunk-oriented processing may look like:

<job id="myJob" xmlns="http://batch.jsr352/jsl">
<step id="myStep" >
<chunk reader="MyItemReader"
writer="MyItemWriter"
processor="MyItemProcessor"
buffer-size="5"
checkpoint-policy="item"
commit-interval="10" />
</step>
</job>

  • The <job> has an "id" attribute that defines the logical name of the job and is used for identification purposes.
  • Each <job> can multiple <step>s where each <step> identifies a job step and it's characteristics. Each <step> has an "id" attribute that defines the logical name of the job and is used for identification purposes.
  • A <step> may have <chunk> or <batchlet> element, this <step> has a <chunk>. A <chunk> identifies a chunk type step and implements the reader-processor-writer pattern of batch.
  • The "reader", "processor", and "writer" attributes specify the class names of an item reader, processor, and writer respectively.
  • "buffer-size" specifies number of items to read and buffer before writing. When enough items have been read to fill the buffer, the buffer is emptied to a list and the configured ItemWriter is invoked with the list of items.
  • "checkpoint-policy" attribute specifies the checkpoint policy that governs commit behavior for this chunk. Valid values are "item", "time" and "custom". The "item" policy means chunk is checkpointed after a specified number of items are processed. The "time" policy means the chunk is committed after a specified amount of time. The "custom" policy means the chunk is checkpointed according to a checkpoint algorithm implementation. The default policy is "item".
  • "commit-interval" specifies the commit interval for the specified checkpointed policy. The unit meaning of the commit-interval specifies depends on the specified checkpoint policy. For "item" policy, commit-interval specifies a number of items. For "time" policy, commit- interval specifies a number of seconds. The commit-interval attribute is ignored for "custom" policy.

    When the configured checkpoint policy directs it is time to checkpoint, all the items read and processed so far are passed to the "writer".

Here is a simple reader:

@ItemReader
public class MyItemReader {
private static int id;
MyCheckPoint checkpoint = null;

@Open
void open(MyCheckPoint checkpoint) {
this.checkpoint = checkpoint;
System.out.println(getClass().getName() + ".open: " + checkpoint.getItemCount());
}

@ReadItem
MyBatchRecord read() {
checkpoint.incrementByOne();
return new MyBatchRecord(++id);
}

@CheckpointInfo
MyCheckPoint getCheckPoint() {
return checkpoint;
}
}

Methods marked with @Open, @ReadItem, and @CheckpointInfo are required.

Here is a simple processor that rejects every other item:

@ItemProcessor
public class MyItemProcessor {
@ProcessItem
MyBatchRecord process(MyBatchRecord record) {
return (record.getId() % 2 == 0) ? record : null;
}
}

And here is a simple writer:

@ItemWriter
public class MyItemWriter {
MyCheckPoint checkpoint = null;

@Open
void open(MyCheckPoint checkpoint) {
this.checkpoint = checkpoint;
System.out.println(getClass().getName() + ".open: " + checkpoint.getItemCount());
}

@WriteItems
void write(List<MyBatchRecord> list) {
System.out.println("Writing the chunk...");
for (MyBatchRecord record : list) {
System.out.println(record.getId());
}
checkpoint.increment(list.size());
System.out.println("... done.");
}

@CheckpointInfo
MyCheckPoint getCheckPoint() {
return checkpoint;
}
}

Finally a simple implementation of MyCheckpoint:

public class MyCheckPoint {
int itemCount;

public int getItemCount() {
return itemCount;
}

public void setItemCount(int itemCount) {
this.itemCount = itemCount;
}

void incrementByOne() {
itemCount++;
}

void increment(int size) {
itemCount += size;
}
}

Together, MyItemReader, MyItemWriter, MyItemProcessor, MyCheckPoint, and batch.xml, will read/process/write 5 items and commit when 10 such items have been processed.

JSR 352 specification defines several other concepts such as how Job XML can define sequencing of jobs, listeners to interpose on job execution, transaction management, and running jobs in partitioned and concurrent modes. Subsequent blog will explain some of those concepts.

A complete replay of Java Batch for Cost-Optimized Business Efficiency from JavaOne 2012 can be seen here (click on CON4105_mp4_4105_001 in Media).

Each feature will be added to the JSR subject to EG approval. You can share your feedback to public@jbatch.java.net.

The APIs and implementation of JSR 352 are not integrated in GlassFish 4 promoted builds yet.

Here are some more references for you:

Here are some other Java EE 7 primers published so far:


And of course, more on their way! Do you want to see any particular one first ?

Wednesday Dec 26, 2012

Simple JMS 2.0 Sample - @JMSDestinationDefinition and Synchronous Message Receive: TOTD #191


JMS 2.0 Early Draft - Simplified API Sample Code explained some of the changes that are made in JMS 2.0 to "catch up" with all the changes in the Java SE and EE platform over the past few years. The main goals of JMS 2.0 are:
  • Changes to improve ease-of-development
  • Clarification of relationship between JMS and other Java EE specifications
  • Definition of a new mandatory API to allow any JMS provider to be integrated with any other Java EE Application Server
  • Other enhancements as requested by the community
This Tip Of The Day (TOTD) will explain a simple sample showing how to send a message and receive it synchronously. The complete source code for the sample can be downloaded here.

This is a Stateless EJB that has a single method to send a message.

@Stateless
public class MessageSender {

@Inject
JMSContext context;

@Resource(mappedName="java:global/jms/myQueue")
Queue queue;

public void sendMessage(String message) {
context.createProducer().send(queue, message);
}
}
In this code:
  • JMSContext is a new interface introduced in the simplified API in JMS 2.0. This combines in a single object the functionality of two separate objects from the JMS 1.1 API: a Connection and a Session.

    A JMSContext may be injected in the Java EE web and EJB containers using the @Inject annotation. A JMSContext created in this way is described as being container-managed. A container-managed JMSContext will be closed automatically by the container. Applications running in the Java EE web and EJB containers are not permitted to create more than one active session on a connection. This allows to combine them in a single object offering a simpler API. This is the recommended way for creating JMS context in Java EE applications.

    A JMSContext may be created by calling one of the createContext methods on a ConnectionFactory. A JMSContext that is created this way is described as being application-managed. An application-managed JMSContext must be closed when no longer needed by calling its close method. Applications running in a Java SE environment or in the Java EE application client container are permitted to create multiple active sessions on the same connection. This allows the same physical connection to be used in multiple threads simultaneously. The createContext method is recommended to create JMSContext in such applications.
  • The Java EE Platform requires a preconfigured JMS ConnectionFactory accessible to the application under the JNDI name:
    java:comp/DefaultJMSConnectionFactory
    The annotation @JMSConnectionFactory may be used to specify the JNDI lookup name of the ConnectionFactory used to create the JMSContext as:
    @Inject
    @JMSConnectionFactory("java:comp/DefaultJMSConnectionFactory")
    JMSContext context;
    If no lookup name is specified or the @JMSConnectionFactory is omitted then the platform default JMS connection factory will be used. The above code fragment is equivalent to:
    @Inject
    JMSContext context;
  • @Resource defines a dependency on a resource needed by the application. In this case, it specifies the JNDI name of the destination to which the message needs to be sent.
  • When an application needs to send messages it uses the createProducer method to create JMSProducer which provides methods to configure and send messages. The various setProperty methods are used to set property on the message being sent. There are several other methods like setPriority, setDeliveryDelay, and setTimeToLive to set other quality-of-service attributes for the message being sent.

    Messages may be sent synchronously or asynchronously. Synchronous messages are sent using one of the send methods. Asynchronous messages are sent using setAsync method and assigning a CompletionListener. When the message has been successfully sent the JMS provider invokes the callback method onCompletion on the CompletionListener object. If the message is not sent for some reason or an acknowledgement from the remote JMS server is not received then onException callback method is called. An asynchronous send is not permitted in a Java EE application.

This is a Stateless EJB that has a single method to receive the message synchronously.

@Stateless
public class MessageReceiverSync {

@Inject
private JMSContext context;

@Resource(mappedName="java:global/jms/myQueue")
Queue myQueue;

public String receiveMessage() {
String message = context.createConsumer(myQueue).receiveBody(String.class, 1000);
return "Received " + message;
}
}

In this code:
  • JMSContext referring to the preconfigured JMS ConnectionFactory is injected by the container.
  • @Resource defines a dependency on the JMS destination on which the message is received.
  • When an application needs to receive messages it uses one of the several createConsumer or createDurableConsumer methods to create a JMSConsumer. createConsumer creates a non-durable subscription on the specified destination. This means that a client will only see the messages published on the destination when the subscriber is active. If the subscriber is not active, it is missing messages published on the destination. createDurableConsumer creates an unshared durable subscription of a specified topic and creates a consumer on that subscription. This allows the subscriber will receive all messages published on a topic, including the ones published when there is no active consumer associated with it. The JMS provider retains a record of this durable subscription and ensures that all messages from the topic's publishers are retained until they are delivered to, and acknowledged by, a consumer on this durable subscription or until they have expired.

    A JMSConsumer provides methods to receive messages either synchronously or asynchronously. receive methods are used for synchronous delivery of the messages. A MessageListener object may be registered with the client for asynchronous delivery of the messages. onMessage method of the MessageListener object are called as messages are received. Asynchronous delivery of messages will not work until MQ-264 is fixed.
Next is a Servlet that ties all the pieces together. It defines the JMS Destination and send and receive the message using the previously defined EJBs.

@JMSDestinationDefinition(name = "java:global/jms/myQueue",
resourceAdapterName = "jmsra",
className = "javax.jms.Queue",
destinationName="queue1234",
description="My Queue")
@WebServlet(urlPatterns = {"/TestServlet"})
public class TestServlet extends HttpServlet {

@EJB MessageSender sender;

@EJB MessageReceiverSync receiver;


void doGet(HttpServletRequest request, HttpServletResponse response) {
. . .
String m = "Hello there";
sender.sendMessage(m);
out.format("Message sent: %1$s.<br>", m);
out.println("Receiving message...<br>");
String message = receiver.receiveMessage();
out.println("Message received: " + message);
. . .
}
In this code:
  • @JMSDestinationDefinition defines the JMS destination. The name attribute defines the JNDI name of the destination being defined, destinationName attribute defines the name of the queue or topic, and className attribute defines the JMS destination implementation class name.
  • doGet method uses the injected EJBs to send and receive the message.
The complete source code for the sample can be downloaded here. "mvn package" and deploy the generated WAR file.

Download GlassFish 4 build 68 onwards and try this sample today!

The latest progress on JMS 2.0 can be tracked at:

Help us make JMS 2.0 better, simpler, easier to use. Join users@jms-spec and contribute!

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