69
JEE.next() Kuba Marchwicki @kubem Gdańsk, 26.09.2013

JEE.next()

Embed Size (px)

DESCRIPTION

What's new in JEE7

Citation preview

Page 1: JEE.next()

JEE.next()Kuba Marchwicki

@kubem

Gdańsk, 26.09.2013

Page 2: JEE.next()

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

but when there is nothing left to take away.

Antoine de Saint-Exupery

Page 3: JEE.next()

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

Page 4: JEE.next()

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

Page 5: JEE.next()

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

Page 6: JEE.next()

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

Page 7: JEE.next()
Page 8: JEE.next()

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

Page 9: JEE.next()

Before we start

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

</dependency>

Page 10: JEE.next()

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

Page 11: JEE.next()

JMS 2.0

Configuration - Old API

??

Page 12: JEE.next()

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>

Page 13: JEE.next()

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 {

}

Page 14: JEE.next()

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

Page 15: JEE.next()

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);

}

}

Page 16: JEE.next()

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();

}

}

}

Page 17: JEE.next()
Page 18: JEE.next()

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

Page 19: JEE.next()

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>

Page 20: JEE.next()

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>

Page 21: JEE.next()

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>

Page 22: JEE.next()

JPA 2.1

Old API – Converterspublic enum UseSex {

MALE, FEMALE;}

@Entitypublic class User {

@Idprivate long id;

@Enumerated(EnumType.ORDINAL)private UserSex sex;

//..}

Page 23: JEE.next()

JPA 2.1

Old API – Converterspublic enum UseSex {

MALE, FEMALE;}

@Entitypublic class User {

@Idprivate long id;

@Enumerated(EnumType.STRING)private UserSex sex;

//..}

Page 24: JEE.next()

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();}

}

Page 25: JEE.next()

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();

}}

Page 26: JEE.next()

JPA 2.1

New API@Entitypublic class User {

@Idprivate long id;

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

//..}

Page 27: JEE.next()

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();

}}

}

Page 28: JEE.next()

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";

//..

}

Page 29: JEE.next()

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

Page 30: JEE.next()

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);}

Page 31: JEE.next()

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());

}

Page 32: JEE.next()

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);}

Page 33: JEE.next()

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) {//..

}}

Page 34: JEE.next()

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

Page 35: JEE.next()

JAX-RS 2.0

Configuration - Old API

??

Page 36: JEE.next()

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>

Page 37: JEE.next()

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 {}

Page 38: JEE.next()

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());

Page 39: JEE.next()

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());

Page 40: JEE.next()

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("{}");

Page 41: JEE.next()

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

Page 42: JEE.next()

Java API for JSON Processing

{"data": [

"Hello Jakub","Guten Tag Jakub"

]}

Page 43: JEE.next()

Java API for JSON Processing

Old API

??

Page 44: JEE.next()

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");

Page 45: JEE.next()

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");

Page 46: JEE.next()

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();

}

Page 47: JEE.next()

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

Page 48: JEE.next()

Java API for Websockets

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

protected StreamInbound createWebSocketInbound(String subprotocol,HttpServletRequest req) {

//..}

}

Page 49: JEE.next()

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);

}}

Page 50: JEE.next()

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);}

...

Page 51: JEE.next()

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);}

}}

Page 52: JEE.next()

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);}

...

Page 53: JEE.next()

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);}

}}

}

Page 54: JEE.next()

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

Page 55: JEE.next()

Batch Applications

Old API

??

Page 56: JEE.next()

Batch Applications

Item Reader

Item Processor

Item WriterJobs Repository

Job Operator Job Step

1 *1

1

1

1

11

Page 57: JEE.next()

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.

Page 58: JEE.next()

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>

Page 59: JEE.next()

Batch Applications

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

@ItemProcessorpublic class MyItemProcessor { //...}

@ItemWriterpublic class MyItemWriter { //...}

Page 60: JEE.next()

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

Page 61: JEE.next()

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

Page 62: JEE.next()

@Asynchronous

Old API@Statelesspublic class EventWatcher {

@Asynchronouspublic void method(FeedEvent event) {

System.out.println(event);}

}

Page 63: JEE.next()

Asynchronous Servlets

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

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {//..

}}

Page 64: JEE.next()

ManagedThreadFactory

New API@Namedpublic class ThreadManager {

@ResourceManagedThreadFactory mtf;

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

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

}

}

Page 65: JEE.next()

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();

}}

Page 66: JEE.next()
Page 67: JEE.next()

Java EE8 ??

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

Page 68: JEE.next()

twitter: @kubem

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

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

Page 69: JEE.next()

In case you ask – we are hiring