Advertisement

50 new features of Java EE 7 in 50 minutes

CTO at AllCraft
Jan. 14, 2014
Advertisement

More Related Content

Advertisement
Advertisement

50 new features of Java EE 7 in 50 minutes

  1. 50 new features of Java EE 7 in 50 minutes by antonio goncalves @agoncal
  2. Antonio Goncalves @agoncal 2
  3. Java EE 7 (for Java EE 6 developers)
  4. 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
  5. CDI 1.1 (JSR 346)
  6. #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
  7. #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
  8. Bean Validation 1.1 (JSR 349)
  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 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
  11. Interceptor 1.2 (JSR 318)
  12. #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
  13. #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
  14. Concurrency Utilities 1.0 (JSR 236)
  15. #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
  16. #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
  17. #08: ManagedThreadFactory Create managed threads for Java EE environment @Resource ManagedThreadFactory factory; Thread thread = factory.newThread(new MyTask()); thread.start(); @agoncal 17
  18. #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
  19. JPA 2.1 (JSR 338)
  20. #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
  21. #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
  22. #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
  23. #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
  24. #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
  25. JTA 1.2 (JSR 907)
  26. #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
  27. #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
  28. EJB 3.2 (JSR 345)
  29. #17: Disable passivation of 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. JMS 2.0 (JSR 343)
  32. #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
  33. #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
  34. #21: Autocloseable Several JMS interfaces implement Autocloseable try (JMSContext ctx = connectionFactory.createContext()){ ctx.createProducer().send(queue, "Text message sent"); } @agoncal 34
  35. #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
  36. #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
  37. Servlet 3.1 (JSR 340)
  38. #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
  39. #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
  40. #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
  41. #25: Improved Security Any authenticated users @WebServlet(“/test”) @ServletSecurity(@HttpConstraint(rolesAllowed={“**”})) public class TestServlet extends HttpServlet { ... } @agoncal 41
  42. #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
  43. #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
  44. #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
  45. #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
  46. Web Socket 1.0 (JSR 356)
  47. #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
  48. #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
  49. #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
  50. Expression Language 3.0 (JSR 341)
  51. #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
  52. #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
  53. JSF 2.2 (JSR 344)
  54. #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
  55. #32: Faces Flow New CDI flow scope @Named @FlowScoped("flow1") public class Flow1Bean implements Serializable { ... } @agoncal 55
  56. #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
  57. #33: Resource Library Contract 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-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
  59. #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
  60. JAX-RS 2.0 (JSR 339)
  61. #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
  62. #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
  63. #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
  64. #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
  65. #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
  66. #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
  67. #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
  68. JSON-P 1.0 (JSR 353)
  69. #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
  70. #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
  71. Batch 1.0 (JSR 352)
  72. #43: Jobs and steps 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-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
  75. #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
  76. JavaMail 1.5 (JSR 919)
  77. #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
  78. JCA 1.7 (JSR 322)
  79. #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
  80. Java EE 7 (JSR 342)
  81. #49: Default Resources Default datasource @Resource(lookup="java:comp/DefaultDataSource") private DataSource myDS; @Resource private DataSource myDS; @agoncal 81
  82. #49: Default Resources Default JMS factory @Resource(lookup="java:comp/DefaultJMSConnectionFactory") private ConnectionFactory myCF; @Resource private ConnectionFactory myCF; @agoncal 82
  83. #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
  84. #50: Get more information ;o) @agoncal 84
  85. Thanks www.antoniogoncalves.org antonio.goncalves@gmail.com @agoncal @pluralsight @devoxxfr @lescastcodeurs
  86. Q&A
  87. Thanks ● Arun Gupta @arungupta ● From our 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
Advertisement