The Java EE 7 Platform: Simplicity, Productivity and HTML 5

Sivakumar Thyagarajan Oracle India



Disclaimer

The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.



Java EE 6 Platform December 10, 2009



Java EE 6 – Key Statistics

40+ Million Java EE 6 Component Downloads #1 Choice for Enterprise Developers #1 Application Development Platform Fastest implementation of a Java EE release



Top Ten Features in Java EE 6

1. EJB packaging in a WAR 2. Type-safe dependency injection 3. Optional deployment descriptors

(web.xml, faces-config.xml) 4. JSF standardizing on Facelets 5. One class per EJB 6. Servlet and CDI extension points 7. CDI Events 8. EJBContainer API 9. Cron-based @Schedule 10. Web Profile



Java EE 7 Revised Scope

Productivity and HTML5

• Higher Productivity

– Less Boilerplate – Richer Functionality – More Defaults

• HTML5 Support

– WebSocket – JSON – HTML5 Forms



Common Annotations 1.1

Connector 1.7

Portable Extension s

Managed Beans 1.0

Java EE 7 – Candidate JSRs

New

Major Release

JSP 2.2

JPA 2.1

Interceptors 1.1

Updated

JSF 2.2

Servlet 3.1

JTA 1.2

JAX-RS 2.0

EJB 3.2

CDI 1.1

JMS 2.0

EL 3.0

B

e

a

n

V

a

l

i

d

a

t

i

o

n

1

.

1

Java API for WebSocket (JSR 356)

Concurrency Utilities (JSR 236)

Batch Applications (JSR 352)

Java API for JSON (JSR 353)

Java Caching API (JSR 107)



Java API for RESTful Web Services 2.0

• Client API

• Message Filters & Entity Interceptors

• Asynchronous Processing – Server & Client

• Hypermedia Support

• Common Configuration



Java API for RESTful Web Services 2.0

Client API - Before

String address = String.format("http://.../orders/%0$s/customer?shipped=%1$b", "10", true);

URL url = new URL(address); 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) {

//. . . }



Java API for RESTful Web Services 2.0

Client API - Now

// Get instance of Client Client client = ClientFactory.newClient();

// Get customer name for the shipped products String name = client.target(“../orders/{orderId}/customer”)

.resolveTemplate(”orderId", ”10”) .queryParam(”shipped", ”true”) .request() .get(String.class);



Java API for RESTful Web Services 2.0

Filters

@Provider class LoggingFilter implements ContainerRequestFilter {

@Override public void filter(ContainerRequestContext context) {

logRequest(ctx.getRequest()); // non-wrapping => returns without invoking next filter } }



Java API for RESTful Web Services 2.0

Client-side Async

Client client = ClientFactory.newClient(); Future<String> future = client.target("http://.../atm/{card}/balance")

.pathParam("card", "1111222233334444") .queryParam("pin", "1234") .request("text/plain") .async() .get(

new InvocationCallback<String>() {

public void completed(String result) { }

public void failed(InvocationException e) { } } );



Java Message Service 2.0

Simplify the existing API

• Less verbose

• Reduce boilerplate code

• Resource injection

• Connection, Session, and other objects are AutoCloseable

• Requires Resource Adapter for Java EE containers

• Simplified API in both Java SE and EE



Java Message Service 2.0 Sending message using JMS 1.1

@Resource(lookup = "java:global/jms/demoConnectionFactory") ConnectionFactory connectionFactory;

@Resource(lookup = "java:global/jms/demoQueue") Queue demoQueue;

public void sendMessage(String payload) {

try {

Connection connection = connectionFactory.createConnection(); try {

Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(demoQueue); TextMessage textMessage = session.createTextMessage(payload); messageProducer.send(textMessage); } finally {

connection.close(); } } catch (JMSException ex) {

Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); } }

13 lines of code just to send a message



Java Message Service 2.0

Sending message using JMS 1.1

@Resource(lookup = "java:global/jms/demoConnectionFactory") ConnectionFactory connectionFactory;

@Resource(lookup = "java:global/jms/demoQueue") Queue demoQueue;

public void sendMessage(String payload) {

try {

Connection connection = connectionFactory.createConnection(); try {

Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(demoQueue); TextMessage textMessage = session.createTextMessage(payload); messageProducer.send(textMessage); } finally {

connection.close(); } } catch (JMSException ex) {

Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); } }

must create several intermediate objects



Java Message Service 2.0

Sending message using JMS 1.1

@Resource(lookup = "java:global/jms/demoConnectionFactory") ConnectionFactory connectionFactory;

@Resource(lookup = "java:global/jms/demoQueue") Queue demoQueue;

public void sendMessage(String payload) {

try {

Connection connection = connectionFactory.createConnection(); try {

Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(demoQueue); TextMessage textMessage = session.createTextMessage(payload); messageProducer.send(textMessage); } finally {

connection.close(); } } catch (JMSException ex) {

Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); } }

redundant and misleading arguments



Java Message Service 2.0 Sending message using JMS 1.1

@Resource(lookup = "java:global/jms/demoConnectionFactory") ConnectionFactory connectionFactory;

@Resource(lookup = "java:global/jms/demoQueue") Queue demoQueue;

public void sendMessage(String payload) {

try {

Connection connection = connectionFactory.createConnection(); try {

Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(demoQueue); TextMessage textMessage = session.createTextMessage(payload); messageProducer.send(textMessage); } finally {

connection.close(); } } catch (JMSException ex) {

Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); } }

boilerplate code



Java Message Service 2.0 Sending message using JMS 1.1

@Resource(lookup = "java:global/jms/demoConnectionFactory") ConnectionFactory connectionFactory;

@Resource(lookup = "java:global/jms/demoQueue") Queue demoQueue;

public void sendMessage(String payload) {

try {

Connection connection = connectionFactory.createConnection(); try {

Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(demoQueue); TextMessage textMessage = session.createTextMessage(payload); messageProducer.send(textMessage); } finally {

connection.close(); } } catch (JMSException ex) {

Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); } }

must close resources after use!



Java Message Service 2.0 Sending message using JMS 1.1

@Resource(lookup = "java:global/jms/demoConnectionFactory") ConnectionFactory connectionFactory;

@Resource(lookup = "java:global/jms/demoQueue") Queue demoQueue;

public void sendMessage(String payload) {

try {

Connection connection = connectionFactory.createConnection(); try {

Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(demoQueue); TextMessage textMessage = session.createTextMessage(payload); messageProducer.send(textMessage); } finally {

connection.close(); } } catch (JMSException ex) {

Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); } }

all methods throw checked exceptions



Java Message Service 2.0

Sending message using JMS 1.1

@Resource(lookup = "java:global/jms/demoConnectionFactory") ConnectionFactory connectionFactory;

@Resource(lookup = "java:global/jms/demoQueue") Queue demoQueue;

public void sendMessage(String payload) {

try {

Connection connection = connectionFactory.createConnection(); try {

Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(demoQueue); TextMessage textMessage = session.createTextMessage(payload); messageProducer.send(textMessage); } finally {

connection.close(); } } catch (JMSException ex) {

Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex); } }

pre-create app- server specific resources



Java Message Service 2.0 Simpler API to close JMS objects

@Resource(lookup = "jms/connFactory") ConnectionFactory cf; @Resource(lookup="jms/inboundQueue") Destination dest;

public void sendMessage (String payload) throws JMSException {

try ( Connection conn = connectionFactory.createConnection();

Session session = conn.createSession(); MessageProducer producer = session.createProducer(dest); ){

Message mess = sess.createTextMessage(payload); producer.send(mess); } catch(JMSException e){ // exception handling } }

Create closeable resources in a try- with-resources block

close() is called automatically at end of block



Java Message Service 2.0 Introducing JMSContext and JMSProducer

@Resource(lookup = "java:global/jms/demoConnectionFactory") ConnectionFactory connectionFactory;

@Resource(lookup = "java:global/jms/demoQueue") Queue demoQueue;

public void sendMessage (String payload) {

try (JMSContext context = connectionFactory.createContext();){

context.createProducer().send(demoQueue, payload); } catch (JMSRuntimeException ex) {

// exception handling } }

JMSContext combines Connection and Session

Payload can be sent directly

No checked exceptions thrown

close() is called automatically at end of block



Java Message Service 2.0

@Inject JMSContext context;

@Resource(lookup = "java:global/jms/demoQueue”) Queue demoQueue;

public void sendMessage(String payload) {

context.createProducer().send(demoQueue, payload); } Default resource definition

Default resource definition Or @JmsConnectionFactory

13 lines →1 line



Java API for JSON Processing 1.0

• API to parse and generate JSON

• Streaming API

– Low-level, efficient way to parse/generate JSON – Provides pluggability for parsers/generators

• Object Model

– Simple, easy-to-use high-level API – Implemented on top of Streaming API

• Binding JSON to Java objects forthcoming



Java API for JSON Processing 1.0

Streaming API – JsonParser and JsonGenerator

• JsonParser

• Parses JSON in a streaming way from input sources

• Similar to StaX’s XMLStreamReader, a pull parser

• Created using

• Json.createParser(...)

• Json.createParserFactory().createParser(...)

• Parser state events

• START_ARRAY, END_ARRAY, START_OBJECT, END_OBJECT, ...



Java API for JSON Processing 1.0

Streaming API – JsonParser and JsonGenerator

• JsonGenerator

• Generates JSON in a streaming way to output sources

• Similar to StaX’s XMLStreamWriter

• Created using

• Json.createGenerator(...)

• Json.createGeneratorFactory().createGenerator(...)

• Optionally, configured with features

• E.g. for pretty printing



Java API for JSON Processing 1.0

Streaming API – JsonGenerator

"phoneNumber": [

{

"type": "home", "number": ”408-123-4567” }, {

"type": ”work", "number": ”408-987-6543” } ]

JsonGenerator jg = Json.createGenerator(...);

jg.

.beginArray("phoneNumber")

.beginObject()

.add("type", "home") .add("number", "408-123-4567") .endObject() .beginObject()

.add("type", ”work") .add("number", "408-987-6543") .endObject() .endArray(); jg.close();



Java API for JSON Processing 1.0

Object Model API

• JsonObject/JsonArray – JSON object and array structures

• JsonString and JsonNumber for string and number values

• JsonBuilder – Builds JsonObject and JsonArray

• JsonReader – Reads JsonObject and JsonArray from input source

• JsonWriter – Writes JsonObject and JsonArray to output source



Java API for JSON Processing 1.0

DOM API – JsonReader

• Reads JsonObject and JsonArray from input source

– I/O Reader, InputStream (+ encoding)

• Optionally, configured with features

• Uses pluggable JsonParser

// Reads a JSON object try(JsonReader reader = new JsonReader(io)) {

JsonObject obj = reader.readObject(); }



Java API for WebSocket 1.0

• Create WebSocket Client/Endpoints

• Annotation-driven (@WebSocketEndpoint)

• Interface-driven (Endpoint)

• Integration with Java EE Web container



Java API for WebSocket 1.0

Hello World – POJO/Annotation-driven

import javax.net.websocket.annotations.*;

@WebSocketEndpoint("/hello") public class HelloBean {

@WebSocketMessage public String sayHello(String name) {

return “Hello “ + name; } }



Java API for WebSocket 1.0

WebSocket Annotations

Annotation Level Purpose

@WebSocketEndpoint class Turns a POJO into a WebSocket Endpoint

@WebSocketOpen method Intercepts WebSocket Open events

@WebSocketClose method Intercepts WebSocket Close events

@WebSocketMessage method Intercepts WebSocket Message events

@WebSocketPathParam

method parameter

Flags a matched path segment of a URI-template

@WebSocketError method Intercepts errors during a conversation



Java API for WebSocket 1.0

@WebSocketEndpoint Attributes

value

Relative URI or URI template e.g. “/hello” or “/chat/{subscriber-level}”

decoders list of message decoder classnames

encoders list of message encoder classnames

subprotocols list of the names of the supported subprotocols



Bean Validation 1.1

Open: Spec, Reference Implementation, TCK Alignment with Dependency Injection Method-level validation

Constraints on parameters and return values Check pre-/post-conditions



Bean Validation 1.1 Method Parameter and Result Validation

Built-in

Custom

public void placeOrder(

@NotNull String productName, @NotNull @Max(“10”) Integer quantity, @Customer String customer) {

//. . . }

@Future public Date getAppointment() {

//. . . }



Batch Applications for the Java Platform 1.0

• Suited for non-interactive, bulk-oriented and long- running tasks

• Computationally intensive

• Can execute sequentially/parallel

• May be initiated

• Adhoc

• Scheduled

• No scheduling APIs included



Batch Applications for the Java Platform 1.0

Concepts

• Job: Entire batch process

– Put together through a Job Specification Language (XML)

• Step: Independent, sequential phase of a job

– ItemReader: Retrieval of input for a step, one at a time – ItemProcessor: Business processing of an item – ItemWriter: Output of an item, chunks of items at a time

• JobOperator: Manage batch processing

• JobRepository: Metadata for jobs



Batch Applications for the Java Platform 1.0

Job Specification Language – Simple Job

<job id=“myJob”> <step id=“init”>

<chunk reader=“R” writer=W” processor=“P” /> <next on=“initialized” to=“process”/> <fail on=“initError”/> </step> <step id=“process”>

<batchlet ref=“ProcessAndEmail”/>

<end on=”success”/> <fail on=”*” exit-status=“FAILURE”/> </step> </job>



Java Temporary Caching API 1.0

• API and semantics for temporary, in-memory caching of Java objects

• SPI for implementers

• Designed to support “local” and “distributed” caching

• Caching strategies supported

By value (default) By reference (not suitable for “distributed” caching)



Java Temporary Caching API 1.0

• javax.cache.*

• Delivered as part of Java EE 7

• Immediately usable by Java EE 6, Spring and Guice

• Immediately usable by any Java app

• Not a Data Grid specification

• JSR 107 does not mandate a topology

• JSR 347 does: builds on JSR 107



Java Temporary Caching API 1.0

Key Concepts

Cache Manager =>Caches Cache => Entries Entry => Key,Value

• CacheManager acquired via CacheManagerFactory

• CacheManagerFactory acquired via Service Provider

META-INF/services/javax.cache.spi.CachingProvider



Java Temporary Caching API 1.0

Code Sample – Blog

public class BlogManager {

@CachePut(cacheName=”blogManager”) public void createEntry(

@CacheKeyParam String title, @CacheValue Blog blog) {...}

. . .



Java Temporary Caching API 1.0

Code Sample – Blog

. . .

@CacheResult(cacheName="blogManager") public Blog getBlogEntry(String title) {...}

@CacheResult(cacheName="blogManager") public Blog getEntryCached(

String randomArg, @CacheKeyParam String title) {...}

. . .



Java Temporary Caching API 1.0

Annotations – Blog Sample

. . .

@CacheRemoveEntry(cacheName="blogManager") public void removeBlogEntry(String title) {...}

@CacheRemoveAll(cacheName="blogManager") public void removeAllBlogs() {...} }



Java Persistence API 2.1

Schema Generation Unsynchronized Persistence Contexts Converters Bulk update/delete using Criteria User-defined functions using FUNCTION Stored Procedure Query



Enterprise JavaBeans 3.2

EJBs Today

• @Singleton

• @Asynchronous

• @Schedule

• Portable JNDI Name

• EJBContainer.createEJBContainer

• EJB 3.1 Lite



Enterprise JavaBeans 3.2

Updates: Opt-out passivation of Stateful Session Beans

@Stateful(passivationCapable=false) public class HelloBean {

private NonSerializableType ref = ...;

... }



Enterprise JavaBeans 3.2

Updates: Simplified Rules for Local/Remote Client Views

@Stateless public class Bean implements Foo, Bar { }

@Local @Stateless public class Bean implements Foo, Bar { }

@Remote @Stateless public class Bean implements Foo, Bar { }

Local

Remote



Enterprise JavaBeans 3.2

Updates: Simplified Rules for Local/Remote Client Views

@Remote public interface Foo { . . . }

public interface Bar { . . . ]

Remote

@Stateless public class Bean implements Foo, Bar { }



Servlet 3.1

Non-blocking I/O Protocol Upgrade Security Enhancements



Servlet 3.1

Non-blocking IO - Traditional

public class TestServlet extends HttpServlet

protected void doGet(HttpServletRequest request,

HttpServletResponse response) throws IOException, ServletException { ServletInputStream input = request.getInputStream(); byte[] b = new byte[1024]; int len = -1; while ((len = input.read(b)) != -1) {

. . . } } }



Servlet 3.1

Non-blocking I/O: doGet Code Sample

AsyncContext context = request.startAsync(); ServletInputStream input = request.getInputStream(); input.setReadListener(

new MyReadListener(input, context));



Servlet 3.1

Non-blocking I/O: MyReadListener Code Sample

@Override public void onDataAvailable() {

try {

StringBuilder sb = new StringBuilder(); int len = -1; byte b[] = new byte[1024]; while (input.isReady() && (len = input.read(b)) != -1) {

String data = new String(b, 0, len); System.out.println("--> " + data); } } catch (IOException ex) {

. . . } } . . .



Servlet 3.1

Non-blocking I/O: MyListener Code Sample

. . . @Override public void onAllDataRead() {

context.complete(); }

@Override public void onError(Throwable t) {

t.printStackTrace(); context.complete(); }



Concurrency Utilities for Java EE 1.0

Goals

• Provide concurrency capabilities to Java EE application components

• Without compromising container integrity

• Support simple (common) and advanced concurrency patterns

• Provide consistency between Java SE and Java EE concurrency programming model

• Extend the Concurrency Utilities API (JSR 166)



Concurrency Utilities for Java EE 1.0

ManagedExecutorService

• Manageable version of java.util.concurrent.ExecutorService

• Lookup using JNDI

• Java EE components create task classes

• Implement java.lang.Runnable or java.util.concurrent.Callable

• Submitted using submit or invoke methods

• Multiple (configurable) executors are permitted



Concurrency Utilities for Java EE 1.0

Defining ManagedExecutorService using JNDI

• Recommended to bind in java:comp/env/concurrent subcontext <resource-env-ref>

<resource-env-ref-name>

concurrent/BatchExecutor </resource-env-ref-name> <resource-env-ref-type>

javax.enterprise.concurrent.ManagedExecutorService </resource-env-ref-type> </resource-env-ref>



Concurrency Utilities for Java EE 1.0

Submit Tasks to ManagedExecutorService using JNDI

public class TestServlet extends HTTPServlet {

@Resource(name=“concurrent/BatchExecutor”) ManagedExecutorService executor;

Future future = executor.submit(new MyTask());

class MyTask implements Runnable {

public void run() { . . . // task logic } } }



Java Transaction API 1.2

• Declarative transactions outside EJB

• Based on CDI interceptors

• Adds annotation and standard values to javax.transaction package



Java Transaction API 1.2

public @interface Transactional {

TxType value() default TxType.REQUIRED } public enum TxType {

REQUIRED, REQUIRED_NEW, MANDATORY, SUPPORTS, NOT_SUPPORTED, NEVER }



Java Transaction API 1.2

public class ShoppingCart {

... @Transactional public void checkOut() {...} ... }



JavaServer Faces 2.2

HTML5 Friendly Markup Support

Pass through attributes and elements Faces Flows Cross Site Request Forgery Protection Loading Facelets via ResourceHandler File Upload Component Multi-templating



Contexts & Dependency Injection 1.1

Embedded mode to startup outside Java EE container Global ordering of interceptors and decorators API for managing built-in contexts Send Servlet events as CDI events . . .



Java EE 7 – Implementation Status

4.0

http://download.java.net/glassfish/4.0/promoted/



Java EE 8 and Beyond Standards-based cloud programming model

• Deliver cloud architecture

• Multi tenancy for SaaS applications

• Incremental delivery of JSRs

• Modularity based on Jigsaw

NoSQL Storage JSON-B

Multitenancy

Concurrency

Java EE 7

Cloud

PaaS Enablement

Thin Server Architecture



Call to Action

• Java EE 7 Expert Group

– javaee-spec.java.net

• Java EE 7 Reference Implementation

– glassfish.org

• The Aquarium

– blogs.oracle.com/theaquarium

• Adopt-a-JSR

– glassfish.org/adoptajsr



Transparency

• Oracle’s Java EE 7 JSRs are run in the open on java.net

• http://javaee-spec.java.net

• One project per spec – e.g., jpa-spec, jax-rs-spec, jms-spec, connector-spec ...

• Publicly viewable Expert Group mail archive

• Users observer list gets copies of all Expert Group emails

• Publicly viewable download area

• Publicly viewable issue tracker

• Commitment to update to JCP 2.8 Process



Status and Schedule

• All JSRs up and running

• All Early Drafts, and several Public Drafts

• Final release target: Q2 2013



GlassFish v3

• Java EE 6 support

• Single instance

• GlassFish Enterprise Mgr

2009

GlassFish Roadmap

GlassFish Server 3.0.1

• Oracle branding

• Oracle platform support

• Oracle interoperability

2010

GlassFish Server 3.1

• Centralized administration

• Clustering / HA

• GlassFish Server Control

GlassFish Server 3.1.1

• Bug fixes

• Updated components

• Incremental features

2011

2012

GlassFish Server 3.1.2

• Bug Fixes

• Incremental features

GlassFish Server 4

• Java EE 7

• Multitenancy

• PaaS-enablement

2013



The Java EE 7 Platform: Simplicity, Productivity and HTML 5

Sivakumar Thyagarajan Oracle India