Thursday Feb 28, 2013

Updating to latest WebSocket API - Starting with GlassFish b78 (TOTD #209)


Java API for WebSocket (JSR 356) has recently gone through a major refactoring. The changes are integrated in Tyrus b12 and now available in GlassFish b78. This Tip Of The Day (TOTD) shows the change log for WebSocket endpoint in Collaborative Whiteboard Sample (explained in TOTD #189) between GlassFish b76 and b78.

First of all, everything stays in javax.websocket.* and javax.websocket.server.* package.

There are name changes in annotations, APIs, class renames, and some behavior change as well. Pavel's blog provides a comprehensive list of changes and the annotation changes are listed here as well:

Name before b78
Name after b78
@WebSocketEndpoint
@ServerEndpoint
@WebSocketClient
@ClientEndpoint
@WebSocketMessage
@OnMessage
@WebSocketPathParam @PathParam
@WebSocketOpen
@OnOpen
@WebSocketClose
@OnClose
@WebSocketError
@OnError


Here is the change log for updating Whiteboard.java:

--- <html>Whiteboard.java (<b>849f919</b>)</html>
+++ <html><b>Current File</b></html>
@@ -45,50 +45,48 @@
import java.util.HashSet;
import java.util.Set;
import javax.websocket.EncodeException;
+import javax.websocket.OnClose;
+import javax.websocket.OnMessage;
+import javax.websocket.OnOpen;
import javax.websocket.Session;
-import javax.websocket.WebSocketClose;
-import javax.websocket.WebSocketMessage;
-import javax.websocket.WebSocketOpen;
-import javax.websocket.server.WebSocketEndpoint;
+import javax.websocket.server.ServerEndpoint;

/**
* @author Arun Gupta
*/
-@WebSocketEndpoint(value = "/websocket",
+@ServerEndpoint(value = "/websocket",
encoders = {FigureEncoder.class},
decoders = {FigureDecoder.class})
public class Whiteboard {

private static Set<Session> peers = Collections.synchronizedSet(new HashSet<Session>());

- @WebSocketOpen
+ @OnOpen
public void onOpen(Session peer) {
peers.add(peer);
}

- @WebSocketClose
+ @OnClose
public void onClose(Session peer) {
peers.remove(peer);
}

- @WebSocketMessage
+ @OnMessage
public void boradcastFigure(Figure figure, Session session) throws IOException, EncodeException {
System.out.println("boradcastFigure: " + figure);
for (Session peer : peers) {
if (!peer.equals(session)) {
- peer.getRemote().sendObject(figure);
+ peer.getBasicRemote().sendObject(figure);
}
}
}

- @WebSocketMessage
+ @OnMessage
public void broadcastSnapshot(ByteBuffer data, Session session) throws IOException {
System.out.println("broadcastBinary: " + data);
for (Session peer : peers) {
if (!peer.equals(session)) {
- peer.getRemote().sendBytes(data);
+ peer.getBasicRemote().sendBinary(data);
}
}
}

The updated source code for the sample is available here and runs on GlassFish b78.

Hopefully this gives you a good idea on how to migrate your WebSocket applications from the older to the newer API. The changes are still evolving and the specification (PDF) and javadocs (ZIP) are the definitive source for the latest information. The complete set of latest spec downloads are available here.

As always, send the spec feedback to users@websocket-spec.java.net and implementation feedback to users@tyrus.java.net.

Wednesday Feb 27, 2013

Transparency and Community Participation in Java EE 7


Ever since the launch of Java EE 7 and its component JSRs, Oracle has been very committed to a high level of transparency for all of the JSRs under the Java EE 7 umbrella. We're so excited that increased transparency has resulted in more useful feedback that has improved the Java EE platform. Let me tell you what we've done, how it's helped, and how you can get involved too.

One of the requirements for JCP 2.8 is:

When voting to approve a JSR's transition to the next stage, EC members are expected to take into consideration the extent to which the Spec Lead is meeting the transparency requirements.

Now that many of these JSRs have gone through the Public Review Ballot and others are in progress, it is useful to review how they have contributed to the transparency process.

First of all, all Java EE 7 Expert Groups are operating using the transparency rules defined JCP 2.8. The transparency rule requires:
  1. Public can read the names on the Expert Group
  2. Expert Group business is regularly reported on a publicly readable alias
  3. Mechanism for allow public to provide feedback
  4. Spec lead respond to the posts on the alias
  5. Schedule of JSR is publicly available, current, and updated regularly
  6. Open source process for the development of RI and/or TCK
  7. Publicly readable and/or writable issue-tracker
  8. Publicly accessible document archive
Happy to report that all the JSRs in Java EE 7 have followed the guidelines mentioned above. Providing a specific example using JSR 342:
  1. JSR 342 has all the Expert Group member names publicly listed
  2. All technical discussions on the Expert Group are reported on jsr342-experts@javaee-spec.java.net alias and archived
  3. Anybody outside the Expert Group can subscribe to the alias at users@javaee-spec.java.net and provide feedback
  4. Spec leads regularly read and respond on the alias
  5. Schedule of JSR is publicly reported at javaee-spec.java.net
  6. GlassFish is the Reference Implementation and is completely built in open source. The promoted builds have been available for several months, the schedule is completely transparent, maven coordinates are published, and NetBeans tooling is available for some time. All this allows developers to play with the bleeding edge Java EE 7 technologies as they are integrated in GlassFish. Public forum allows the users to communicate specifically about the RI.
  7. Publicly readable/writable issue tracker
  8. Publicly accessible document archive
The transparency checklist by each JSR is explained in the table below.

Many of our spec leads have gone beyond this in their outreach to the community with blogs, talks, chats, and more. The Java EE 7 Expert Group recently concluded a public survey seeking community input to define key areas in the platform such as which specifications should be included in the Web Profile, should CDI be enabled by default, expanded use of @Stereotype, and expansions of Interceptors to all Java EE components. Over 1100 respondents voted, make their voices heard, and help decide the direction of the platform.

The table below provides:
  • Public website for each specification in Java EE 7. All of our JSRs that are part of the Java EE 7 Platform are being run in the open, using java.net projects.  These JSRs, and links to their respective projects are listed on the home page of the Java EE 7 Platform JSR and in the table below. Each page has publicly viewable Expert Group mailing lists as Users observer lists. The Users lists receive copies of all expert group emails, as well as providing users the ability to post feedback and engage in discussions with each other and with expert group members. All lists have publicly viewable archives on the java.net project sites.

    Similarly, all projects have publicly accessible download areas, and JIRA issue trackers where bugs and suggestions for new features can be posted, and which also serve as another means of discussion with EG members. The schedules and interim drafts of the specification were posted on the main project page and publicly visible Downloads area.
  • Transparency Checklist columns shows the status of different JSRs meeting the transparency requirements of JCP 2.8.
  • Community Participation represents the increase in community participation above and beyond the core Expert Group for each Specification. As you can see the participation from the community outside the Expert Group is pretty significant and has worked really well.
  • To encourage further community participation, different Java EE 7 Expert Groups defined specific areas to provide feedback using Adopt-a-JSR. We saw tremendous success with the effort with several JUGs joining the effort. The last column lists different JUGs that have adopted a particular JSR. In several cases, JUGs have adopted multiple JSRs.

Specification / JSR Transparency Checklist
Community
Participation
Adopt-a-JSR
A B C D E F G H
Concurrency (JSR 236)

~250%

JPA (JSR 338)
~250%
Chennai JUG
Hyderabad JUG
JAX-RS (JSR 339)
~350%
CE JUG
Indonesia JUG
LJC
Madrid JUG
Morocco JUG
Peru JUG
SouJava
Servlet (JSR 340)
~350%

EL (JSR 341)
~125%

Java EE 7 (JSR 342)
~600%
LJC
JMS (JSR 343)
~500%
FASO JUG
Indonesia JUG
LJC
Peru JUG
JSF 2.2 (JSR 344)
~200%
CE JUG
Chennai JUG
Cologne JUG
Hyderabad JUG
SouJava
EJB (JSR 345)
~300%
SouJava Campinas JUG
CDI (JSR 346)
Only public forum
Chennai JUG
Hyderabad JUG
Indonesia JUG
LJC
Bean Validation (JSR 349) Only public forum
SouJava
Batch (JSR 352)
~750%
Chennai JUG
LJC, SouJava
JSON (JSR 353)
~650%
CE JUG
Congo JUG
LJC
Mbale JUG
Morocco JUG
Peru JUG
SouJava
Toronto JUG
WebSocket (JSR 356)
~400%
BeJUG
LJC
Chennai JUG
Morocco JUG
CEJUG
NY SIG

The map below shows geographical coordinates for different JUGs participating in the Adopt-a-JSR effort for Java EE 7:


View Java EE 7 Adopt-a-JSR Maps in a larger map

Specific contributions from Adopt-a-JSR effort:
  • London Java Community (LJC) organized a WebSocket and JSON Hack Day. The event was sold out within 2 hours and had 17 people on the waiting list. The event started with a presentation on explaining the APIs in Java API for WebSocket (JSR 353) and Java API for JSON Processing (JSR 353). The attendees designed a Market Ticker application. All the presentation material and source code was shared publicly. LJC also created projects (cdiex-palindrom-jsf and cdiex-datastore) to test CDI 1.1 specification.
  • Chennai JUG is building a multi-player game that can be played across the Internet. The application uses Java API for WebSocket 1.0 (JSR 356), Java API for JSON Processing 1.0 (JSR 353), Java Persistence API 2.1 (JSR 338), JavaServer Faces 2.2 (JSR 344) and Batch Applications for Java Platform (JSR 352) and/or Enterprise JavaBeans 3.2 (JSR 345) and so provide a holistic experience of building a Java EE 7 application. The energetic JUG meets regularly using G+ hangouts and in the neighborhood coffee shops to coordinate. And then they go hacking the application on github.  There are 5 developers that are regularly contributing to the application and the JUG plans to incorporate several other technologies as part of an ongoing effort.
  • Morocco JUG will be presenting on Java EE 7, WebSocket, and JSON at Java Developer Conference, Cairo, Egypt.
  • Cologne JUG had a meetup on about JSF 2.2 and another one on CDI 1.1 (video).
  • BeJUG has adopted JSR 356 have planned a hackathon on Mar 6th. They plan to build a cross-browser Tic-Tac-Toe application using JSR 356. One of the JUG members is on its way to become a committer in Tyrus - the Reference Implementation for JSR 356.
  • Ceara JUG has planned a set of presentations on Mar 9 by on JAX-RS 2.0 (JSR 339), Java API for JSON Processing (JSR 353), JavaServer Faces 2.2 (JSR 344), and Java API for WebSocket (JSR 356).
  • San Francisco JUG organized a Java EE 7 and WebSocket session and planning a session on JAX-RS 2.0.
  • SouJava is contributing by adding new features from JSF 2.2 to Scrum Toys.
Several other JUGs are doing an outstanding work and contributing towards making Java EE 7 as the best release ever. All these efforts truly indicate that Java EE 7 is getting grass roots participation from the global community. This truly allows early feedback on the specification and implementation from the end user and developers who will eventually use these APIs. Overall this leads to a higher quality deliverables and will hopefully eventually lead to a faster adoption as well.

Even though many of the JSRs have gone through Public Review Ballot and others are in progress, its never too late to contribute. So how do you contribute ? Just follow this three step process:
  • Join a JUG: If you do not participate in your local Java User Group, then find your local JUG and participate. There are several already active JUGs around the world. If one does not exist in your neighborhood, now is your time to shine as a leader and start one.
  • Participate in Adopt-a-JSR: Encourage JUG members to participate in the global Adopt-a-JSR effort. Several JUGs are already participating and contributing very effectively.
  • Share the joy: Pick any of the Java EE 7 JSRs that are particularly interesting, download GlassFish 4 promoted builds, read javadocs, build a sample application, provide feedback to the Expert Group, and share the joy!
Adopt-a-JSR for Java EE 7: Getting Started provide more details on how your JUGs can contribute effectively.

Java EE 7 JSRs are truly operating in a fully transparent manner and took community participation to a new level. We are always ready for feedback!

Tuesday Feb 26, 2013

WebSocket Java Client API in GlassFish 4 (TOTD #208)


The WebSocket API by W3C defines an API that enables Web pages to use the WebSocket protocol for two-way communication with a remote host. Java API for WebSocket (JSR 356) has added an ability to invoke a WebSocket endpoint from a Java application. This Tip Of The Day (TOTD) will explain how you can use that API for invoking a WebSocket endpoint.

JSR 356 introduces a class-level annotation @WebSocketClient that converts a POJO into a WebSocket client. The usual lifecycle annotations such as @WebSocketOpen, @WebSocketClose, @WebSocketError, and @WebSocketMessage can be specified on methods.

@WebSocketClient
public class MyClientEndpoint {
@WebSocketOpen
public void onOpen(Session session) {
System.out.println("Connected to endpoint: " + session.getRemote());
try {
String name = "Duke";
System.out.println("Sending message to endpoint: " + name);
session.getRemote().sendString(name);
} catch (IOException ex) {
Logger.getLogger(MyClientEndpoint.class.getName()).log(Level.SEVERE, null, ex);
}
}

@WebSocketMessage
public void processMessage(String message) {
System.out.println("Received message in client: " + message);
Client.messageLatch.countDown();
}
}
This code sends a message to the connected WebSocket endpoint from the onOpen method and prints the message when it comes back. This endpoint is bootstrapped using a separate class:

public class Client {

final static CountDownLatch messageLatch = new CountDownLatch(1);

public static void main(String[] args) {
try {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
String uri = "ws://echo.websocket.org:80/";
System.out.println("Connecting to " + uri);
container.connectToServer(MyClientEndpoint.class, URI.create(uri));
messageLatch.await(100, TimeUnit.SECONDS);
} catch (DeploymentException | InterruptedException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Note that a CountDownLatch is used to ensure that there is enough time for the client to connect to the endpoint. The latch counts down in MyClientEndpoint.processMessage once the echo message is received from the endpoint.

The source code can be downloaded here, connects to a remote WebSocket endpoint, and displays the output on the console.

The Maven dependency for now are specified as:
<dependencies>
<dependency>
<groupId>org.glassfish.tyrus</groupId>
<artifactId>tyrus-client</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.glassfish.tyrus</groupId>
<artifactId>tyrus-container-grizzly</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>

Hopefully these could be specified as javax dependencies only!

The latest specification draft and javadocs can be downloaded here. Share your feedback at users@websocket-spec.java.net (for the specification) or users@tyrus.java.net (for the implenentation).

Monday Feb 25, 2013

Chat Sever using WebSocket in GlassFish 4 (TOTD #207)


A canonical example of using WebSocket is a chat server. This Tip Of The Day (TOTD) will share the code for building exactly that!

The complete code in this TOTD is available here.

Here is the code for the Chat Server built as a WebSocket endpoint:

@WebSocketEndpoint("/websocket")
public class ChatEndpoint {
private static final Set<Session> peers = Collections.synchronizedSet(new HashSet<Session>());

@WebSocketOpen
public void onOpen(Session peer) {
peers.add(peer);
}

@WebSocketClose
public void onClose(Session peer) {
peers.remove(peer);
}

@WebSocketMessage
public void message(String message, Session client) throws IOException, EncodeException {
for (Session peer : peers) {
peer.getRemote().sendObject(message);
}
}
}

In this code:
  • Lifecycle callbacks manage the coordinates of the connecting clients
  • message method receives all the messages sent by the client and then transmits to all the connected clients.
Simple, isn't it ?

You can use a trivial JavaScript to exchange messages between two browsers. A chat session between two Chrome and Firefox is shown below:



Download the source code and run it in GlassFish 4 b77.

Tuesday Feb 19, 2013

JsonParser and JsonReader - Streaming and Object Readers in Java API for JSON Processing (TOTD #206)


JsonReader reads a JSON object or array from an input source. This provides DOM access to the JSON structure.

JsonParser provides forward, ready-only access to JSON data in a streaming way. The parser can be created from InputStream and Reader. A sample code looks like:

JsonParser jsonParser = Json.createParser(new StringReader(YOUR_STRING_HERE));

Here is a table with code fragments for parsing some common JSON using Object Model and events generated from Streaming API:

JSON Object Model API Events from Streaming API
{ }
JsonReader jsonReader =
    new JsonReader(new StringReader("{}"));
JsonObject json = jsonReader.readObject();
{START_OBJECT }END_OBJECT
{
  "apple":"red",
  "banana":"yellow"
}
jsonReader =
    new JsonReader(new StringReader(...));
json = jsonReader.readObject();

{START_OBJECT
  "apple"KEY_NAME:"red"VALUE_STRING,
  "banana"KEY_NAME:"yellow"VALUE_STRING
}
[
  { "apple":"red" },
  { "banana":"yellow" }
]
jsonReader =
    new JsonReader(new StringReader(...));
JsonArray jsonArr = jsonReader.readArray();

[START_ARRAY
  {START_OBJECT "apple"KEY_NAME:"red"VALUE_STRING }END_OBJECT,
  {START_OBJECT "banana"KEY_NAME:"yellow"VALUE_STRING }END_OBJECT
]END_ARRAY
{
  "title":"The Matrix",
  "year":1999,
  "cast":[
    "Keanu Reaves",
    "Laurence Fishburne",
    "Carrie-Anne Moss"
  ]
}
jsonReader =
    new JsonReader(new StringReader(...));
json = jsonReader.readObject();

{START_OBJECT
  "title"KEY_NAME:"The Matrix"VALUE_STRING,
  "year"KEY_NAME:1999VALUE_NUMBER,
  "cast"KEY_NAME:[START_ARRAY
    "Keanu Reaves"VALUE_STRING,
    "Laurence Fishburne"VALUE_STRING,
    "Carrie-Anne Moss"VALUE_STRING
  ]END_ARRAY
}END_OBJECT

The source code for this sample can be downloaded here, try it with GlassFish 4 b76 or later.

Note, GlassFish b76 has Public Review version of the APIs. But the APIs have evolved since then and an integration is planned in the next few days. So if you are using an older build, the sample code may not work. I'll update the sample code once the bits are integrated.

Here are some more links for you to read further:

Monday Feb 18, 2013

JsonGenerator and JsonObjectBuilder - Streaming and Object API in Java API for JSON Processing (TOTD #205)


Java API for JSON Processing (JSR 353) cleared Public Review unanimously and is on its way to to standardization. There is still Proposed Final Draft and the final vote to come. As per the Java EE 7 schedule, the specification will be final on 4/15/2013. The implementation is already integrated in GlassFish 4 builds.

The API provides an Object Model (like DOM for XML) and Streaming API (like StAX for XML) to parse and generate JSON structure. Here is a table that provide code fragments for generating some common JSON:

JSON Object Model API Streaming API
{ }
JsonObject jsonObject =
     new JsonObjectBuilder().build();

new JsonWriter(System.out)
     .writeObject(jsonObject);

JsonGeneratorFactory factory =
     Json.createGeneratorFactory();

JsonGenerator gen =
     factory.createGenerator(System.out);

gen.writeStartObject().writeEnd();
{
  "apple":"red",
  "banana":"yellow"
}
new JsonObjectBuilder()
  .add("apple", "red")
  .add("banana", "yellow")
.build();
gen.writeStartObject()
     .write("apple", "red")
     .write("banana", "yellow")
   .writeEnd();
[
  { "apple":"red" },
  { "banana":"yellow" }
]
JsonArray jsonArray = new JsonArrayBuilder()
  .add(new JsonObjectBuilder()
          .add("apple","red"))

  .add(new JsonObjectBuilder()
          .add("banana","yellow"))

  .build();
gen.writeStartArray()
     .writeStartObject()
       .write("apple", "red")
     .writeEnd()
     .writeStartObject()
       .write("banana", "yellow")
     .writeEnd()
.writeEnd();
{
  "title":"The Matrix",
  "year":1999,
  "cast":[
    "Keanu Reaves",
    "Laurence Fishburne",
    "Carrie-Anne Moss"
  ]
}
new new JsonObjectBuilder()
  .add("title", "The Matrix")
  .add("year", 1999)
  .add("cast", new JsonArrayBuilder()
  .add("Keanu Reaves")
  .add("Laurence Fishburne")
  .add("Carrie-Anne Moss"))
.build();
gen.writeStartObject()
     .write("title", "The Matrix")
     .write("year", 1999)
     .writeStartArray("cast")
       .write("Keanu Reaves")
       .write("Laurence Fishburne")
       .write("Carrie-Anne Moss")
     .writeEnd()
   .writeEnd();

The source code for this sample can be downloaded here, try it with GlassFish 4 b76 or later.

Here are some more links for you to read further:

Wednesday Feb 13, 2013

@WebSocketClient in GlassFish 4 (TOTD #204)


Tyrus is the Reference Implementation for Java API for WebSocket (JSR 356) and is already integrated in GlassFish 4. The implementation is rapidly evolving and and adding support for different features already defined in the latest version of the specification.

The latest integration in GlassFish added support for creating Java-based WebSocket clients.

Any POJO can be made a WebSocket client by adding @WebSocketClient. A inbound message is received in a method annotated with @WebSocketMessage. Any method can be designated as lifecycle method by specifying @WebSocketOpen, @WebSocketClose, @WebSocketError. Here is a simple sample:

@WebSocketClient
public class MyClient {
@WebSocketOpen
public void onOpen(Session session) {
System.out.println("Connected to endpoint: " + session.getRemote());
try {
session.getRemote().sendString("Duke");
} catch (IOException ex) {
Logger.getLogger(MyClient.class.getName()).log(Level.SEVERE, null, ex);
}
}

@WebSocketMessage
public void processMessage(String message, Session session) {
System.out.println(getClass().getName() + ": " + message);
}
}

In this code, a message is sent to the connected WebSocket endpoint whenever the connection is initiated. An inbound message (coming from the server) is processed using processMessage method.

The endpoint code is pretty trivial:

@WebSocketEndpoint(value="/websocket", configuration=DefaultServerConfiguration.class)
public class MyEndpoint {

@WebSocketMessage
public String sayHello(String name) {
System.out.println(getClass().getName() + ": " + name);
return "Hello " + name;
}

}
The endpoint has a single method that receives the payload, appends a string and returns back as the response. Even though server is returning the response right away, the client views this as two separate messages, one outbound and the other one inbound. So any message-exchange-pattern such as request/response need to be specifically built using the application code. The configuration attribute, in this case, is optional and will be fixed in a subsequent release of Tyrus.

The client can bootstrap using Java SE or Java EE components as:

WebSocketContainer container = ContainerProvider.getWebSocketContainer();
String uri = "ws://localhost:8080" + request.getContextPath() + "/websocket";
container.connectToServer(MyClient.class, URI.create(uri));
The complete source code used in this Tip Of The Day (TOTD) is available here. It will run on the latest checked out version of GlassFish workspace, not a promoted build yet (bleeding edge eh ;-)

Please provide feedback on users@tyrus.java.net.

How are you going to use Java-based WebSocket client in your applications ?

Here are other Java EE 7 entries published on this blog so far:


Monday Feb 11, 2013

Create ManagedExecutorService, ManagedScheduledExecutorService, ManagedThreadFactory, ContextService in GlassFish 4 build 74 (TOTD #203)


Latest GlassFish 4 promoted build (74 at this time) has the first cut of Concurrency Utilities for Java EE (JSR 236) implementation integrated. An earlier blog provided an overview of the specification, lets see what can be actually done with this build.

This build introduce new commands to create ManagedExecutorService, ManagedScheduledExecutorService, ManagedThreadFactory, and ContextService.

A simple command execution as:

asadmin create-managed-executor-service concurrent/myExecutor
Managed executor service concurrent/myExecutor created successfully.
Command create-managed-executor-service executed successfully.

creates the configuration for a default ManagedExecutorService. Adding --help shows more details about the command:

create-managed-executor-service
    [--enabled=true]
    [--contextinfo=contextinfo]
    [--threadpriority=5]
    [--longrunningtasks=false]
    [--hungafterseconds=hungafterseconds]
    [--corepoolsize=0]
    [--maximumpoolsize=2147483647]
    [--keepaliveseconds=60]
    [--threadlifetimeseconds=0]
    [--taskqueuecapacity=2147483647]
    [--description=description]
    [--property=property]
    [--target=target]
    jndi_name

The created executor can then be injected into a Java EE component (say Servlet) as:

@Resource(name = "concurrent/myExecutor")
ManagedExecutorService executor;

or looked up using JNDI as:

InitialContext ctx = new InitialContext();
ManagedExecutorService executor = (ManagedExecutorService) ctx.lookup("concurrent/myExecutor");

A task can be defined as:

public class MyRunnableTask implements Runnable {

private int id;

public MyRunnableTask(int id) {
this.id = id;
}

@Override
public void run() {
try {
System.out.format("%d (runnable): starting", id);
System.out.format("%d (runnable): sleeping 2 seconds", id);
Thread.sleep(2000);
System.out.format("%d (runnable): complete", id);
} catch (InterruptedException ex) {
Logger.getLogger(TestResourceServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

Task can be submitted as:

Future<?> f = executor.submit(new MyRunnableTask(1));

OR

executor.execute(new MyRunnableTask(2));

A task may also be defined as:

public class MyCallableTask implements Callable<Product> {

private int id;

public MyCallableTask(int id) {
this.id = id;
}

@Override
public Product call() {
try {
System.out.format("%d (callable): starting", id);
System.out.format("%d (callable): sleeping 2 seconds", id);
Thread.sleep(2000);
System.out.format("%d (callable): complete", id);
} catch (InterruptedException ex) {
Logger.getLogger(TestResourceServlet.class.getName()).log(Level.SEVERE, null, ex);
}
return new Product(id);
}
}

where Product is a domain-specific class. In this case, the task is submited for execution as:

Future<Product> f2 = executor.submit(new MyCallableTask(3));
A ManagedScheduledExecutorService can be created as:

asadmin create-managed-scheduled-executor-service concurrent/myScheduledExecutor
Managed scheduled executor service concurrent/myScheduledExecutor created successfully.
Command create-managed-scheduled-executor-service executed successfully.

A ManagedThreadFactory can be created as:

asadmin create-managed-thread-factory concurrent/myThreadFactory
Managed thread factory concurrent/myThreadFactory created successfully.
Command create-managed-thread-factory executed successfully.

A ContextService can be created as:

asadmin create-context-service concurrent/myContextService
Context service concurrent/myContextService created successfully.
Command create-context-service executed successfully.

Note, this is the first integration and some of the options may not work. But you can definitely start playing around with basic stuff now.

The complete source code used in this Tip Of The Day (TOTD) is available here and will run on GlassFish 4 b74.

Friday Feb 08, 2013

Resource Library Contracts in JSF2.2 (TOTD #202)


JavaServer Faces 2 introduced Facelets as the default View Declaration Language. Facelets allows to create templates using XHTML and CSS that can be then used to provide a consistent look-and-feel across different pages of an application. JSF 2.2 defines Resource Library Contracts that allow facelet templates to be applied to an entire application in a reusable and interchangeable manner.

This Tip Of The Day (TOTD) will explain how you can leverage them in your web application.

The complete source code for this sample can be downloaded here. This will run on GlassFish build 72 + latest JSF 2.2.0 SNAPSHOT copied over "glassfish3/glassfish/modules/javax.faces.jar" file.

Consider the following WAR file:
index.xhtml
user/index.xhtml
contracts/blue/layout.css
contracts/blue/template.xhtml
contracts/red
contracts/red/layout.css
contracts/red/template.xhtml
WEB-INF/faces-config.xml

The application also has two pages - "index.xhtml" and "user/index.xhtml". All contracts reside in the "contracts" directory of the WAR. All templates and resources for a contract are in their own directory. For example, the structure above has two defined contracts "blue" and "red". Each contract has a "template.xhtml" and a CSS. Each template is called as "declared template". The "template.xhtml" has <ui:insert> tags called as "declared insertion points". CSS and other resources bundled in the directory are "declared resources". The "declared template", "declared insertion points", and "declared resources" together make the definition of the resource library contract. A template client needs to know the value of all three in order to use the contract.

In our case, templates have similar "ui:insert" sections and template clients will accordingly have "ui:define" sections. The difference will primarily be in the CSS. "index.xhtml" will refer to the template as:

<ui:composition template="/template.xhtml">
<ui:define name="content">
. . .
</ui:define>
</ui:composition>

The usage of the contracts is defined in "faces-config.xml" as:

<application>
<resource-library-contracts>
<contract-mapping>
<url-pattern>/user/*</url-pattern>
<contracts>blue</contracts>
</contract-mapping>
<contract-mapping>
<url-pattern>*</url-pattern>
<contracts>red</contracts>
</contract-mapping>
</resource-library-contracts>
</application>
A contract is applied based upon the URL pattern invoked. Based upon the configuration specified here, "red" contract will be applied to "faces/index.xhtml" and "red" contract will be applied to "faces/user/index.xhtml".

The template of the page can be changed dynamically as well. For example consider "index.xhtml" is updated as:

<f:view contracts="#{contractsBean.contract}">
<ui:composition template="/template.xhtml">

<ui:define name="content">
<a href="#{facesContext.externalContext.requestContextPath}/faces/user/index.xhtml">Go to</a> other contract
<p/>
Look at WEB-INF/faces-config.xml for contract configuration.
<p/><p/>
Choose a template:<br/>
<h:form>
<h:selectOneRadio value="#{contractsBean.contract}" layout="pageDirection" required="true">
<f:selectItem itemValue="red" itemLabel="red"/>
<f:selectItem itemValue="blue" itemLabel="blue"/>
</h:selectOneRadio>
<h:commandButton value="Apply" action="index" />
</h:form>
</ui:define>

</ui:composition>
</f:view>
The "ui:composition" is included in "f:view". An additional "contracts" attribute can bind to an EL. The value of this EL is populated from the radio button in the newly added form. Now you can choose a radio button, click on the "Apply" button and the new template will be applied to the page. The bean is very trivial:

@Named
@SessionScoped
public class ContractsBean implements Serializable {

String contract = "red";

public String getContract() {
return contract;
}

public void setContract(String contract) {
this.contract = contract;
}
}

This is a very powerful feature. Imagine providing different look-and-feel for your website and letting the user choose them, fun eh ?

Contracts may be packaged as a JAR file. Such a JAR file maybe bundled in "WEB-INF/lib" directory. Read section 2.7 for more details about the packaging requirement and a marker file that identifies the JAR to contain a contract.

In the specification ...
  • Section 10.1.3 provide background on the feature.
  • Section 2.7 provide formal definition of the feature.
  • Section 11.4.2.1 defines how the contracts are identified during application startup.
Create templates as JAR files and reuse them across different applications, enjoy!

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:

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
« February 2013 »
SunMonTueWedThuFriSat
     
2
3
4
5
6
9
10
12
14
15
16
17
20
21
22
23
24
  
       
Today