KEMBAR78
50 new features of Java EE 7 in 50 minutes | PDF
50 new features of Java EE 7
in 50 minutes
by antonio goncalves
@agoncal
Antonio Goncalves

@agoncal

2
Java EE 7
(for Java EE 6 developers)
Concurrency 1.0

Interceptors 1.2

Bean Validation 1.1

CDI 1.1

What's new? What has been updated?

JSP JSTL

EL 3.0

Servlet 3.1

JSF 2.2

Web Socket 1.0

JAX-RS 2.0
JSON-P 1.0
Batch 1.0

JTA 1.2

EJB 3.2
JPA 2.1

JMS 2.0

JavaMail 1.5
JCA 1.7

Java EE 7

@agoncal

4
CDI 1.1
(JSR 346)
#01: Default enabling
Finer scanning control
●

Possible values: all, annotated, none

●

all behaves like in Java EE 6 (default if not set)

<beans ... version="1.1" bean-discovery-mode="all">
<alternatives>
<class>org.agoncal.book.MockGenerator</class>
</alternatives>
</beans>

@agoncal

6
#02: @Vetoed
Veto the processing of the class or package
@Vetoed
public class NonProcessedBean {
...
}
package-info.java
@Vetoed
package com.non.processed.package;

@agoncal

7
Bean Validation 1.1
(JSR 349)
#03: Constructor & method validation
Pre/post conditions on method and constructors
public class CardValidator {
public CardValidator(@NotNull Algorithm algo) {
this.algo = algo;
}
@AssertTrue
public Boolean validate(@NotNull CreditCard cc) {
return algorithm.validate(cc.getNumber());
}
}

@agoncal

9
#04: CDI in validators
Injection in validators is now possible
public class ZipCodeValidator implements
ConstraintValidator<ZipCode, String> {
@Inject @USA
ZipCodeChecker checker = new ZipCodeChecker();
public boolean isValid(String value,
ConstraintValidatorContext context) {
return checker.isZipCodeValid(value);
}
}

@agoncal

10
Interceptor 1.2
(JSR 318)
#05: AroundConstruct
Interceptor associated with a constructor
public class LoggingInterceptor {
@AroundConstruct
private void init(InvocationContext ic) ...{
logger.fine("Entering constructor");
ic.proceed();
logger.fine("Exiting constructor");
}
@AroundInvoke
public Object logMethod(InvocationContext ic) ... {
...
}
}
@agoncal

12
#06: @Priority
Prioritizing interceptor bindings
●

PLATFORM_BEFORE (0), LIBRARY_BEFORE
(1000), APPLICATION (2000), LIBRARY_AFTER
(3000), PLATFORM_AFTER (4000)

@Interceptor
@Loggable
@Priority(Interceptor.Priority.LIBRARY_BEFORE + 10)
public class LoggingInterceptor {
@AroundInvoke
...
}

@agoncal

13
Concurrency Utilities 1.0
(JSR 236)
#07: ManagedExecutor
Use threads in Java EE applications
●

Java EE applications cannot use:
●
●

java.lang.Thread

●

●

java.util.concurrent.ThreadPoolExecutor
java.util.Timer

In managed environment, use:
●

javax.enterprise.concurrent.ManagedExecutorService

●

implements java.util.concurrent.ExecutorService

@agoncal

15
#07: ManagedExecutor
Use threads in Java EE applications
public class MyTask implements Runnable {
public void run() {
...
}
}

@Resource
ManagedExecutorService executor;
executor.execute(new MyTask());

@agoncal

16
#08: ManagedThreadFactory
Create managed threads for Java EE environment
@Resource
ManagedThreadFactory factory;
Thread thread = factory.newThread(new MyTask());
thread.start();

@agoncal

17
#09: ManagedScheduledExecutorServ
Submit delayed or periodic tasks
@Resource
ManagedScheduledExecutorService executor;
executor.schedule(new MyTask(), 5, TimeUnit.SECONDS);
executor.scheduleAtFixedRate(new MyTask(), 2, 3,
TimeUnit.SECONDS);
executor.scheduleWithFixedDelay(new MyTask(), 2, 3,
TimeUnit.SECONDS);

@agoncal

18
JPA 2.1
(JSR 338)
#10: Schema Generation
Standardized database schema generation
<persistence ... version="2.1">
<persistence-unit ...>
<properties>
<property name="javax.persistence.schema-generation.scripts.action"
value="drop-and-create"/>
<property name="javax.persistence.schema-generation.scripts.create-target"
value="create.ddl"/>
<property name="javax.persistence.sql-load-script-source"
value="insert.sql"/>
</properties>
</persistence-unit>

@agoncal

20
#11: @Index
Defines additional indexes in schema generation
@Entity
@Table(indexes = {
@Index(columnList = "ISBN"),
@Index(columnList = "NBOFPAGE")
})
public class Book {
@Id @GeneratedValue
private Long id;
private String isbn;
private Integer nbOfPage;
...
}
@agoncal

21
#12: Stored Procedure
Declaring and calling a stored procedure
@Entity
@NamedStoredProcedureQuery(name = "archiveOldBooks",
procedureName = "sp_archive_books",
parameters = {
@StoredProcedureParameter(name = ”date",
mode = IN, type = Date.class),
@StoredProcedureParameter(name = "warehouse",
mode = IN, type = String.class)
})
public class Book {...}

@agoncal

22
#13: CDI in listeners
Injection is now possible into event listeners
public class AgeCalculationListener {
@Inject
private AgeCalculator ageCalculator;
@PostLoad
@PostPersist
@PostUpdate
public void calculateAge(Customer c) {
customer.setAge(ageCalculator.calc(c.getBirth));
}
}

@agoncal

23
#14: Converters
Classes that convert between database and attributes
@Converter
public class CreditCardEnumConverter implements
AttributeConverter<CreditCard, String> {
public String convertToDatabaseColumn(CreditCard attr) {...}
public CreditCard convertToEntityAttribute(String data){...}
}

@Entity
public class Order {
@Convert(converter = CreditCardEnumConverter.class)
private CreditCard creditCard;
}
@agoncal

24
JTA 1.2
(JSR 907)
#15: @Transactional
Tx management on Managed Beans as CDI interceptor
@Path("book")
@Transactional(value = Transactional.TxType.REQUIRED,
rollbackOn = {SQLException.class,
JMSException.class},
dontRollbackOn = SQLWarning.class)
public class BookRestService {
@PersistenceContext
private EntityManager em;
@POST
@Consumes(MediaType.APPLICATION_XML)
public Response createBook(Book book) {...}
}
@agoncal

26
#16: @TransactionScoped
CDI scope whose lifecycle is scoped to the current tx
@TransactionScoped
public class BookBean {...}
@WebServlet
public class TxServlet extends HttpServlet {
@Inject BookBean b1;
@Inject BookBean b2;
protected void processRequest(...) {
tx.begin();
out.println(b1.getReference());
out.println(b2.getReference());
tx.commit();
}
}

@agoncal

27
EJB 3.2
(JSR 345)
#17: Disable passivation of stateful
In some cases increases performance
@Stateful(passivationCapable = false)
public class ShoppingCart {
...
}

@agoncal

29
#18: Async + Non-persistent timer
EJB Lite includes asynchronous calls and Timer Service
@Stateless
public class OrderEJB {
@Asynchronous
public void sendEmail (Order order) {
// Very Long task
}
@Schedule(hour="2", persistent=false)
public void createDailyReport() {
// ...
}
}
@agoncal

30
JMS 2.0
(JSR 343)
#19: JMSContext API
New simplified API to produce and consume messages
JMSContext ctx = connectionFactory.createContext()
ctx.createProducer().send(queue, "Text msg sent");
ctx.createConsumer(queue).receiveBody(String.class);
ctx.createProducer()
.setPriority(2)
.setTimeToLive(1000)
.setDeliveryMode(DeliveryMode.NON_PERSISTENT)
.send(queue, message);

@agoncal

32
#20: Runtime Exceptions
A set of new unchecked exceptions have been created
RuntimeException
JMSRuntimeException
IllegalStateRuntimeException
InvalidClientIDRuntimeException
InvalidDestinationRuntimeException
InvalidSelectorRuntimeException
JMSSecurityRuntimeException
MessageFormatRuntimeException
MessageNotWriteableRuntimeException
ResourceAllocationRuntimeException
TransactionInProgressRuntimeException
TransactionRolledBackRuntimeException

@agoncal

33
#21: Autocloseable
Several JMS interfaces implement Autocloseable
try (JMSContext ctx = connectionFactory.createContext()){
ctx.createProducer().send(queue, "Text message sent");
}

@agoncal

34
#22: JMSConnectionFactoryDefinition
A ConnectionFactory can be defined using an annotation
@Stateless
@JMSConnectionFactoryDefinition(
name = "java:app/jms/MyConnectionFactory",
interfaceName = "javax.jms.TopicConnectionFactory")

public class ExpensiveOrderEJB {
...
}

@agoncal

35
#23: JMSDestinationDefinition
A JMS queue or topic can be defined using an annotation
@Stateless
@JMSConnectionFactoryDefinition(
name = "java:app/jms/MyConnectionFactory",
interfaceName = "javax.jms.TopicConnectionFactory")
@JMSDestinationDefinition(
name = "java:app/jms/MyTopic",
interfaceName = "javax.jms.Topic")
public class ExpensiveOrderEJB {
...
}

@agoncal

36
Servlet 3.1
(JSR 340)
#24: Non-blocking IO
New interfaces
public interface ReadListener extends EventListener {
public void onDataAvailable() throws IOException;
public void onAllDataRead() throws IOException;
public void onError(Throwable t);
}
public interface WriteListener extends EventListener {
public void onWritePossible() throws IOException;
public void onError(Throwable t);
}

@agoncal

38
#24: Non-blocking IO
New methods on existing APIs
●

javax.servlet.ServletInputStream
●
●

public abstract boolean isReady()

●
●

public abstract boolean isFinished()
public abstract void setReadListener(ReadListener l)

javax.servlet.ServletOutputStream
●

public abstract boolean isReady()

●

public abstract setWriteListener(WriteListener l)

@agoncal

39
#24: Non-blocking IO
Example
@WebServlet(“/test”)

public class TestServlet extends HttpServlet {
protected void doPost(HttpServletRequest req,
HttpServletResponse res) ... {
AsyncContext ac = req.startAsync();
...
ServletInputStream input = req.getInputStream();
ReadListener readListener = new
ReadListenerImpl(input, output, ac);
input.setReadListener(readListener);
}

@agoncal

40
#25: Improved Security
Any authenticated users
@WebServlet(“/test”)
@ServletSecurity(@HttpConstraint(rolesAllowed={“**”}))

public class TestServlet extends HttpServlet {
...
}

@agoncal

41
#25: Improved Security
All HTTP Methods except GET are uncovered
<web-app . . . version="3.1">
<security-constraint>
<web-resource-collection>
<url-pattern>/account/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
</security-constraint>
</web-app>

@agoncal

42
#25: Improved Security
The container denies any HTTP protocol method
<web-app . . . version="3.1">
<security-constraint>
<deny-uncovered-http-methods/>
<web-resource-collection>
<url-pattern>/account/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
</security-constraint>
</web-app>

@agoncal

43
#26: Protocol Upgrade
New interfaces and methods on existing APIs
●

Add two new interfaces
●
●

●

javax.servlet.http.HttpUpgradeHandler
javax.servlet.http.WebConnection

Add a method to HttpServletRequest
●

upgrade(Class<T> handlerClass)

@agoncal

44
#26: Protocol Upgrade
Example
@WebServlet(“/upgrade”)
public class UpgradeServlet extends HttpServlet
protected void doGet(HttpServletRequest req,
HttpServletResponse res) ... {
...
if (decideToUpgrade) {
MyHttpUpgradeHandler handler =
request.upgrade(MyHttpUpgradeHandler.class);
}
}
}

@agoncal

45
Web Socket 1.0
(JSR 356)
#27: Annotated server endpoint
Bi-directional communication over single TCP connection
@javax.websocket.server.ServerEndpoint("/chat")
public class ChatServer {
@OnMessage
public String chat(String name, Session session) {
for (Session peer : client.getOpenSessions()) {
peer.getBasicRemote().sendObject(message);
}
}
}

@agoncal

47
#28: Annotated client endpoint
Bi-directional communication over single TCP connection
@javax.websocket.ClientEndpoint
public class ChatClient {
@OnOpen
public void open(Session session) {
...
}
}

@agoncal

48
#29: Lifecycle callbacks
Allows you to act on lifecycle events
@OnMessage
public String chat(String name, Session session) {..}
@OnOpen
public void open(Session s) {...}
@OnClose
public void close(CloseReason c) {...}
@OnError
public void error(Throwable t) {...}

@agoncal

49
Expression Language 3.0
(JSR 341)
#30: ELProcessor
Use EL in a stand-alone environment
ELProcessor el = new ELProcessor();
assert ((Integer)el.eval("a = [1, 2]; a[1]")) == 2;
el.defineBean("employee", new Employee("John"));
assert (el.eval("employee.name")).equals("John");

@agoncal

51
#31: Lambda expression
Use lambdas before Java SE 8
ELProcessor el = new ELProcessor();
assert ((Integer)(el.eval
("((x,y) -> x+y)(4, 5)"))) == 9;

@agoncal

52
JSF 2.2
(JSR 344)
#32: Faces Flow
Navigate in a flow using convention over configuration
./src/main/webapp/flow1
/flow1.xhtml
/flow1a.xhtml
/flow1b.xhtml
./src/main/webapp/flow2
/flow2-flow.xml
/flow2.xhtml
/flow2a.xhtml
/flow2b.xhtml
/index.xhtml

@agoncal

54
#32: Faces Flow
New CDI flow scope
@Named
@FlowScoped("flow1")
public class Flow1Bean implements Serializable {
...
}

@agoncal

55
#33: Resource Library Contract
Reusable and interchange templates
index-blue.xhtml
index-red.xhtml
WEB-INF/lib/mycontracts-1.0.jar
/META-INF/contracts/blue
/style.css
/javax.faces.contract.xml
/template.xhtml
/META-INF/contracts/red
/style.css
/javax.faces.contract.xml
/template.xhtml

@agoncal

56
#33: Resource Library Contract
Reusable and interchange templates
<f:view contracts=”red”>
<ui:composition template="/template.xhtml">
. . .
</ui:composition>
</f:view>

@agoncal

57
#34: Pass-through Attributes
HTML5-Friendly Markup
<input type="email" placeholder="john@foo.net">

<html xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://xmlns.jcp.org/jsf/passthrough">
<h:inputText p:type="email"
p:placeholder="john@foo.net"
value="#{bean.email}"/>
</html>

@agoncal

58
#35: File upload
Use the Servlet 3.0 Part
<h:form enctype="multipart/form-data">
<h:inputFile value="#{fileUploadBean.file}"/>
<h:commandButton value="Upload"/>
</h:form>

@Named
@RequestScoped
public class FileUploadBean {
private Part file;
...
}

@agoncal

59
JAX-RS 2.0
(JSR 339)
#36: Client API
New API to consume rest services
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://www.foo.com/book");
Invocation invocation = target.request(TEXT_PLAIN).get();
Response response = invocation.invoke();
Response response = ClientBuilder.newClient()
.target("http://www.foo.com/book")
.request(MediaType.TEXT_PLAIN)
.get();
String body = ClientBuilder.newClient()
.target("http://www.foo.com/book")
.request()
.get(String.class);

@agoncal

61
#37: Async client
The client API also supports asynchronous invocation
Future<String> future = ClientBuilder.newClient()
.target("http://www.foo.com/book")
.request()
.async()
.get(String.class);
try {
String body = future.get(1, TimeUnit.MINUTES);
} catch (InterruptedException |ExecutionException e){
...
}

@agoncal

62
#38: Async server
Asynchronous request processing on the server
@Path("/async")
public class AsyncResource {
@GET
public void asyncGet(@Suspended AsyncResponse resp){
new Thread(new Runnable() {
public void run() {
String result = veryExpensiveOperation();
resp.resume(result);
}
}).start();
}}
@agoncal

63
#39: Message Filter
Process incoming/outgoing request/response headers
●

Filters on client side
●
●

●

javax.ws.rs.client.ClientRequestFilter
javax.ws.rs.client.ClientResponseFilter

Filters on server side
●

javax.ws.rs.container.ContainerRequestFilter

●

javax.ws.rs.container.ContainerResponseFilter

@agoncal

64
#39: Message Filter
Process incoming/outgoing request/response headers
public class LogginFilter implements ClientRequestFilter{
public void filter(ClientRequestContext ctx) ... {
System.out.println(ctx.getMethod());
System.out.println(ctx.getUri());
}
}

@agoncal

65
#40: Entity Interceptors
Marshalling and unmarshalling HTTP message bodies
●

Intercepts inbound stream (read from the “wire”)
●

●

javax.ws.rs.ext.ReaderInterceptor

Intercepts outbound stream (written to the “wire”)
●

javax.ws.rs.ext.WriterInterceptor

@agoncal

66
#40: Entity Interceptors
Marshalling and unmarshalling HTTP message bodies
public class ZipInterceptor implements WriterInterceptor{
public void aroundWriteTo(WriterInterceptorContext ctx){
OutputStream os = ctx.getOutputStream();
ctx.setOutputStream(new GZIPOutputStream(os));
ctx.proceed();
}
}

@agoncal

67
JSON-P 1.0
(JSR 353)
#41: JSON Builder
Builds an object model in memory by adding elements
JsonObject value = Json.createObjectBuilder()
.add("id", "1234")
.add("date", "19/09/2012")
.add("total_amount", "93.48")
.add("customer", Json.createObjectBuilder()
.add("first_name", "James")
.add("last_name", "Rorrison")
.add("email", "j.rorri@me.com")
.add("phoneNumber", "+44 1234 1234")
)
.build();

@agoncal

69
#42: JSON Parser
Event-based parser reading JSON data from a stream
JsonParser parser = Json.createParser(
new FileReader(“order.json"));
while (parser.hasNext()) {
JsonParser.Event event = parser.next();
if (event.equals(JsonParser.Event.KEY_NAME) &&
parser.getString().matches("email")) {
parser.next();
email = parser.getString();
}
}

@agoncal

70
Batch 1.0
(JSR 352)
#43: Jobs and steps
Batch uses jobs and steps to do the work

@agoncal

72
#44: Workflow
Flow, step, decision... to create workflows
<split id="split1" next=" . . . ">
<flow id="flow1" next="step3">
<step id="step1" next="step2"> . . . </step>
<step id="step2"> . . . </step>
</flow>
<flow id="flow2”>
<step id="stepA”> . . . </step>
</flow>
</split>
<step id="step3"> . . . </step>

@agoncal

73
#45: Chunk-style processing
Item-oriented way of processing
<step id=”sendStatements”>
<chunk item-count=“3”>
<reader ref=”accountReader”/>
<processor ref=”accountProcessor”/>
<writer ref=”emailWriter”/>
</step>

...implements ItemReader {
public Object readItem() {
// read account using JPA
}

...implements ItemProcessor {
public Object processItems(Object account) {
// read Account, return Statement
}

...implements ItemWriter {
public void writeItems(List accounts) {
// use JavaMail to send email
}

@agoncal

74
#46: Batchlet-style processing
Task-oriented way of processing
<step id=”transferFile”>
<batchlet ref=“MyFileTransfer” />
</step>

...implements Batchlet {
@Override
public void process() {
// Transfer file
}

@agoncal

75
JavaMail 1.5
(JSR 919)
#47: MailSessionDefinition
A mail session can be defined using an annotation
@MailSessionDefinition(name = "java:comp/myMailSession",
properties = {
"mail.smtp.host=smtp.gmail.com",
"mail.smtp.ssl.enable=true",
"mail.smtp.auth=true",
"mail.transport.protocol=smtp",
"mail.debug=true"
})

@Resource(lookup = "java:comp/myMailSession")
Session session;

@agoncal

77
JCA 1.7
(JSR 322)
#48: Connector definition
A connector can be defined using an annotation
@ConnectionDefinition(
connection="MyConnection.class",
connectionImpl="MyConnectionImpl.class",
connectionFactory="MyConnectionFactory.class",
connectionFactoryImpl="MyConnectionFactoryImpl.class"
)
@AdministeredObjectDefinition(
className="MyQueueImpl.class",
name="java:comp/MyQueue",
resourceAdapter="myAdapter",
)

@agoncal

79
Java EE 7
(JSR 342)
#49: Default Resources
Default datasource
@Resource(lookup="java:comp/DefaultDataSource")
private DataSource myDS;
@Resource
private DataSource myDS;

@agoncal

81
#49: Default Resources
Default JMS factory
@Resource(lookup="java:comp/DefaultJMSConnectionFactory")
private ConnectionFactory myCF;
@Resource
private ConnectionFactory myCF;

@agoncal

82
#49: Default Resources
Default Concurrency Utilities objects
@Resource(lookup="java:comp/DefaultManagedExecutorService")
private ManagedExecutorService mes;
@Resource(lookup="java:comp/DefaultManagedScheduledExecutorService")
private ManagedScheduledExecutorService mses;
@Resource(lookup="java:comp/DefaultManagedThreadFactory")
private ManagedThreadFactory mtf;
@Resource(lookup="java:comp/DefaultContextService")
private ContextService cs;
@Resource
private ManagedExecutorService mes;
@Resource
private ManagedScheduledExecutorService mses;
@Resource
private ManagedThreadFactory mtf;
@Resource
private ContextService cs;

@agoncal

83
#50: Get more information ;o)

@agoncal

84
Thanks
www.antoniogoncalves.org
antonio.goncalves@gmail.com
@agoncal
@pluralsight
@devoxxfr
@lescastcodeurs
Q&A
Thanks
●

Arun Gupta @arungupta

●

From our talk at JavaOne 2013

@agoncal

87
Creative Commons
●

●

●

Attribution — You must attribute the work in
the manner specified by the author or licensor
(but not in any way that suggests that they
endorse you or your use of the work).
Noncommercial — You may not use this work for
commercial purposes.
Share Alike — If you alter, transform, or build
upon this work, you may distribute the resulting
work only under the same or similar license to
this one.
@agoncal

88

50 new features of Java EE 7 in 50 minutes

  • 1.
    50 new featuresof Java EE 7 in 50 minutes by antonio goncalves @agoncal
  • 2.
  • 3.
    Java EE 7 (forJava EE 6 developers)
  • 4.
    Concurrency 1.0 Interceptors 1.2 BeanValidation 1.1 CDI 1.1 What's new? What has been updated? JSP JSTL EL 3.0 Servlet 3.1 JSF 2.2 Web Socket 1.0 JAX-RS 2.0 JSON-P 1.0 Batch 1.0 JTA 1.2 EJB 3.2 JPA 2.1 JMS 2.0 JavaMail 1.5 JCA 1.7 Java EE 7 @agoncal 4
  • 5.
  • 6.
    #01: Default enabling Finerscanning control ● Possible values: all, annotated, none ● all behaves like in Java EE 6 (default if not set) <beans ... version="1.1" bean-discovery-mode="all"> <alternatives> <class>org.agoncal.book.MockGenerator</class> </alternatives> </beans> @agoncal 6
  • 7.
    #02: @Vetoed Veto theprocessing of the class or package @Vetoed public class NonProcessedBean { ... } package-info.java @Vetoed package com.non.processed.package; @agoncal 7
  • 8.
  • 9.
    #03: Constructor &method validation Pre/post conditions on method and constructors public class CardValidator { public CardValidator(@NotNull Algorithm algo) { this.algo = algo; } @AssertTrue public Boolean validate(@NotNull CreditCard cc) { return algorithm.validate(cc.getNumber()); } } @agoncal 9
  • 10.
    #04: CDI invalidators Injection in validators is now possible public class ZipCodeValidator implements ConstraintValidator<ZipCode, String> { @Inject @USA ZipCodeChecker checker = new ZipCodeChecker(); public boolean isValid(String value, ConstraintValidatorContext context) { return checker.isZipCodeValid(value); } } @agoncal 10
  • 11.
  • 12.
    #05: AroundConstruct Interceptor associatedwith a constructor public class LoggingInterceptor { @AroundConstruct private void init(InvocationContext ic) ...{ logger.fine("Entering constructor"); ic.proceed(); logger.fine("Exiting constructor"); } @AroundInvoke public Object logMethod(InvocationContext ic) ... { ... } } @agoncal 12
  • 13.
    #06: @Priority Prioritizing interceptorbindings ● PLATFORM_BEFORE (0), LIBRARY_BEFORE (1000), APPLICATION (2000), LIBRARY_AFTER (3000), PLATFORM_AFTER (4000) @Interceptor @Loggable @Priority(Interceptor.Priority.LIBRARY_BEFORE + 10) public class LoggingInterceptor { @AroundInvoke ... } @agoncal 13
  • 14.
  • 15.
    #07: ManagedExecutor Use threadsin Java EE applications ● Java EE applications cannot use: ● ● java.lang.Thread ● ● java.util.concurrent.ThreadPoolExecutor java.util.Timer In managed environment, use: ● javax.enterprise.concurrent.ManagedExecutorService ● implements java.util.concurrent.ExecutorService @agoncal 15
  • 16.
    #07: ManagedExecutor Use threadsin Java EE applications public class MyTask implements Runnable { public void run() { ... } } @Resource ManagedExecutorService executor; executor.execute(new MyTask()); @agoncal 16
  • 17.
    #08: ManagedThreadFactory Create managedthreads for Java EE environment @Resource ManagedThreadFactory factory; Thread thread = factory.newThread(new MyTask()); thread.start(); @agoncal 17
  • 18.
    #09: ManagedScheduledExecutorServ Submit delayedor periodic tasks @Resource ManagedScheduledExecutorService executor; executor.schedule(new MyTask(), 5, TimeUnit.SECONDS); executor.scheduleAtFixedRate(new MyTask(), 2, 3, TimeUnit.SECONDS); executor.scheduleWithFixedDelay(new MyTask(), 2, 3, TimeUnit.SECONDS); @agoncal 18
  • 19.
  • 20.
    #10: Schema Generation Standardizeddatabase schema generation <persistence ... version="2.1"> <persistence-unit ...> <properties> <property name="javax.persistence.schema-generation.scripts.action" value="drop-and-create"/> <property name="javax.persistence.schema-generation.scripts.create-target" value="create.ddl"/> <property name="javax.persistence.sql-load-script-source" value="insert.sql"/> </properties> </persistence-unit> @agoncal 20
  • 21.
    #11: @Index Defines additionalindexes in schema generation @Entity @Table(indexes = { @Index(columnList = "ISBN"), @Index(columnList = "NBOFPAGE") }) public class Book { @Id @GeneratedValue private Long id; private String isbn; private Integer nbOfPage; ... } @agoncal 21
  • 22.
    #12: Stored Procedure Declaringand calling a stored procedure @Entity @NamedStoredProcedureQuery(name = "archiveOldBooks", procedureName = "sp_archive_books", parameters = { @StoredProcedureParameter(name = ”date", mode = IN, type = Date.class), @StoredProcedureParameter(name = "warehouse", mode = IN, type = String.class) }) public class Book {...} @agoncal 22
  • 23.
    #13: CDI inlisteners Injection is now possible into event listeners public class AgeCalculationListener { @Inject private AgeCalculator ageCalculator; @PostLoad @PostPersist @PostUpdate public void calculateAge(Customer c) { customer.setAge(ageCalculator.calc(c.getBirth)); } } @agoncal 23
  • 24.
    #14: Converters Classes thatconvert between database and attributes @Converter public class CreditCardEnumConverter implements AttributeConverter<CreditCard, String> { public String convertToDatabaseColumn(CreditCard attr) {...} public CreditCard convertToEntityAttribute(String data){...} } @Entity public class Order { @Convert(converter = CreditCardEnumConverter.class) private CreditCard creditCard; } @agoncal 24
  • 25.
  • 26.
    #15: @Transactional Tx managementon Managed Beans as CDI interceptor @Path("book") @Transactional(value = Transactional.TxType.REQUIRED, rollbackOn = {SQLException.class, JMSException.class}, dontRollbackOn = SQLWarning.class) public class BookRestService { @PersistenceContext private EntityManager em; @POST @Consumes(MediaType.APPLICATION_XML) public Response createBook(Book book) {...} } @agoncal 26
  • 27.
    #16: @TransactionScoped CDI scopewhose lifecycle is scoped to the current tx @TransactionScoped public class BookBean {...} @WebServlet public class TxServlet extends HttpServlet { @Inject BookBean b1; @Inject BookBean b2; protected void processRequest(...) { tx.begin(); out.println(b1.getReference()); out.println(b2.getReference()); tx.commit(); } } @agoncal 27
  • 28.
  • 29.
    #17: Disable passivationof stateful In some cases increases performance @Stateful(passivationCapable = false) public class ShoppingCart { ... } @agoncal 29
  • 30.
    #18: Async +Non-persistent timer EJB Lite includes asynchronous calls and Timer Service @Stateless public class OrderEJB { @Asynchronous public void sendEmail (Order order) { // Very Long task } @Schedule(hour="2", persistent=false) public void createDailyReport() { // ... } } @agoncal 30
  • 31.
  • 32.
    #19: JMSContext API Newsimplified API to produce and consume messages JMSContext ctx = connectionFactory.createContext() ctx.createProducer().send(queue, "Text msg sent"); ctx.createConsumer(queue).receiveBody(String.class); ctx.createProducer() .setPriority(2) .setTimeToLive(1000) .setDeliveryMode(DeliveryMode.NON_PERSISTENT) .send(queue, message); @agoncal 32
  • 33.
    #20: Runtime Exceptions Aset of new unchecked exceptions have been created RuntimeException JMSRuntimeException IllegalStateRuntimeException InvalidClientIDRuntimeException InvalidDestinationRuntimeException InvalidSelectorRuntimeException JMSSecurityRuntimeException MessageFormatRuntimeException MessageNotWriteableRuntimeException ResourceAllocationRuntimeException TransactionInProgressRuntimeException TransactionRolledBackRuntimeException @agoncal 33
  • 34.
    #21: Autocloseable Several JMSinterfaces implement Autocloseable try (JMSContext ctx = connectionFactory.createContext()){ ctx.createProducer().send(queue, "Text message sent"); } @agoncal 34
  • 35.
    #22: JMSConnectionFactoryDefinition A ConnectionFactorycan be defined using an annotation @Stateless @JMSConnectionFactoryDefinition( name = "java:app/jms/MyConnectionFactory", interfaceName = "javax.jms.TopicConnectionFactory") public class ExpensiveOrderEJB { ... } @agoncal 35
  • 36.
    #23: JMSDestinationDefinition A JMSqueue or topic can be defined using an annotation @Stateless @JMSConnectionFactoryDefinition( name = "java:app/jms/MyConnectionFactory", interfaceName = "javax.jms.TopicConnectionFactory") @JMSDestinationDefinition( name = "java:app/jms/MyTopic", interfaceName = "javax.jms.Topic") public class ExpensiveOrderEJB { ... } @agoncal 36
  • 37.
  • 38.
    #24: Non-blocking IO Newinterfaces public interface ReadListener extends EventListener { public void onDataAvailable() throws IOException; public void onAllDataRead() throws IOException; public void onError(Throwable t); } public interface WriteListener extends EventListener { public void onWritePossible() throws IOException; public void onError(Throwable t); } @agoncal 38
  • 39.
    #24: Non-blocking IO Newmethods on existing APIs ● javax.servlet.ServletInputStream ● ● public abstract boolean isReady() ● ● public abstract boolean isFinished() public abstract void setReadListener(ReadListener l) javax.servlet.ServletOutputStream ● public abstract boolean isReady() ● public abstract setWriteListener(WriteListener l) @agoncal 39
  • 40.
    #24: Non-blocking IO Example @WebServlet(“/test”) publicclass TestServlet extends HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse res) ... { AsyncContext ac = req.startAsync(); ... ServletInputStream input = req.getInputStream(); ReadListener readListener = new ReadListenerImpl(input, output, ac); input.setReadListener(readListener); } @agoncal 40
  • 41.
    #25: Improved Security Anyauthenticated users @WebServlet(“/test”) @ServletSecurity(@HttpConstraint(rolesAllowed={“**”})) public class TestServlet extends HttpServlet { ... } @agoncal 41
  • 42.
    #25: Improved Security AllHTTP Methods except GET are uncovered <web-app . . . version="3.1"> <security-constraint> <web-resource-collection> <url-pattern>/account/*</url-pattern> <http-method>GET</http-method> </web-resource-collection> </security-constraint> </web-app> @agoncal 42
  • 43.
    #25: Improved Security Thecontainer denies any HTTP protocol method <web-app . . . version="3.1"> <security-constraint> <deny-uncovered-http-methods/> <web-resource-collection> <url-pattern>/account/*</url-pattern> <http-method>GET</http-method> </web-resource-collection> </security-constraint> </web-app> @agoncal 43
  • 44.
    #26: Protocol Upgrade Newinterfaces and methods on existing APIs ● Add two new interfaces ● ● ● javax.servlet.http.HttpUpgradeHandler javax.servlet.http.WebConnection Add a method to HttpServletRequest ● upgrade(Class<T> handlerClass) @agoncal 44
  • 45.
    #26: Protocol Upgrade Example @WebServlet(“/upgrade”) publicclass UpgradeServlet extends HttpServlet protected void doGet(HttpServletRequest req, HttpServletResponse res) ... { ... if (decideToUpgrade) { MyHttpUpgradeHandler handler = request.upgrade(MyHttpUpgradeHandler.class); } } } @agoncal 45
  • 46.
  • 47.
    #27: Annotated serverendpoint Bi-directional communication over single TCP connection @javax.websocket.server.ServerEndpoint("/chat") public class ChatServer { @OnMessage public String chat(String name, Session session) { for (Session peer : client.getOpenSessions()) { peer.getBasicRemote().sendObject(message); } } } @agoncal 47
  • 48.
    #28: Annotated clientendpoint Bi-directional communication over single TCP connection @javax.websocket.ClientEndpoint public class ChatClient { @OnOpen public void open(Session session) { ... } } @agoncal 48
  • 49.
    #29: Lifecycle callbacks Allowsyou to act on lifecycle events @OnMessage public String chat(String name, Session session) {..} @OnOpen public void open(Session s) {...} @OnClose public void close(CloseReason c) {...} @OnError public void error(Throwable t) {...} @agoncal 49
  • 50.
  • 51.
    #30: ELProcessor Use ELin a stand-alone environment ELProcessor el = new ELProcessor(); assert ((Integer)el.eval("a = [1, 2]; a[1]")) == 2; el.defineBean("employee", new Employee("John")); assert (el.eval("employee.name")).equals("John"); @agoncal 51
  • 52.
    #31: Lambda expression Uselambdas before Java SE 8 ELProcessor el = new ELProcessor(); assert ((Integer)(el.eval ("((x,y) -> x+y)(4, 5)"))) == 9; @agoncal 52
  • 53.
  • 54.
    #32: Faces Flow Navigatein a flow using convention over configuration ./src/main/webapp/flow1 /flow1.xhtml /flow1a.xhtml /flow1b.xhtml ./src/main/webapp/flow2 /flow2-flow.xml /flow2.xhtml /flow2a.xhtml /flow2b.xhtml /index.xhtml @agoncal 54
  • 55.
    #32: Faces Flow NewCDI flow scope @Named @FlowScoped("flow1") public class Flow1Bean implements Serializable { ... } @agoncal 55
  • 56.
    #33: Resource LibraryContract Reusable and interchange templates index-blue.xhtml index-red.xhtml WEB-INF/lib/mycontracts-1.0.jar /META-INF/contracts/blue /style.css /javax.faces.contract.xml /template.xhtml /META-INF/contracts/red /style.css /javax.faces.contract.xml /template.xhtml @agoncal 56
  • 57.
    #33: Resource LibraryContract Reusable and interchange templates <f:view contracts=”red”> <ui:composition template="/template.xhtml"> . . . </ui:composition> </f:view> @agoncal 57
  • 58.
    #34: Pass-through Attributes HTML5-FriendlyMarkup <input type="email" placeholder="john@foo.net"> <html xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:p="http://xmlns.jcp.org/jsf/passthrough"> <h:inputText p:type="email" p:placeholder="john@foo.net" value="#{bean.email}"/> </html> @agoncal 58
  • 59.
    #35: File upload Usethe Servlet 3.0 Part <h:form enctype="multipart/form-data"> <h:inputFile value="#{fileUploadBean.file}"/> <h:commandButton value="Upload"/> </h:form> @Named @RequestScoped public class FileUploadBean { private Part file; ... } @agoncal 59
  • 60.
  • 61.
    #36: Client API NewAPI to consume rest services Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://www.foo.com/book"); Invocation invocation = target.request(TEXT_PLAIN).get(); Response response = invocation.invoke(); Response response = ClientBuilder.newClient() .target("http://www.foo.com/book") .request(MediaType.TEXT_PLAIN) .get(); String body = ClientBuilder.newClient() .target("http://www.foo.com/book") .request() .get(String.class); @agoncal 61
  • 62.
    #37: Async client Theclient API also supports asynchronous invocation Future<String> future = ClientBuilder.newClient() .target("http://www.foo.com/book") .request() .async() .get(String.class); try { String body = future.get(1, TimeUnit.MINUTES); } catch (InterruptedException |ExecutionException e){ ... } @agoncal 62
  • 63.
    #38: Async server Asynchronousrequest processing on the server @Path("/async") public class AsyncResource { @GET public void asyncGet(@Suspended AsyncResponse resp){ new Thread(new Runnable() { public void run() { String result = veryExpensiveOperation(); resp.resume(result); } }).start(); }} @agoncal 63
  • 64.
    #39: Message Filter Processincoming/outgoing request/response headers ● Filters on client side ● ● ● javax.ws.rs.client.ClientRequestFilter javax.ws.rs.client.ClientResponseFilter Filters on server side ● javax.ws.rs.container.ContainerRequestFilter ● javax.ws.rs.container.ContainerResponseFilter @agoncal 64
  • 65.
    #39: Message Filter Processincoming/outgoing request/response headers public class LogginFilter implements ClientRequestFilter{ public void filter(ClientRequestContext ctx) ... { System.out.println(ctx.getMethod()); System.out.println(ctx.getUri()); } } @agoncal 65
  • 66.
    #40: Entity Interceptors Marshallingand unmarshalling HTTP message bodies ● Intercepts inbound stream (read from the “wire”) ● ● javax.ws.rs.ext.ReaderInterceptor Intercepts outbound stream (written to the “wire”) ● javax.ws.rs.ext.WriterInterceptor @agoncal 66
  • 67.
    #40: Entity Interceptors Marshallingand unmarshalling HTTP message bodies public class ZipInterceptor implements WriterInterceptor{ public void aroundWriteTo(WriterInterceptorContext ctx){ OutputStream os = ctx.getOutputStream(); ctx.setOutputStream(new GZIPOutputStream(os)); ctx.proceed(); } } @agoncal 67
  • 68.
  • 69.
    #41: JSON Builder Buildsan object model in memory by adding elements JsonObject value = Json.createObjectBuilder() .add("id", "1234") .add("date", "19/09/2012") .add("total_amount", "93.48") .add("customer", Json.createObjectBuilder() .add("first_name", "James") .add("last_name", "Rorrison") .add("email", "j.rorri@me.com") .add("phoneNumber", "+44 1234 1234") ) .build(); @agoncal 69
  • 70.
    #42: JSON Parser Event-basedparser reading JSON data from a stream JsonParser parser = Json.createParser( new FileReader(“order.json")); while (parser.hasNext()) { JsonParser.Event event = parser.next(); if (event.equals(JsonParser.Event.KEY_NAME) && parser.getString().matches("email")) { parser.next(); email = parser.getString(); } } @agoncal 70
  • 71.
  • 72.
    #43: Jobs andsteps Batch uses jobs and steps to do the work @agoncal 72
  • 73.
    #44: Workflow Flow, step,decision... to create workflows <split id="split1" next=" . . . "> <flow id="flow1" next="step3"> <step id="step1" next="step2"> . . . </step> <step id="step2"> . . . </step> </flow> <flow id="flow2”> <step id="stepA”> . . . </step> </flow> </split> <step id="step3"> . . . </step> @agoncal 73
  • 74.
    #45: Chunk-style processing Item-orientedway of processing <step id=”sendStatements”> <chunk item-count=“3”> <reader ref=”accountReader”/> <processor ref=”accountProcessor”/> <writer ref=”emailWriter”/> </step> ...implements ItemReader { public Object readItem() { // read account using JPA } ...implements ItemProcessor { public Object processItems(Object account) { // read Account, return Statement } ...implements ItemWriter { public void writeItems(List accounts) { // use JavaMail to send email } @agoncal 74
  • 75.
    #46: Batchlet-style processing Task-orientedway of processing <step id=”transferFile”> <batchlet ref=“MyFileTransfer” /> </step> ...implements Batchlet { @Override public void process() { // Transfer file } @agoncal 75
  • 76.
  • 77.
    #47: MailSessionDefinition A mailsession can be defined using an annotation @MailSessionDefinition(name = "java:comp/myMailSession", properties = { "mail.smtp.host=smtp.gmail.com", "mail.smtp.ssl.enable=true", "mail.smtp.auth=true", "mail.transport.protocol=smtp", "mail.debug=true" }) @Resource(lookup = "java:comp/myMailSession") Session session; @agoncal 77
  • 78.
  • 79.
    #48: Connector definition Aconnector can be defined using an annotation @ConnectionDefinition( connection="MyConnection.class", connectionImpl="MyConnectionImpl.class", connectionFactory="MyConnectionFactory.class", connectionFactoryImpl="MyConnectionFactoryImpl.class" ) @AdministeredObjectDefinition( className="MyQueueImpl.class", name="java:comp/MyQueue", resourceAdapter="myAdapter", ) @agoncal 79
  • 80.
  • 81.
    #49: Default Resources Defaultdatasource @Resource(lookup="java:comp/DefaultDataSource") private DataSource myDS; @Resource private DataSource myDS; @agoncal 81
  • 82.
    #49: Default Resources DefaultJMS factory @Resource(lookup="java:comp/DefaultJMSConnectionFactory") private ConnectionFactory myCF; @Resource private ConnectionFactory myCF; @agoncal 82
  • 83.
    #49: Default Resources DefaultConcurrency Utilities objects @Resource(lookup="java:comp/DefaultManagedExecutorService") private ManagedExecutorService mes; @Resource(lookup="java:comp/DefaultManagedScheduledExecutorService") private ManagedScheduledExecutorService mses; @Resource(lookup="java:comp/DefaultManagedThreadFactory") private ManagedThreadFactory mtf; @Resource(lookup="java:comp/DefaultContextService") private ContextService cs; @Resource private ManagedExecutorService mes; @Resource private ManagedScheduledExecutorService mses; @Resource private ManagedThreadFactory mtf; @Resource private ContextService cs; @agoncal 83
  • 84.
    #50: Get moreinformation ;o) @agoncal 84
  • 85.
  • 86.
  • 87.
    Thanks ● Arun Gupta @arungupta ● Fromour talk at JavaOne 2013 @agoncal 87
  • 88.
    Creative Commons ● ● ● Attribution —You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work). Noncommercial — You may not use this work for commercial purposes. Share Alike — If you alter, transform, or build upon this work, you may distribute the resulting work only under the same or similar license to this one. @agoncal 88