JEE.next()

Post on 25-May-2015

1.038 views 2 download

Tags:

description

What's new in JEE7

Transcript of JEE.next()

JEE.next()Kuba Marchwicki

@kubem

Gdańsk, 26.09.2013

Perfection is achieved, not when there is nothing more to add,

but when there is nothing left to take away.

Antoine de Saint-Exupery

J2EE 1.2

Servlet, JSP, EJB, JMS,

RMI

1999

J2EE 1.3

CMP, Connector

Architecture

2001

J2EE 1.4

Web Services,

Deployment, Async

Connector

2003

JEE 5

PrunningEJB 3.0, JPA, JSF, JAXB,

JAX-WS, StAX

2006

Web profile

Servlet 3.0EJB 3.1 Lite

2009

Web profile

JAX-RS 2.0

2013

JEE 6

PrunningCDI,

JAX-RS

JEE 7

PrunningJMS 2.0,Batch, JSON,

Web sockets

Servlet 3.0

JSF 2.0

EJB 3.1

JPA 2.0

JSP

CDI

JTA

Bean Validation

JAX-WS

JAX-RPC

JAXR

SAAJ

JAX-RS

JAXB

JMS

JAAS

JASPIC

JACC

JCA

JavaMail

JSR 88

JSR 77

RMI

JNDI

Web profile

Full profile

Java EE6 profiles

JSP 2.2 JSF 2.2 JAX-RS 2.0 EL 3.0

Servlet 3.1

Port

able

ex

tens

ions

CDI 1.1 Interceptors 1.1 Common Annotations 1.1

Managed Beans 1.0 EJB 3.2

Connector 1.6 JPA 2.1 JTA 1.2 JMS 2.0

Bean

Val

idati

on 1

.1

Concurrency Utilities (JSR 236)

Batch Applications (JSR 352)

Java API for JSON(JSR 353)

Java API for Websockets(JSR 356)

Java EE7

JSP 2.2 JSF 2.2 JAX-RS 2.0 EL 3.0

Servlet 3.1

Port

able

ex

tens

ions

CDI 1.1 Interceptors 1.1 Common Annotations 1.1

Managed Beans 1.0 EJB 3.2

Connector 1.6 JPA 2.1 JTA 1.2 JMS 2.0

Bean

Val

idati

on 1

.1

Concurrency Utilities (JSR 236)

Batch Applications (JSR 352)

Java API for JSON(JSR 353)

Java API for Websockets(JSR 356)

Java EE7 deep dive

Java EE7 deep dive

• JMS 2.0• JPA 2.1• Bean Validation 1.1• JAX-RS 2.0• Java API for JSON• Java API for Websockets• Batch Application• Concurrency Utilities

Before we start

<dependency><groupId>javax</groupId><artifactId>javaee-api</artifactId><version>7.0</version><scope>provided</scope>

</dependency>

Java EE7 deep dive

• JMS 2.0• JPA 2.1• Bean Validation 1.1• JAX-RS 2.0• Java API for JSON• Java API for Websockets• Batch Application• Concurrency Utilities

JMS 2.0

Configuration - Old API

??

JMS 2.0

Configuration - Old API

<subsystem xmlns="urn:jboss:domain:messaging:1.1"> <hornetq-server> <jms-destinations> <jms-queue name="testQueue"> <entry name="queue/test"/> </jms-queue> <jms-topic name="testTopic"> <entry name="topic/test"/> </jms-topic> </jms-destinations> </hornetq-server></subsystem>

JMS 2.0

Configuration – New API

@JMSConnectionFactoryDefinition(name = "java:global/jms/demoConnectionFactory", className = "javax.jms.ConnectionFactory")

@JMSDestinationDefinition(name = "java:global/jms/demoQueue", interfaceName = "javax.jms.Queue", destinationName = "demoQueue")

public class JmsConfiguration {

}

JMS 2.0

Send message – Old API@Statelesspublic class SendMessageService { @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 {//...

JMS 2.0

Send message – New API@Statelesspublic class MessageService {

@Injectprivate JMSContext context;@Resource(mappedName = "jms/inboundQueue")private Queue inboundQueue;

public void sendMessage(String payload) {context.createProducer().send(inboundQueue, payload);

}

}

JMS 2.0

Receive message – New API@MessageDriven(mappedName="global/jms/demoQueue")public class MessageConsumer implements MessageListener {

@Overridepublic void onMessage(Message msg) {

try {//No casting!!!String payload = msg.getBody(String.class);

} catch (JMSException e) {e.printStackTrace();

}

}

}

Java EE7 deep dive

• JMS 2.0• JPA 2.1• Bean Validation 1.1• JAX-RS 2.0• Java API for JSON• Java API for Websockets• Batch Application• Concurrency Utilities

JPA 2.1

Old API - persistence.xml<persistence-unit> <properties> <property name="hibernate.connection.driver_class"

value="org.apache.derby.jdbc.ClientDriver" /> <property name="hibernate.connection.url"

value="jdbc:derby://localhost:1527/sample;create=true" /> <property name="hibernate.connection.username" value="user" /> <property name="hibernate.connection.password" value="pass" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.use_sql_comments" value="true" /> <property name="hibernate.dialect"

value="org.hibernate.dialect.MySQL5Dialect" /> <property name="hibernate.hbm2ddl.auto" value="create-drop" /> </properties></persistence-unit>

JPA 2.1

Old API - persistence.xml<persistence-unit> <properties> <property name="eclipselink.jdbc.driver"

value="org.apache.derby.jdbc.ClientDriver" /> <property name="eclipselink.jdbc.url"

value="jdbc:derby://localhost:1527/sample;create=true" /> <property name="eclipselink.jdbc.user" value="user" /> <property name="eclipselink.jdbc.password" value="pass" /> <property name="eclipselink.logging.level" value="FINE" /> <property name="eclipselink.target-database"

value="org.eclipse.persistence.platform.database.MySQLPlatform" /> <property name="eclipselink.ddl-generation"

value="drop-and-create-tables" /> <property name="eclipselink.ddl-generation.output-mode"

value="database" /> </properties></persistence-unit>

JPA 2.1

New API - persistence.xml<persistence-unit> <properties> <property name="javax.persistence.jdbc.driver"

value="org.apache.derby.jdbc.ClientDriver" /> <property name="javax.persistence.jdbc.url"

value="jdbc:derby://localhost:1527/sample;create=true" /> <property name="javax.persistence.jdbc.user" value="user" /> <property name="javax.persistence.jdbc.password" value="pass" /> <property name="javax.persistence.schema-generation.database.action"

value="drop-and-create" />

<property name="eclipselink.logging.level" value="FINE" /> <property name="eclipselink.target-database"

value="org.eclipse.persistence.platform.database.MySQLPlatform" /> </properties></persistence-unit>

JPA 2.1

Old API – Converterspublic enum UseSex {

MALE, FEMALE;}

@Entitypublic class User {

@Idprivate long id;

@Enumerated(EnumType.ORDINAL)private UserSex sex;

//..}

JPA 2.1

Old API – Converterspublic enum UseSex {

MALE, FEMALE;}

@Entitypublic class User {

@Idprivate long id;

@Enumerated(EnumType.STRING)private UserSex sex;

//..}

JPA 2.1

Old API – Converters@Entitypublic class User {

@Transientprivate UserSex sex;

private String db_sex;

@PostLoadpublic void afterLoad() {

switch(db_sex){case "M": sex = UserSex.MALE;case "F": sex = UserSex.FEMALE;default: throw new IllegalArgumentException();}

}

JPA 2.1

Old API – Converters

@PrePersistpublic void beforePersit() {

switch(sex){case MALE: db_sex = "M";case FEMALE: db_sex = "F";default: throw new IllegalArgumentException();

}}

JPA 2.1

New API@Entitypublic class User {

@Idprivate long id;

@Convert(converter = SexConverter.class)private UserSex sex;

//..}

JPA 2.1

New API@Converterpublic class SexConverter implements AttributeConverter<UserSex, String>{

public String convertToDatabaseColumn(UserSex arg0) {switch(arg0){

case MALE: return "M";case FEMALE: return "F";default: throw new IllegalArgumentException();

}}public UserSex convertToEntityAttribute(String arg0) {

switch(arg0){case "M": return UserSex.MALE;case "F": return UserSex.FEMALE;default: throw new IllegalArgumentException();

}}

}

JPA 2.1

New API – stored procedures @Table(indexes = @Index(columnList = "name"))@Entity@NamedQuery(name = User.FIND_USER_BY_NAME,

query = "from User u where name = ?")@NamedStoredProcedureQuery(name = User. REFRESH_USERS,

procedureName = "USR_STRD_PRCR_CALL")public class User {

public final static String FIND_USER_BY_NAME = "User.findByName";public final static String REFRESH_USERS = "User.doSomething";

//..

}

Java EE7 deep dive

• JMS 2.0• JPA 2.1• Bean Validation 1.1• JAX-RS 2.0• Java API for JSON• Java API for Websockets• Batch Application• Concurrency Utilities

Bean Validation 1.1

Old API

@Interceptors(ValidationInterceptor.class)public void addAuthor(@Size(min=5) String name,

String surename) {Author a = new Author();a.setName(name);a.setSurename(surename);

em.persist(a);}

Bean Validation 1.1

Old API

public Object validateMethodInvocation(InvocationContext ctx) throws Exception {

MethodValidator validator = validatorFactory.getValidator().unwrap(MethodValidator.class);

Set<MethodConstraintViolation<Object>> violations = validator.validateAllParameters(

ctx.getTarget(), ctx.getMethod(), ctx.getParameters());

}

Bean Validation 1.1

New API

public void addAuthor(@Size(min=5) String name, String surename) {

Author a = new Author();a.setName(name);a.setSurename(surename);

em.persist(a);}

Bean Validation 1.1

New API@Path("/hello")public class HelloWorld {

@Path("/{name}")@GET@Produces(MediaType.APPLICATION_JSON)public JsonObject sayHello(

@NotEmpty @PathParam("name") String name) {//..

}}

Java EE7 deep dive

• JMS 2.0• JPA 2.1• Bean Validation 1.1• JAX-RS 2.0• Java API for JSON• Java API for Websockets• Batch Application• Concurrency Utilities

JAX-RS 2.0

Configuration - Old API

??

JAX-RS 2.0

Configuration - Old API

<servlet> <servlet-name>JAX-RS Servlet</servlet-name> <servlet-class> com.sun.jersey.spi.container.servlet.ServletContainer </servlet-class> <load-on-startup>1</load-on-startup></servlet><servlet-mapping> <servlet-name>JAX-RS Servlet</servlet-name> <url-pattern>/jax-rs/*</url-pattern></servlet-mapping>

JAX-RS 2.0

Configuration – New API

import javax.ws.rs.ApplicationPath;import javax.ws.rs.core.Application;

@ApplicationPath("/rs")public class RestApp extends Application {}

JAX-RS 2.0

Client - Old APIHttpURLConnection connection =

(HttpURLConnection)serverAddress.openConnection();connection.setRequestMethod("GET");connection.setDoOutput(true);connection.setReadTimeout(10000);

BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));

StringBuilder sb = new StringBuilder();

while ((line = rd.readLine()) != null) {sb.append(line + '\n');

}

System.out.println(sb.toString());

JAX-RS 2.0

Client - Old API<dependency>

<groupId>com.github.kevinsawicki</groupId><artifactId>http-request</artifactId><version>5.4.1</version>

</dependency>

HttpRequest request = HttpRequest.get(baseURL).receive(output);

System.out.println(request.toString());

JAX-RS 2.0

New APIimport javax.ws.rs.client.Client;import javax.ws.rs.client.ClientBuilder;import javax.ws.rs.client.WebTarget;

Client client = ClientBuilder.newBuilder().build();WebTarget target = client.target(uri.toString());Response response = target.request().get();

assertThat(response.getStatus()).isEqualTo(200);assertThat(target.request().get(String.class))

.isEqualTo("{}");

Java EE7 deep dive

• JMS 2.0• JPA 2.1• Bean Validation 1.1• JAX-RS 2.0• Java API for JSON• Java API for Websockets• Batch Application• Concurrency Utilities

Java API for JSON Processing

{"data": [

"Hello Jakub","Guten Tag Jakub"

]}

Java API for JSON Processing

Old API

??

Java API for JSON Processing

New API – streaming API

JsonParser parser = Json.createParser(new StringReader(string)));

event = parser.next();assertThat(event).is(new Condition<Object>() {

public boolean matches(Object value) {return value instanceof Event

&& value == Event.VALUE_STRING;}

});assertThat(parser.getString()).isEqualTo("Hello Jakub");

Java API for JSON Processing

New API – object API

JsonReader reader = Json.createReader(new StringReader(string));

JsonObject obj = reader.readObject();assertThat(obj.containsKey("data")).isTrue(); JsonArray results = obj.getJsonArray("data"); assertThat(results.size()).isEqualTo(2);assertThat(results.getString(0)).isEqualTo("Hello Jakub");assertThat(results.getString(1)).isEqualTo("Guten tag Jakub");

Java API for JSON Processing

New API – builder

import javax.json.Json;import javax.json.JsonObject;

@Path("/simple/{name}")@GET@Produces(MediaType.APPLICATION_JSON)public JsonObject saySimpleHello(@PathParam("name") String name) {

return Json.createObjectBuilder().add("data", Json.createArrayBuilder()

.add("Hello " + name)

.add("Guten tag " + name)

.build()).build();

}

Java EE7 deep dive

• JMS 2.0• JPA 2.1• Bean Validation 1.1• JAX-RS 2.0• Java API for JSON• Java API for Websockets• Batch Application• Concurrency Utilities

Java API for Websockets

Old API #1@WebServlet(urlPatterns = "/ping")public class FeedNotifierWebSocket extends WebSocketServlet {

protected StreamInbound createWebSocketInbound(String subprotocol,HttpServletRequest req) {

//..}

}

Java API for Websockets

Old API #1class NotificationInbound extends MessageInbound {

private WsOutbound outbound;

protected void onOpen(WsOutbound outbound) {this.outbound = outbound;

}

protected void onBinaryMessage(ByteBuffer m) {outbound.writeBinaryMessage(message);

}

protected void onTextMessage(CharBuffer m) {outbound.writeTextMessage(message);

}}

Java API for Websockets

Old API #2@Singleton@WebSocketEndpoint(path=”/chat”)public class ChatServer {

Set<Session> peers = new HashSet<>();

@WebSocketOpenpublic void onOpen(Session peer) {

peers.add(session);}

@WebSocketClosepublic void onClose(Session session) {

peers.remove(session);}

...

Java API for Websockets

Old API #2@WebSocketMessagepublic void message(String message, Session client)

throws IOException {for (Session session : peers) {if (!session.equals(client)) {

session.getRemote().sendObject(message);}

}}

Java API for Websockets

New API@Singleton@ServerEndpoint("/ping")public class NotificationServer {

Set<Session> sessions = new HashSet<>();

@OnOpenpublic void onOpen(Session s) throws IOException {

sessions.add(s);}

@OnClosepublic void onClose(Session s) throws IOException {

sessions.remove(s);}

...

Java API for Websockets

New API

@OnMessagepublic void message(String m, Session client)

throws IOException {for (Session s: sessions) {

if (s == client) continue; try {

s.getBasicRemote().sendText(m);} catch (Exception e) {

onClose(s);}

}}

}

Java EE7 deep dive

• JMS 2.0• JPA 2.1• Bean Validation 1.1• JAX-RS 2.0• Java API for JSON• Java API for Websockets• Batch Application• Concurrency Utilities

Batch Applications

Old API

??

Batch Applications

Item Reader

Item Processor

Item WriterJobs Repository

Job Operator Job Step

1 *1

1

1

1

11

Batch Applications

Job Repository holds information about jobs current running

and jobs that run in the past. JobOperator provides access to this repository.

Job Operator an interface to manage all aspects of job

processing, including operational commands, such as start, restart, and stop, retrieval of job and step executions.

Batch Applications

Jobencapsulates an entire batch process

<job id="myJob" xmlns="http://batch.jsr352/jsl"> <step id="myStep" > <chunk reader="MyItemReader" writer="MyItemWriter" processor="MyItemProcessor" buffer-size="5" checkpoint-policy="item" commit-interval="10" /> </step></job>

Batch Applications

Chunks@ItemReaderpublic class MyItemReader { //...}

@ItemProcessorpublic class MyItemProcessor { //...}

@ItemWriterpublic class MyItemWriter { //...}

Java EE7 deep dive

• JMS 2.0• JPA 2.1• Bean Validation 1.1• JAX-RS 2.0• Java API for JSON• Java API for Websockets• Batch Application• Concurrency Utilities

The enterprise bean must not attempt to manage threads. The

enterprise bean must not attempt to start, stop, suspend, or resume a thread, or to change a thread’s priority or name. The enterprise

bean must not attempt to manage thread groups.

21.2.2. Programming restrictions

@Asynchronous

Old API@Statelesspublic class EventWatcher {

@Asynchronouspublic void method(FeedEvent event) {

System.out.println(event);}

}

Asynchronous Servlets

Old API@WebServlet(urlPatterns = "/somepath", asyncSupported = true)public class AsyncServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {//..

}}

ManagedThreadFactory

New API@Namedpublic class ThreadManager {

@ResourceManagedThreadFactory mtf;

public ExecutorService getThreadManager() {return new ThreadPoolExecutor(5,10, 10,

TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100), mtf);

}

}

ManagedThreadFactory

New API

@Namedpublic class ProcessingService {

public void doMuchStuff(ExecutorService executor) {for (int i = 0; i < 50; i++) {

Runnable worker = new WorkerThread("" + i);executor.execute(worker);

}executor.shutdown();

}}

Java EE8 ??

• JSON-B (JSON binding)• JCache (JSR 107)• Adopt JSR• Open TCK (??)• More JSP (+ templates), less JSF• no more EARs (??)

twitter: @kubem

http://github.com/kubamarchwicki/jee7-examples

http://www.slideshare.net/kubamarchwicki/jeenext

In case you ask – we are hiring