Java EE 7, what’s in it
for me
Alex Soto - @alexsotob
Alex Soto!
@alexsotob - asotobu@gmail.com
Member of
Scytl Architect Software Engineer
lordofthejars.com
Apache Tomcat!
Apache TomEE
Questions?
Ask them right away!
New Specifications
• Websockets
• Batch Applications
• Concurrency Utilities
• JSON Processing
Improvements
• Simplified JMS API
• Default Resources
• JAX-RS Client API
• EJB’s External Transactions
• CDI Annotations
• Entity Graphs
Java EE 7 JSRs
Websockets
• Supports Client and Server
• Declarative and Programmatic
Websockets Chat Server
@ServerEndpoint("/chatWebSocket")!
public class ChatWebSocket {!
private static final Set<Session> sessions = Collections.synchronizedSet(new HashSet<Session>());!
!
@OnOpen!
public void onOpen(Session session) {sessions.add(session);}!
!
@OnMessage!
public void onMessage(String message) {!
for (Session session : sessions) { session.getAsyncRemote().sendText(message);}!
}!
!
@OnClose!
public void onClose(Session session) {sessions.remove(session);}!
}
Websockets Chat Client
@ClientEndpoint!
public class ChatClientEndpoint {!
public static String TEXT = "Client1 joins";!
public static CountDownLatch latch;!
public static String response;!
!
@OnOpen!
public void onOpen(Session session) {!
session.getBasicRemote().sendText(TEXT);!
}!
!
@OnMessage!
public void processMessage(String message) {!
response = message;!
latch.countDown();!
}!
}
CDI
• Finer Scanning Control
• More Annotations
CDI
<beans!
xmlns="http://xmlns.jcp.org/xml/ns/javaee"!
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"!
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee !
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"!
bean-discovery-mode="all">!
</beans>
CDI
@Vetoed,@Transactional, @TransactionScoped
@RequestScoped!
public class MyTransactionalTxTypeBean {!
@Transactional(Transactional.TxType.REQUIRED)!
public void required() {!
System.out.println(getClass().getName() + "Transactional.TxType.REQUIRED");!
}!
}
Bean Validation
• Design By Contract
• CDI integration
Bean Validation
@Future!
public Date showDate(boolean correct) {!
Calendar cal = Calendar.getInstance();!
cal.add(Calendar.DAY_OF_MONTH, correct ? 5 : -5);!
return cal.getTime();!
}!
!
public String showList(@NotNull @Size(min = 1, max = 3) List<String> list, @NotNull String prefix) {!
StringBuilder builder = new StringBuilder();!
!
for (String s : list) {!
builder.append(prefix).append(s).append(" ");!
}!
!
return builder.toString();!
}
Batch Applications
• For long, non-interactive processes
• Either sequential or parallel (partitions)
• Task or Chunk oriented processing
Batch Applications
Batch Applications - job.xml
<job id="myJob" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">!
<step id="myStep" >!
<chunk item-count="3">!
<reader ref="myItemReader"/>!
<processor ref="myItemProcessor"/>!
<writer ref="myItemWriter"/>!
</chunk>! !
</step>!
</job>
Concurrency Utilities
• Asynchronous capabilities to the Java EE world
• Java SE Concurrency API extension (Executor
Service, Scheduled Executor, ThreadFactory)
• Safe and propagates context
Concurrency Utilities
public class TestServlet extends HttpServlet {!
@Resource(name = "concurrent/MyExecutorService")!
ManagedExecutorService executor;!
!
Future future = executor.submit(new MyTask());!
!
class MyTask implements Runnable {!
public void run() {!
! ! ! // do something!
}!
}!
}
JSON Processing
• Read, generate and transform JSON
• Streaming API and Object Model API
JSON Processing
JsonArray jsonArray = Json.createArrayBuilder()!
.add(Json.createObjectBuilder()!
.add("name", “Jack"))!
.add("age", "30"))!
.add(Json.createObjectBuilder()!
.add("name", “Mary"))!
.add("age", "45"))!
.build();!
!
[ {“name”:”Jack”, “age”:”30”}, !
{“name”:”Mary”, “age”:”45”} ]
JMS
• New interface JMSContext
• Modern API with Dependency Injection
• Resources AutoCloseable
• Simplified how to send messages
• Programmatic definition
JMS
@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);!
}!
}
JMS
@Inject!
private JMSContext context;!
!
@Resource(mappedName = "jms/inboundQueue")!
private Queue inboundQueue;!
!
public void sendMessage (String payload) {!
context.createProducer()!
.setPriority(1)!
.setTimeToLive(1000)!
.setDeliveryMode(NON_PERSISTENT)!
.send(inboundQueue, payload);!
}
JMS
String body=null;!
try (JMSContext context = connectionFactory.createContext();){!
JMSConsumer consumer = session.createConsumer(queue);!
body = consumer.receiveBody(String.class);!
} catch (JMSRuntimeException ex) {!
// handle exception (details omitted)!
}!
return body;
JMS
!
@JMSDestinationDefinition(!
name = Resources.REQUEST_QUEUE,!
resourceAdapter = "jmsra",!
interfaceName = "javax.jms.Queue",!
destinationName = "requestQueue",!
description = "Queue for service requests")!
public class Resources {!
public static final String REQUEST_QUEUE = "java:global/jms/
requestQueue";!
}
JAX-RS
• New API to consume REST services
• Asynchronous processing (client and server)
• Filters and Interceptors
JAX-RS
String movie = ClientBuilder.newClient()!
.target("http://www.movies.com/movie")!
.request(MediaType.TEXT_PLAIN)!
.get(String.class);
JAX-RS
@GET!
public void getList(@Suspended final AsyncResponse ar) throws NamingException {!
ar.setTimeoutHandler(new TimeoutHandler() );!
!
ar.register(new MyCompletionCallback());!
ar.register(new MyConnectionCallback());!
!
Executors.newSingleThreadExecutor(threadFactory).submit(new Runnable() {!
!
@Override!
public void run() {!
Thread.sleep(3000);!
ar.resume(response[0]);!
}!
});!
}!
JAX-RS
Future<Response> r1 = ClientBuilder.newClient()!
.target("http://www.movies.com/movie")!
! ! ! ! ! ! ! ! .request().async().get();
JAX-RS
• ClientRequestFilter
• ClientResponseFilter
• ContainerRequestFilter
• ContainerResponseFilter
• ReaderInterceptor (Entity Interceptor)
• WriterInterceptor (Entity Interceptor)
JPA
• Schema generation
• Stored Procedures
• Entity Graphs
• Unsynchronized Persistence Context
JPA
<persistence-unit name="myPU" transaction-type="JTA">!
<properties>!
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>!
<property name="javax.persistence.schema-generation.create-source" value="script"/>!
<property name="javax.persistence.schema-generation.drop-source" value="script"/>!
<property name="javax.persistence.schema-generation.create-script-source" value="META-INF/
create.sql"/>!
<property name="javax.persistence.schema-generation.drop-script-source" value="META-INF/
drop.sql"/>!
<property name="javax.persistence.sql-load-script-source" value="META-INF/load.sql"/>!
</properties>!
</persistence-unit>
JPA
@Entity!
@NamedStoredProcedureQuery(name="top10MoviesProcedure",!
procedureName = "top10Movies")!
public class Movie {}!
!
StoredProcedureQuery query = entityManager.createNamedStoredProcedureQuery(!
"top10MoviesProcedure");!
query.registerStoredProcedureParameter(1, String.class, ParameterMode.INOUT);!
query.setParameter(1, "top10");!
query.registerStoredProcedureParameter(2, Integer.class, ParameterMode.IN);!
query.setParameter(2, 100);!
query.execute();!
query.getOutputParameterValue(1);
JPA@Entity!
@NamedQueries({!
@NamedQuery(name = "Movie.findAll", query = "SELECT m FROM Movie m")!
})!
@NamedEntityGraphs({!
@NamedEntityGraph(!
name = "movieWithActors",!
attributeNodes = {!
@NamedAttributeNode("movieActors")!
}!
)!
public class Movie implements Serializable {!
!
@OneToMany!
@JoinColumn(name = "ID")!
private Set<MovieActor> movieActors;!
}
JPA
public List<Movie> listMovies(String hint, String graphName) {!
return entityManager.createNamedQuery("Movie.findAll")!
.setHint("javax.persistence.fetchgraph", entityManager.getEntityGraph(graphName))!
.getResultList();!
}
JSF
• HTML 5 support
• @FlowScoped and @ViewScoped
• File Upload component
• Flow Navigation by Convention
• Resource Library Contracts
Others
• Servlet: Non-blocking I/O, Security
• Default JMS Queue/Topic, DataSource, Concurrent
pool
• Mail Session definition: @MailSessionDefinition
• Interceptors: @Priority, @AroundConstruct
• EJB: Passivation opcional, EJB-Lite with
@Asynchronous and @Schedule
• EL: Lambdas, isolated API
Certified Servers
• Glassfish 4.0
• Wildfly 8.0.0
• TMAX JEUS 8
• Websphere Liberty Profile 9
• TomEE 7 on progress
Java EE 8
• Alignment with Java 8
• JCache
• JSON-B
• MVC
• HTTP 2.0 Support
• Cloud Support
• Security
How to get involved
• Join an expert group
• https://javaee-spec.java.net
• Adopt a JSR
• https://glassfish.java.net/adoptajsr/
Materials
• Tutorial Java EE 7 - http://docs.oracle.com/javaee/7/
tutorial/doc/home.htm
• Samples Java EE 7 - https://github.com/javaee-
samples/javaee7-samples
• Batch Sample - WoW Auctions - https://github.com/
radcortez/wow-auctions
• WebSocket Sample - Chat Server - https://
github.com/radcortez/cbrjug-websockets-chat
Thank you!

Java EE 7, what's in it for me?

  • 1.
    Java EE 7,what’s in it for me Alex Soto - @alexsotob
  • 2.
    Alex Soto! @alexsotob -asotobu@gmail.com Member of Scytl Architect Software Engineer lordofthejars.com Apache Tomcat! Apache TomEE
  • 3.
  • 5.
    New Specifications • Websockets •Batch Applications • Concurrency Utilities • JSON Processing
  • 6.
    Improvements • Simplified JMSAPI • Default Resources • JAX-RS Client API • EJB’s External Transactions • CDI Annotations • Entity Graphs
  • 7.
  • 8.
    Websockets • Supports Clientand Server • Declarative and Programmatic
  • 9.
    Websockets Chat Server @ServerEndpoint("/chatWebSocket")! publicclass ChatWebSocket {! private static final Set<Session> sessions = Collections.synchronizedSet(new HashSet<Session>());! ! @OnOpen! public void onOpen(Session session) {sessions.add(session);}! ! @OnMessage! public void onMessage(String message) {! for (Session session : sessions) { session.getAsyncRemote().sendText(message);}! }! ! @OnClose! public void onClose(Session session) {sessions.remove(session);}! }
  • 10.
    Websockets Chat Client @ClientEndpoint! publicclass ChatClientEndpoint {! public static String TEXT = "Client1 joins";! public static CountDownLatch latch;! public static String response;! ! @OnOpen! public void onOpen(Session session) {! session.getBasicRemote().sendText(TEXT);! }! ! @OnMessage! public void processMessage(String message) {! response = message;! latch.countDown();! }! }
  • 11.
    CDI • Finer ScanningControl • More Annotations
  • 12.
  • 13.
    CDI @Vetoed,@Transactional, @TransactionScoped @RequestScoped! public classMyTransactionalTxTypeBean {! @Transactional(Transactional.TxType.REQUIRED)! public void required() {! System.out.println(getClass().getName() + "Transactional.TxType.REQUIRED");! }! }
  • 14.
    Bean Validation • DesignBy Contract • CDI integration
  • 15.
    Bean Validation @Future! public DateshowDate(boolean correct) {! Calendar cal = Calendar.getInstance();! cal.add(Calendar.DAY_OF_MONTH, correct ? 5 : -5);! return cal.getTime();! }! ! public String showList(@NotNull @Size(min = 1, max = 3) List<String> list, @NotNull String prefix) {! StringBuilder builder = new StringBuilder();! ! for (String s : list) {! builder.append(prefix).append(s).append(" ");! }! ! return builder.toString();! }
  • 16.
    Batch Applications • Forlong, non-interactive processes • Either sequential or parallel (partitions) • Task or Chunk oriented processing
  • 17.
  • 18.
    Batch Applications -job.xml <job id="myJob" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">! <step id="myStep" >! <chunk item-count="3">! <reader ref="myItemReader"/>! <processor ref="myItemProcessor"/>! <writer ref="myItemWriter"/>! </chunk>! ! </step>! </job>
  • 19.
    Concurrency Utilities • Asynchronouscapabilities to the Java EE world • Java SE Concurrency API extension (Executor Service, Scheduled Executor, ThreadFactory) • Safe and propagates context
  • 20.
    Concurrency Utilities public classTestServlet extends HttpServlet {! @Resource(name = "concurrent/MyExecutorService")! ManagedExecutorService executor;! ! Future future = executor.submit(new MyTask());! ! class MyTask implements Runnable {! public void run() {! ! ! ! // do something! }! }! }
  • 21.
    JSON Processing • Read,generate and transform JSON • Streaming API and Object Model API
  • 22.
    JSON Processing JsonArray jsonArray= Json.createArrayBuilder()! .add(Json.createObjectBuilder()! .add("name", “Jack"))! .add("age", "30"))! .add(Json.createObjectBuilder()! .add("name", “Mary"))! .add("age", "45"))! .build();! ! [ {“name”:”Jack”, “age”:”30”}, ! {“name”:”Mary”, “age”:”45”} ]
  • 23.
    JMS • New interfaceJMSContext • Modern API with Dependency Injection • Resources AutoCloseable • Simplified how to send messages • Programmatic definition
  • 24.
    JMS @Resource(lookup = "java:global/jms/demoConnectionFactory")! ConnectionFactoryconnectionFactory;! @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);! }! }
  • 25.
    JMS @Inject! private JMSContext context;! ! @Resource(mappedName= "jms/inboundQueue")! private Queue inboundQueue;! ! public void sendMessage (String payload) {! context.createProducer()! .setPriority(1)! .setTimeToLive(1000)! .setDeliveryMode(NON_PERSISTENT)! .send(inboundQueue, payload);! }
  • 26.
    JMS String body=null;! try (JMSContextcontext = connectionFactory.createContext();){! JMSConsumer consumer = session.createConsumer(queue);! body = consumer.receiveBody(String.class);! } catch (JMSRuntimeException ex) {! // handle exception (details omitted)! }! return body;
  • 27.
    JMS ! @JMSDestinationDefinition(! name = Resources.REQUEST_QUEUE,! resourceAdapter= "jmsra",! interfaceName = "javax.jms.Queue",! destinationName = "requestQueue",! description = "Queue for service requests")! public class Resources {! public static final String REQUEST_QUEUE = "java:global/jms/ requestQueue";! }
  • 28.
    JAX-RS • New APIto consume REST services • Asynchronous processing (client and server) • Filters and Interceptors
  • 29.
    JAX-RS String movie =ClientBuilder.newClient()! .target("http://www.movies.com/movie")! .request(MediaType.TEXT_PLAIN)! .get(String.class);
  • 30.
    JAX-RS @GET! public void getList(@Suspendedfinal AsyncResponse ar) throws NamingException {! ar.setTimeoutHandler(new TimeoutHandler() );! ! ar.register(new MyCompletionCallback());! ar.register(new MyConnectionCallback());! ! Executors.newSingleThreadExecutor(threadFactory).submit(new Runnable() {! ! @Override! public void run() {! Thread.sleep(3000);! ar.resume(response[0]);! }! });! }!
  • 31.
    JAX-RS Future<Response> r1 =ClientBuilder.newClient()! .target("http://www.movies.com/movie")! ! ! ! ! ! ! ! ! .request().async().get();
  • 32.
    JAX-RS • ClientRequestFilter • ClientResponseFilter •ContainerRequestFilter • ContainerResponseFilter • ReaderInterceptor (Entity Interceptor) • WriterInterceptor (Entity Interceptor)
  • 33.
    JPA • Schema generation •Stored Procedures • Entity Graphs • Unsynchronized Persistence Context
  • 34.
    JPA <persistence-unit name="myPU" transaction-type="JTA">! <properties>! <propertyname="javax.persistence.schema-generation.database.action" value="drop-and-create"/>! <property name="javax.persistence.schema-generation.create-source" value="script"/>! <property name="javax.persistence.schema-generation.drop-source" value="script"/>! <property name="javax.persistence.schema-generation.create-script-source" value="META-INF/ create.sql"/>! <property name="javax.persistence.schema-generation.drop-script-source" value="META-INF/ drop.sql"/>! <property name="javax.persistence.sql-load-script-source" value="META-INF/load.sql"/>! </properties>! </persistence-unit>
  • 35.
    JPA @Entity! @NamedStoredProcedureQuery(name="top10MoviesProcedure",! procedureName = "top10Movies")! publicclass Movie {}! ! StoredProcedureQuery query = entityManager.createNamedStoredProcedureQuery(! "top10MoviesProcedure");! query.registerStoredProcedureParameter(1, String.class, ParameterMode.INOUT);! query.setParameter(1, "top10");! query.registerStoredProcedureParameter(2, Integer.class, ParameterMode.IN);! query.setParameter(2, 100);! query.execute();! query.getOutputParameterValue(1);
  • 36.
    JPA@Entity! @NamedQueries({! @NamedQuery(name = "Movie.findAll",query = "SELECT m FROM Movie m")! })! @NamedEntityGraphs({! @NamedEntityGraph(! name = "movieWithActors",! attributeNodes = {! @NamedAttributeNode("movieActors")! }! )! public class Movie implements Serializable {! ! @OneToMany! @JoinColumn(name = "ID")! private Set<MovieActor> movieActors;! }
  • 37.
    JPA public List<Movie> listMovies(Stringhint, String graphName) {! return entityManager.createNamedQuery("Movie.findAll")! .setHint("javax.persistence.fetchgraph", entityManager.getEntityGraph(graphName))! .getResultList();! }
  • 38.
    JSF • HTML 5support • @FlowScoped and @ViewScoped • File Upload component • Flow Navigation by Convention • Resource Library Contracts
  • 39.
    Others • Servlet: Non-blockingI/O, Security • Default JMS Queue/Topic, DataSource, Concurrent pool • Mail Session definition: @MailSessionDefinition • Interceptors: @Priority, @AroundConstruct • EJB: Passivation opcional, EJB-Lite with @Asynchronous and @Schedule • EL: Lambdas, isolated API
  • 40.
    Certified Servers • Glassfish4.0 • Wildfly 8.0.0 • TMAX JEUS 8 • Websphere Liberty Profile 9 • TomEE 7 on progress
  • 41.
    Java EE 8 •Alignment with Java 8 • JCache • JSON-B • MVC • HTTP 2.0 Support • Cloud Support • Security
  • 42.
    How to getinvolved • Join an expert group • https://javaee-spec.java.net • Adopt a JSR • https://glassfish.java.net/adoptajsr/
  • 43.
    Materials • Tutorial JavaEE 7 - http://docs.oracle.com/javaee/7/ tutorial/doc/home.htm • Samples Java EE 7 - https://github.com/javaee- samples/javaee7-samples • Batch Sample - WoW Auctions - https://github.com/ radcortez/wow-auctions • WebSocket Sample - Chat Server - https:// github.com/radcortez/cbrjug-websockets-chat
  • 44.