Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Others Talk,
We Listen.
Reactive Java EE -
Let Me Count the
Ways!
Reza Rahman
Senior Architect
rrahman@captechconsulting.c...
CapTech
Full-service US national IT consulting firm that focuses on client best interests,
trust, servant leadership, cult...
Agenda
• What Exactly is Reactive?
• Touring Reactive in Java EE
• Bearable Reactive with Java SE 8?
Copyright © 2015 CapT...
What’s in a Name?
• “Reactive” fairly old but incredibly vague term
• A big hurdle to broad adoption by average developers...
What’s the Big Deal?
• Reactive has always been an important software engineering technique
• More responsive user experie...
Reactive Java EE
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
JMSJMS EJB 3EJB 3
Message-Driven
Beans
Messa...
JMS and Message Driven Beans
• JMS one of the oldest APIs in Java EE, strongly aligned with Reactive
techniques
• Message/...
JMS Send
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
@Inject JMSContext jmsContext;
@Resource(lookup = "j...
Message Driven Bean
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
@MessageDriven(activationConfig = {
@Acti...
Great Possibilities for JMS 2.1
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
@ApplicationScoped
@MaxConcur...
Asynchronous Session Beans
• Dead simple asynchrony at the component level
• Just an annotation on a POJO
• Great when all...
Asynchronous Session Bean
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
@Asynchronous
public void processPa...
Asynchronous Session Bean Client
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
@Inject ReportGeneratorServi...
@Asynchronous + CompletableFuture
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
@Asynchronous
public Comple...
CDI Events/Observers
• Compact, simple, elegant, type-safe events
• Essentially the observer pattern formalized via a DI f...
CDI Events
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
@Inject @CargoInspected Event<Cargo> cargoInspecte...
Asynchronous CDI Events
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
@Inject @CargoInspected Event<Cargo> ...
Asynchronous Servlets and NIO
• Asynchronous Servlets maximize throughput/thread utilization
• Decouple connection from re...
Asynchronous Servlet
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
@WebServlet(urlPatterns={"/report"}, asy...
Asynchronous Servlet NIO (Output Stream)
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
private void printRe...
Asynchronous Servlet NIO (Write Listener)
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
class ReportWriteLi...
Asynchronous Servlet NIO (Write Listener)
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
...
public void onW...
Asynchronous JAX-RS
• Asynchronous capabilities newly added to JAX-RS 2/Java EE 7
• Both on the server and client side
• S...
Asynchronous JAX-RS Resource
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
@Stateless
@Path("/reports")
pub...
Asynchronous JAX-RS Client
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
WebTarget target = client.target("...
Asynchrony/NIO in WebSocket
• WebSocket endpoints are inherently asynchronous/event-driven
• No thread-connection associat...
Asynchronous Remote WebSocket Endpoint
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
@Singleton @ServerEndp...
Java EE Concurrency Utilities
• Allows for lower-level threading/asynchronous capabilities in Java EE in a
safe, reliable,...
Managed Executor Service
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
@Path("/reports")
public class Repor...
Completable Future
• Futures and callbacks both have serious flaws
• Especially when it comes to significantly Reactive co...
Looks are Deceiving…
Person p = ...
Assets assets = getAssets(p);
Liabilities liabilities = getLiabilities(p);
Credit cred...
The Problem with Futures (and Callbacks)
Person p = ...
Future<Assets> f1 = executor.submit(() -> getAssets(p));
Future<Li...
CompletableFuture Basics
public CompletableFuture<Confirmation> processPayment(
Order order) {
CompletableFuture<Confirmat...
Functional Reactive to the Rescue?
CompletableFuture<Assets> getAssets =
CompletableFuture.supplyAsync(() -> getAssets(per...
More Possibilities
• Reactive JPA
• Last major reactive frontier for Java EE
• Async/NIO support in underlying database dr...
Java EE Guardians
http://javaee-guardians.io
@javaee_guardian
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
Summary
• Reactive programming well established technique, may be more important in
the future
• Java EE has long had rich...
Resources
• Java EE Tutorials
• http://docs.oracle.com/javaee/7/tutorial/doc/home.htm
• Java SE Tutorials
• http://docs.or...
Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
Upcoming SlideShare
Loading in …5
×

Reactive Java EE - Let Me Count the Ways!

98,913 views

Published on

As our industry matures there are pockets of increased demand for high-throughput, low-latency systems heavily utilizing event-driven programming and asynchronous processing. This trend is gradually converging on the somewhat well established but so-far not well understood term "Reactive".

This session explores how vanilla Java SE and Java EE aligns with this movement via features and APIs like JMS, MDB, EJB @Asynchronous, JAX-RS/Servlet/WebSocket async, CDI events, Java EE concurrency utilities and so on. We will also see how these robust facilities can be made digestible even in the most complex cases for mere mortal developers through Java SE 8 Lambdas and Completable Futures.

Published in: Technology

Reactive Java EE - Let Me Count the Ways!

  1. 1. Others Talk, We Listen. Reactive Java EE - Let Me Count the Ways! Reza Rahman Senior Architect rrahman@captechconsulting.com @reza_rahman
  2. 2. CapTech Full-service US national IT consulting firm that focuses on client best interests, trust, servant leadership, culture, professionalism and technical excellence. #28 in Vault's Consulting Top 50 #3 Best Consulting Internship #9 Best Overall Internship #1 in Meeting Client’s Needs #7 Best Firm to Work For #1 in Career Development Ranked for the 7th Consecutive Year Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  3. 3. Agenda • What Exactly is Reactive? • Touring Reactive in Java EE • Bearable Reactive with Java SE 8? Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  4. 4. What’s in a Name? • “Reactive” fairly old but incredibly vague term • A big hurdle to broad adoption by average developers • Sound core principals co-opted by marketing concerns? • Event/message driven • Asynchronous • Non-blocking • Overloaded concerns to simple core principals attempted to be added on more recently • Responsive, resilient/fault-tolerant, elastic/adaptive, scalable, etc • These are important concerns not that unique to Reactive techniques • Long met by Java EE at the runtime level Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  5. 5. What’s the Big Deal? • Reactive has always been an important software engineering technique • More responsive user experience • High throughput, optimal hardware/CPU/IO utilization • Loose coupling, complex event processing • Will potentially become more important • Internet of Things (IoT), device-to-device communication • Mobile, large global concurrent user bases, more chatty applications • Not necessarily a panacea • Asynchronous, event driven code is always harder to write, maintain than synchronous, blocking code • Horizontal/hardware scalability can be a cheaper/more maintainable answer Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  6. 6. Reactive Java EE Copyright © 2015 CapTech Ventures, Inc. All rights reserved. JMSJMS EJB 3EJB 3 Message-Driven Beans Message-Driven Beans Asynchronous Session Beans Asynchronous Session Beans CDICDI EventsEvents ObserversObservers ServletServlet AsynchronousAsynchronous NIONIO JAX-RSJAX-RS Async on ServerAsync on Server Async on ClientAsync on Client WebSocketWebSocket Async Remote Endpoints Async Remote Endpoints Concurrency Utilities Concurrency Utilities
  7. 7. JMS and Message Driven Beans • JMS one of the oldest APIs in Java EE, strongly aligned with Reactive techniques • Message/event driven, asynchronous • Loosely coupled, reliable, transactional, durable, fault tolerant, error tolerant, clustered • Message Driven Beans primary vehicle for JMS message handling • Just POJOs with annotations • Transactional, thread-safe, throttled, reliable, load-balanced, fault- tolerant, error-tolerant Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  8. 8. JMS Send Copyright © 2015 CapTech Ventures, Inc. All rights reserved. @Inject JMSContext jmsContext; @Resource(lookup = "jms/HandlingEventRegistrationAttemptQueue") Destination handlingEventQueue; ... public void receivedHandlingEventRegistrationAttempt( HandlingEventRegistrationAttempt attempt) { ... jmsContext.createProducer() .setDeliveryMode(DeliveryMode.PERSISTENT) // The default :-) .setPriority(LOW_PRIORITY) .setDisableMessageID(true) .setDisableMessageTimestamp(true) .setStringProperty("source", source) .send(handlingEventQueue, attempt); }
  9. 9. Message Driven Bean Copyright © 2015 CapTech Ventures, Inc. All rights reserved. @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/HandlingEventRegistrationAttemptQueue"), @ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "source = 'mobile'")}) public class HandlingEventRegistrationAttemptConsumer implements MessageListener { ... public void onMessage(Message message) { ... HandlingEventRegistrationAttempt attempt = message.getBody(HandlingEventRegistrationAttempt.class); ... } }
  10. 10. Great Possibilities for JMS 2.1 Copyright © 2015 CapTech Ventures, Inc. All rights reserved. @ApplicationScoped @MaxConcurrency(10) public class HandlingEventRegistrationAttemptConsumer { @JmsListener( destinationLookup="jms/HandlingEventRegistrationAttemptQueue", selector="source = 'mobile'", batchSize=10, retry=5, retryDelay=7000, orderBy=TIMESTAMP) public void onEventRegistrationAttempt( HandlingEventRegistrationAttempt... attempts) { ... } }
  11. 11. Asynchronous Session Beans • Dead simple asynchrony at the component level • Just an annotation on a POJO • Great when all that is required is greater throughput or responsiveness • Still transactional, thread-safe, throttled • Not loosely coupled, persistent, fault tolerant or error tolerant (client must explicitly handle errors) Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  12. 12. Asynchronous Session Bean Copyright © 2015 CapTech Ventures, Inc. All rights reserved. @Asynchronous public void processPayment(Payment payment) { // CPU/IO heavy tasks to process a payment } @Asynchronous public Future<Report> generateReport(ReportParameters params) { try { Report report = renderReport(params); return new AsyncResult(report); } catch(ReportGenerationException e) { return new AsyncResult(new ErrorReport(e)); }
  13. 13. Asynchronous Session Bean Client Copyright © 2015 CapTech Ventures, Inc. All rights reserved. @Inject ReportGeneratorService reportGeneratorService; ... Future<Report> future = reportGeneratorService.generateReport(parameters); ... if (future.isDone()) { Report report = future.get(); ... } ... future.cancel(true);
  14. 14. @Asynchronous + CompletableFuture Copyright © 2015 CapTech Ventures, Inc. All rights reserved. @Asynchronous public CompletableFuture<Confirmation> processPayment(Order order) { ... Confirmation status = ...; return CompletableFuture<Confirmation>.completedFuture(status); } paymentService .processPayment(order) .thenAccept( confirmation -> System.out.println(confirmation));
  15. 15. CDI Events/Observers • Compact, simple, elegant, type-safe events • Essentially the observer pattern formalized via a DI framework and annotations • Offers excellent solution to loose-coupling, type-safe filtering/chaining and asynchrony (but not much else) Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  16. 16. CDI Events Copyright © 2015 CapTech Ventures, Inc. All rights reserved. @Inject @CargoInspected Event<Cargo> cargoInspected; ... public void inspectCargo(TrackingId trackingId) { ... cargoInspected.fire(cargo); } public void onCargoInspected( @Observes @CargoInspected Cargo cargo) { @Qualifier @Retention(RUNTIME) @Target({FIELD, PARAMETER}) public @interface CargoInspected {}
  17. 17. Asynchronous CDI Events Copyright © 2015 CapTech Ventures, Inc. All rights reserved. @Inject @CargoInspected Event<Cargo> cargoInspected; ... public void inspectCargo(TrackingId trackingId) { ... cargoInspected.fireAsync(cargo); } public void onCargoInspected( @Observes(async=true) @CargoInspected Cargo cargo) {
  18. 18. Asynchronous Servlets and NIO • Asynchronous Servlets maximize throughput/thread utilization • Decouple connection from request thread • Return request thread back to pool • Handle IO/CPU heavy work on separate backend thread • Close cached connection when done • NIO removes possible thread blocks during slow read/write • Get notified when the IO channel might be ready • Only read/write when IO channel is ready • Obvious need when Servlet IO is particularly heavy, otherwise a complex solution Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  19. 19. Asynchronous Servlet Copyright © 2015 CapTech Ventures, Inc. All rights reserved. @WebServlet(urlPatterns={"/report"}, asyncSupported=true) public class AsyncServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) { ... final AsyncContext asyncContext = request.startAsync(); asyncContext.start(() -> { ReportParameters parameters = parseReportParameters(asyncContext.getRequest()); Report report = generateReport(parameters); printReport(report, asyncContext); asyncContext.complete(); }); } }
  20. 20. Asynchronous Servlet NIO (Output Stream) Copyright © 2015 CapTech Ventures, Inc. All rights reserved. private void printReport(Report report, AsyncContext context) { ServletOutputStream output = context.getResponse().getOutputStream(); WriteListener writeListener = new ReportWriteListener( output, report, context); output.setWriteListener(writeListener); }
  21. 21. Asynchronous Servlet NIO (Write Listener) Copyright © 2015 CapTech Ventures, Inc. All rights reserved. class ReportWriteListener implements WriteListener { private ServletOutputStream output = null; private InputStream input = null; private AsyncContext context = null; ReportWriteListener(ServletOutputStream output, Report report, AsyncContext context) { this.output = output; this.input = report.asPdfStream(); this.context = context; } ...
  22. 22. Asynchronous Servlet NIO (Write Listener) Copyright © 2015 CapTech Ventures, Inc. All rights reserved. ... public void onWritePossible() throws IOException { byte[] chunk = new byte[256]; int read = 0; while (output.isReady() && (read = input.read(chunk)) != -1) output.write(chunk, 0, read); if (read == -1) context.complete(); } public void onError(Throwable t) { context.complete(); t.printStackTrace(); } }
  23. 23. Asynchronous JAX-RS • Asynchronous capabilities newly added to JAX-RS 2/Java EE 7 • Both on the server and client side • Server-side essentially identical to Servlet 3 async • Nicer declarative syntax • Client API async capabilities very symmetric to synchronous API • Both Futures and callbacks supported • JAX-RS server-side NIO promised for Java EE 8 Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  24. 24. Asynchronous JAX-RS Resource Copyright © 2015 CapTech Ventures, Inc. All rights reserved. @Stateless @Path("/reports") public class ReportsResource { ... @Path("{id}") @GET @Produces({"application/pdf"}) @Asynchronous public void generateReport( @PathParam("id") Long id, @Suspended AsyncResponse response) { ResponseBuilder builder = Response.ok(renderReport(id)); builder.header("Content-Disposition", "attachment; filename=report.pdf"); response.resume(builder.build()); } }
  25. 25. Asynchronous JAX-RS Client Copyright © 2015 CapTech Ventures, Inc. All rights reserved. WebTarget target = client.target("http://.../balance")... Future<Double> future = target.request() .async().get(Double.class)); ... Double balance = future.get(); WebTarget target = client.target("http://.../balance")... target.request().async().get( new InvocationCallback<Double>() { public void complete(Double balance) { // Process balance } public void failed(InvocationException e) { // Process error } });
  26. 26. Asynchrony/NIO in WebSocket • WebSocket endpoints are inherently asynchronous/event-driven • No thread-connection association in the first place • True for server and client side • Writes/sends can be made asynchronous for better throughput • Very symmetric API for both sync and async • Futures or callbacks supported • Good idea to use asynchronous send in most cases Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  27. 27. Asynchronous Remote WebSocket Endpoint Copyright © 2015 CapTech Ventures, Inc. All rights reserved. @Singleton @ServerEndpoint(value = "/chat"...) public class ChatServer { ... @OnOpen public void onOpen(Session peer) { peers.add(peer); } @OnClose public void onClose(Session peer) { peers.remove(peer); } @OnMessage public void onMessage(ChatMessage message) { for (Session peer : peers) { ...peer.getAsyncRemote().sendObject(message)... } } }
  28. 28. Java EE Concurrency Utilities • Allows for lower-level threading/asynchronous capabilities in Java EE in a safe, reliable, managed fashion • Very specialized code, custom workloads • Fairly small extension of Java SE Concurrency Utilities • ManagedExecutorService • ManagedThreadFactory Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  29. 29. Managed Executor Service Copyright © 2015 CapTech Ventures, Inc. All rights reserved. @Path("/reports") public class ReportsResource { @Resource ManagedExecutorService executor; ... @Path("{id}") @GET @Produces({"application/pdf"}) public void generateReport( @PathParam("id") Long id, @Suspended AsyncResponse response) { executor.execute(() -> { ResponseBuilder builder = Response.ok(renderReport(id)); builder.header("Content-Disposition", "attachment; filename=report.pdf"); response.resume(builder.build()); } } }
  30. 30. Completable Future • Futures and callbacks both have serious flaws • Especially when it comes to significantly Reactive code • Java SE 8 CompletableFuture significantly better for Reactive programming • Non-blocking, event-driven, composable and functional (via lambdas) • Easy to integrate with Java EE 7 managed executors • Java EE 8 should embrace CompletableFuture uniformly Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  31. 31. Looks are Deceiving… Person p = ... Assets assets = getAssets(p); Liabilities liabilities = getLiabilities(p); Credit credit = calculateCreditScore(assets, liabilities); History history = getHealthHistory(p); Health health = calculateHeathScore(history); Coverage coverage = underwrite(credit, health); Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  32. 32. The Problem with Futures (and Callbacks) Person p = ... Future<Assets> f1 = executor.submit(() -> getAssets(p)); Future<Liabilities> f2 = executor.submit( () -> getLiabilities(p)); Future<Credit> f3 = executor.submit( () -> calculateCreditScore(f1.get(), f2.get())); // The unrelated calls below are now blocked for no reason Future<History> f4 = executor.submit(() -> getHealthHistory(p)); Future<Health> f5 = executor.submit( () -> calculateHeathScore(f4.get())); // Unrelated paths join below Future<Coverage> f6 = executor.submit( () -> underwrite(f3.get(), f5.get())); Copyright © 2015 CapTech Ventures, Inc. All rights reserved. Callbacks don’t block, but introduce callback hell… https://github.com/m-reza-rahman/reactive_javaee/blob/master/CallbackHell.java
  33. 33. CompletableFuture Basics public CompletableFuture<Confirmation> processPayment( Order order) { CompletableFuture<Confirmation> future = new CompletableFuture<>(); executor.execute(() -> { Confirmation status = ... future.complete(status); }); return future; } Copyright © 2015 CapTech Ventures, Inc. All rights reserved. paymentService .processPayment(order) .thenAccept( confirmation -> System.out.println(confirmation));
  34. 34. Functional Reactive to the Rescue? CompletableFuture<Assets> getAssets = CompletableFuture.supplyAsync(() -> getAssets(person)); CompletableFuture<Liabilities> getLiabilities = CompletableFuture.supplyAsync(() -> getLiabilities(person)); CompletableFuture<Credit> calculateCreditScore = getAssets.thenCombineAsync(getLiabilities, (assets, liabilities) -> calculateCreditScore(assets, liabilities)); CompletableFuture<Health> calculateHeathScore = CompletableFuture.supplyAsync(() -> getHealthHistory(person)) .thenApplyAsync(history -> calculateHeathScore(history)); Coverage coverage = calculateCreditScore.thenCombineAsync(calculateHeathScore, (credit, health) -> underwrite(credit, health)).join(); Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  35. 35. More Possibilities • Reactive JPA • Last major reactive frontier for Java EE • Async/NIO support in underlying database driver/JDBC/Java SE prerequisite Copyright © 2015 CapTech Ventures, Inc. All rights reserved. CompletableFuture<List<Country>> countries = em.createQuery("SELECT c FROM Country c", Country.class) .async().getResultList(); • Reactive MVC • Similar to basic model in JAX-RS • Reactive JSF conceptually tough • Reactive streams
  36. 36. Java EE Guardians http://javaee-guardians.io @javaee_guardian Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  37. 37. Summary • Reactive programming well established technique, may be more important in the future • Java EE has long had rich support for Reactive techniques • Things should be improved even more with Java EE 8 • Java SE 8 helps quite a bit to make the programming model easier • Beyond Java EE application servers provide clustering, load-balancing, replication, failover, bandwidth throttling, resource pooling, thread pooling, caching, etc • Be careful – Reactive is not an easy approach to take Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  38. 38. Resources • Java EE Tutorials • http://docs.oracle.com/javaee/7/tutorial/doc/home.htm • Java SE Tutorials • http://docs.oracle.com/javase/tutorial/ • Digging Deeper • http://docs.oracle.com/javaee/7/firstcup/doc/home.htm • https://glassfish.java.net/hol/ • http://cargotracker.java.net • Java EE Transparent Expert Groups • http://javaee-spec.java.net • Java EE Reference Implementation • http://glassfish.org Copyright © 2015 CapTech Ventures, Inc. All rights reserved.
  39. 39. Copyright © 2015 CapTech Ventures, Inc. All rights reserved.

×