Wednesday Apr 17, 2013

Suggestions for Java EE and Cloud Track at JavaOne 2013: CFP ends Apr 23




JavaOne Call for Papers has been extended and now will close on April 23. There are eight tracks to submit your talks:
  • Client and Embedded Development with JavaFX
  • Core Java Platform
  • Edge Computing with Java in Embedded, Smart Card, and IoT applications
  • Emerging Languages and the Java Virtual Machine
  • Securing Java
  • Java Development Tools and Techniques
  • Java EE Web Profile and Platform Technologies
  • Java Web Services and the Cloud

A complete description of each track is provided here. Five different kind of sessions can be submitted for each track:

  • Conference Session: A 60-minute session presented by Oracle, customers, partners, developers, and/or user group members
  • Panel: A 60-minute session presented in a panel format by multiple speakers consisting of Oracle, customers, partners, developers, and/or user group members
  • Tutorials: A 2 hour speaker led session where the presenter literally show attendees a live "How to" tutorial, and attendees can ask questions to the presenter during this. It doesn't require the attendee to have any equipment whatsoever. Ideally, the attendee should be listening and taking notes.
  • Birds of a Feather (BOFs): A  60-minute session that allows a closer interaction with the speakers and attendees focusing on a particular aspect of technology.
  • Hands-on Lab (HOL): A two-hour hands-on, interactive lab session
We've seen a good response to paper submission so far and really thankful for that!

You've a few more days to submit your talks. As a track co-lead for Java EE and Cloud tracks, here are some talks that I'd like to see there:
  • Anything related to WebSocket, JSON, Concurrency, Batch, HTML5, Persistence, Dependency Injection, Transactions ?
  • Do you have a creative use of Java EE technologies in your applications ?
  • Are you an extreme believer in Java EE and use most of the components for creating world-class applications ?
  • Are you using multiple application servers in your deployment environment ?
  • Do you have any experience of migrating from earlier versions of J2EE to Java EE ? Tutorials here would be nice.
  • Do you want to show value of standards-based application development over proprietary frameworks ?
  • Are you building support for Java EE 7 in your applications already ?
  • Performance, monitoring, testing, development, deployment strategies ?
  • Any other enterprise Java technologies from the ecosystem ?
  • Real case studies on how Java EE helped you deliver on time, within budget, and stay competitive
And now some suggestions for the Cloud track:
  • How are your Java services powering web and cloud ?
  • Anything related to REST/SOAP Web services and design patterns ?
  • How is Service Oriented Architecture (SOA) helping you realize the benefits ?
  • Do you have an interesting deployment topology across your private and public cloud ?
  • Do you have a case study showing why a particular deployment scenario works ?
  • Are you exposing services at IaaS, PaaS, and SaaS layers and share guidelines on them ?
  • How are you simplifying DevOps ?
  • How are you using BigData in development and deployment ?
  • Anything related to NoSQL ? Using a mix of NoSQL and RDBMS ?
Keep the job of Content Review Committe interesting, demanding, and challenging. Submit as many sessions as you can before April 23rd 11:50pm PT.

Read the content review process and tips for submission from 2 years ago to improve your chances of getting a paper selected.

Submit now!

Thursday Apr 04, 2013

WebSocket Client and Server Endpoint: Annotated and Programmatic (TOTD #212)


JSR 356 defines Java API for WebSocket 1.0. It defines a standard-based programming model for creating WebSocket client and server endpoint. Both kind of endpoints can be created programmatically or using annotations. This Tip Of The Day (TOTD) provide short snippets of how to write a WebSocket client and server endpoint programmatically or using annotations.

The complete source code in this sample can be downloaded from here.

Lets start with annotation-based server endpoint.

@ServerEndpoint("/websocket")
public class MyEndpoint {
   
  @OnMessage
  public String echoText(String name) {
    return name;
  }
}

@ServerEndpoint marks the POJO as a WebSocket server endpoint. URI of the deployed endpoint is as value attribute of the annotation.  echoText method is invoked whenever a message with text payload is received by this endpoint. Payload of the message is mapped to the parameter name. A synchronous response is returned to the client using the return value.

Programmatic server endpoint can be defined as:

public class MyEndpoint extends Endpoint {

  @Override
  public void onOpen(final Session session, EndpointConfig ec) {
    session.addMessageHandler(new MessageHandler.Whole<String>() {

      @Override
      public void onMessage(String text) {
        try {
          session.getBasicRemote().sendText(text);
        } catch (IOException ex) {
          Logger.getLogger(MyEndpoint.class.getName()).log(Level.SEVERE, null, ex);
        }
      }
  });
}

A programmatic server endpoint is defined by extending Endpoint abstract class. onOpen method is overridden to be notified of when a new conversation has started. Session captures the other end of the conversation. EndpointConfig identifies the configuration object used to configure this endpoint. Multiple MessageHandlers are registered to handle text, binary, and pong messages. The first parameter of onOpen captures the other end of the conversation. A synchronous response to the client is sent by calling getBasicRemote().sendText(...) method.

Programmatic server endpoint needs to be configured using ServerApplicationConfig.

public class MyApplicationConfig implements ServerApplicationConfig {

  @Override
  public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> set) {
    return new HashSet<ServerEndpointConfig>() {
      {
        add(ServerEndpointConfig.Builder
            .create(MyEndpoint.class, "/websocket")
            .build());
      }
    };
  }

  @Override
  public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> set) {
    return Collections.emptySet();
  }
}

WebSocket runtime scans the WAR file with all implementations of ServerApplicationConfig and registers the endpoint returned from getEndpointConfigs and getAnnotatedEndpointClasses. The URI of the server endpoint is published using ServerEndpointConfig.Builder.

Now lets take a look at annotated client endpoint.

@ClientEndpoint
public class MyClient {
  @OnOpen
  public void onOpen(Session session) {
    try {
      String name = "Duke";
      System.out.println("Sending message to endpoint: " + name);
      session.getBasicRemote().sendText(name);
    } catch (IOException ex) {
      Logger.getLogger(MyClient.class.getName()).log(Level.SEVERE, null, ex);
    }
  }
}

@ClientEndpoint marks the POJO as a WebSocket client endpoint. onOpen method is invoked whenever a new WebSocket connection is opened and is identified by @OnOpen annotation. Session captures the other end of the conversation. A synchronous message is sent to the server using session.getBasicRemote.sendText() method.

This client can connect to the endpoint as:

WebSocketContainer container = ContainerProvider.getWebSocketContainer();
String uri = "ws://localhost:8080" + request.getContextPath() + "/websocket";
container.connectToServer(MyClient.class, URI.create(uri));

And finally programmatic client endpoint.

public class MyClient extends Endpoint {
  @Override
  public void onOpen(final Session session, EndpointConfig ec) {
    session.addMessageHandler(new MessageHandler.Whole<String>() {

      @Override
      public void onMessage(String text) {
        System.out.println("Received response in client from endpoint: " + text);
      }
  });
  try {
    String name = "Duke";
      System.out.println("Sending message from client -> endpoint: " + name);
      session.getBasicRemote().sendText(name);
    } catch (IOException ex) {
      Logger.getLogger(MyClient.class.getName()).log(Level.SEVERE, null, ex);
    }
  }
}


The first parameter of onOpen captures the other end of the conversation.  EndpointConfig identifies the configuration object used to configure this endpoint. Multiple MessageHandlers are registered to handle text, binary, and pong messages. onMessage method is called whenever a message is received from the endpoint. A synchronous request to the server is sent by calling getBasicRemote().sendText(...) method.

This client can connect to the endpoint as:

WebSocketContainer container = ContainerProvider.getWebSocketContainer();
String uri = "ws://localhost:8080" + request.getContextPath() + "/websocket";
container.connectToServer(MyClient.class,
                null,
                URI.create(uri));

Now go download your GlassFish b82, samples source code, and run them.


Wednesday Mar 06, 2013

Chunked Step using Batch Applications in Java EE 7: Getting Started with GlassFish 4 (TOTD #211)


TOTD #192 explained the key concepts of JSR 352. This Tip Of The Day provides a working example of a how to write a simple chunk step using JSR 352 Reference Implementation integrated in GlassFish 4.

The source code for this sample application can be downloaded from here and works on GlassFish 4 b78.

As explained in TOTD #192, JSR 352 defines item-oriented processing using chunk step and task-oriented processing using batchlet step. A chunk consists of a reader that reads one item at a time, a processor that processes one item at a time, and a writer that aggregates 'chunk' number of items and then writes them out.

Here is an implementation of reader:

@Named
public class MyItemReader extends AbstractItemReader<MyInputRecord> {
   
    private final StringTokenizer tokens;
   
    public MyItemReader() {
        tokens = new StringTokenizer("1,2,3,4,5,6,7,8,9,10", ",");
    }
   
    @Override
    public MyInputRecord readItem() {
        if (tokens.hasMoreTokens()) {
            return new MyInputRecord(Integer.valueOf(tokens.nextToken()));
        }
        return null;
    }
}

Reader uses type information to specify the type of record that it is working on, MyInputRecord in this case. The readItem method returns null to indicate the end of items that can be read. In this case, a StringTokenizer is used to read the items but you can use an InputStream here if you like.

Here is an implementation of processor:

@Named
public class MyItemProcessor implements ItemProcessor<MyInputRecord,MyOutputRecord> {

    @Override
    public MyOutputRecord processItem(MyInputRecord t) {
        System.out.println("processItem: " + t);
       
        return (t.getId() % 2 == 0) ? null : new MyOutputRecord(t.getId() * 2);
    }
}

Processor uses type information to specify the type of input and output records its working on, MyInputRecord is the input record and MyOutputRecord is the output record in this case. The processItem method reads the input record and accepts only odd-numbered records. This is where your business logic would be implemented.

And here is an implementation of writer:

@Named
public class MyItemWriter extends AbstractItemWriter<MyOutputRecord> {

    @Override
    public void writeItems(List<MyOutputRecord> list) {
        System.out.println("writeItems: " + list);
    }
}

Writer uses type information as well to specify the type of output record, MyOutputRecord in this case. All these elements are tied together using "Job XML" as shown:

<job id="myJob" xmlns="http://batch.jsr352/jsl">
    <step id="myStep" >
        <chunk item-count="3">
            <reader ref="myItemReader"></reader>
            <processor ref="myItemProcessor"></processor>
            <writer ref="myItemWriter"></writer>
        </chunk>   
    </step>
</job>


Eventually, the references myItemReader, myItemProcessor, and myItemWriter will be resolved using CDI. But for now, the references can be explicitly resolved using "batch.xml" as shown:

<batch-artifacts xmlns="http://jcp.org.batch/jsl">
    <ref id="myItemReader" class="org.glassfish.chunk.simple.MyItemReader"/>
    <ref id="myItemProcessor" class="org.glassfish.chunk.simple.MyItemProcessor"/>
    <ref id="myItemWriter" class="org.glassfish.chunk.simple.MyItemWriter"/>
</batch-artifacts>


Once again, downloaded the source code from here and get it running on GlassFish 4 b78.

Post feedback on public@jbatch.java.net or users@glassfish.java.net.


Monday Mar 04, 2013

Consuming and Producing JSON using JAX-RS Entity Providers and JSR 353 Streaming API (TOTD# 210)


TOTD #193 explained how JAX-RS Entity Providers can be used to provide mapping between on-the-wire representations and their associated Java types. This blog shows how you can use Java API for JSON Processing (JSR 353), already integrated in GlassFish 4 promoted builds, to produce and consume JSON payload using Entity Providers.

The source code in this blog can be downloaded here and runs on GlassFish b76.

Lets say your domain object is defined as:

public class MyObject {

  private String name;
  private int age;

  //. . .
}

And your resource endpoint is defined as:

@Path("endpoint")
public class MyResource {
  @POST
  @Consumes(MediaType.APPLICATION_JSON)
  public MyObject echoObject(MyObject mo) {
    return mo;
  }
}

This is just echoing the domain object but I suspect your domain logic would be more complex than that ;-)

Using JAX-RS Client API, this endpoint can be invoked as:

WebTarget target = client.target(".../endpoint");
MyObject mo = target
               .request()
               .post(
                 Entity.entity(new MyObject("Duke", 18), MediaType.APPLICATION_JSON),
                 MyObject.class);
System.out.println("Received response: " + mo.getName() + ", " + mo.getAge() + "<br><br>");

The MessageBodyWriter.writeTo method, that writes MyObject to the underlying OutputStream, uses Streaming API from JSR 353 and looks like:

@Override
public void writeTo(MyObject t,
                    Class<?> type,
                    Type type1,
                    Annotation[] antns,
                    MediaType mt,
                    MultivaluedMap<String, Object> mm,
                    OutputStream out)
            throws IOException, WebApplicationException {
  JsonGeneratorFactory factory = Json.createGeneratorFactory();
  JsonGenerator gen = factory.createGenerator(out);
  gen.writeStartObject()
     .write("name", t.getName())
     .write("age", t.getAge())
     .writeEnd();
  gen.flush();
}

Similarly MessageBodyReader.readFrom method, that reads MyObject from the underlying InputStream, uses Streaming API from JSR 353 and looks like:

@Override
public MyObject readFrom(Class<MyObject> type,
                         Type type1,
                         Annotation[] antns,
                         MediaType mt,
                         MultivaluedMap<String, String> mm,
                         InputStream in)
                throws IOException, WebApplicationException {
  MyObject mo = new MyObject();
  JsonParser parser = Json.createParser(in);
  while (parser.hasNext()) {
    switch (parser.next()) {
      case KEY_NAME:
        String key = parser.getString();
        parser.next();
        switch (key) {
          case "name":
            mo.setName(parser.getString());
            break;
          case "age":
            mo.setAge(parser.getIntValue());
            break;
          default:
            break;
        }
        break;
      default:
        break;
    }
  }
  return mo;
}

The code is pretty straight forward and refer to Java API for JSON Processing javadocs if you need help in understanding the code.

Download the source code and enjoy!

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 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.

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