Upload
kuba-marchwicki
View
1.038
Download
2
Tags:
Embed Size (px)
DESCRIPTION
What's new in JEE7
Citation preview
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