java ee 7, what's in it for me?

44
Java EE 7, what’s in it for me Alex Soto - @alexsotob

Upload: alex-soto

Post on 09-Aug-2015

630 views

Category:

Technology


5 download

TRANSCRIPT

Java EE 7, what’s in it for me

Alex Soto - @alexsotob

Alex Soto!@alexsotob - [email protected]

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 Utilitiespublic 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 ProcessingJsonArray 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!