Win a copy of TDD for a Shopping Website LiveProject this week in the Testing forum!

Romain Manni-Bucau

Author
+ Follow
since Feb 18, 2018
Romain is a Senior Software Engineer who works with and contributes to JavaEE and more particularly Apache EE projects since 2011. He is a committer on several of these projects like Apache TomEE, OpenWebBeans, Johnzon, BatchEE, OpenJPA, BVal, Meecrowave...
Cows and Likes
Cows
Total received
5
In last 30 days
0
Total given
0
Likes
Total received
5
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Romain Manni-Bucau

Hi guys,

thanks a lot for the warm welcoming, don't hesitate to open a new thread on JavaEE 8 and performances, I'll be happy to try to answer.

Romain
Ok Divya,

the main changes in my opinion is the fact specs now can be reactive (this is a mix of JavaEE which is friendly to that and Java 8 which got the CompletionStage). This is slower than a sequential programming in general for 1 thread but it scales way more so you will be able to handle more users on the long run on a single instance and still be responsive properly. The fact Java 8 also improved a lot the GC makes JavaEE 8 faster in general.

In terms of cutting edge feature the HTTP2 support allows to push resources and html at once avoiding N HTTPS requests which is a huge boost as well for clients.

Romain
Hi Divya,

I'm not sure you ask about the book creation, the platform update or the performance factors you want to consider on a EE 8 app so I'll try to give some points for each of these options and let you
ask more questions on the particular one you are interested in.

Book creation: the main rational was to try to give the needed entry points and keys for anyone to work on performances on any JavaEE 8 application efficiently and autonomously. It was not about giving particular solutions which rarely work in all cases but more the way to understand any case and work on them.

JavaEE 8 update: main new features are about the language evolution and the modern programming models. This means more reactivity (CompletionStage etc), and java 8 types (dates, ...) support in specifications. There are also some new specification like JSON-B (java-json mapping).

Optimization factors in JavaEE 8 applications: avoid locks on the main codepath and rely on the platform when possible for the locking and thread safety, reactivity when possible (websocket, CDI async events, JAX-RS AsyncResponse, ...), tunning as usual (GC, connection pools, instance pools, ...), caching where possible.

Romain
Hi Srinivas,

Security would be worth a whole book by itseld. The book doesn't deal directly with the cached data security but gives some hints on why to use a remote or local cache which is the main concern in terms of security.
There is not portable security accross cluster in JavaEE (this is vendor specific) and a bit outside the book scope which is more about ensuring it works as expected and you don't get surprises adding cache.

The security topic is interesting because you have all extremes:

- You need to not use String but char[] for sensitive data to erase them (set all items to 0) once used
- You don't need security except for incoming requests

Concretely on a Java platform - and actually any computer platform today - you can access the whole memory so if you want to hack the volatile data you can and preventing to store sensitive data a long time is valuable however if you assume somebody can do that
you also have to assume he can do anything he wants including handling your response the way he wants. I'm not saying it is easy but at the same level of intrusion.

The only way to protect yourself is to use a security manager which will limit a lot what somebody can do inside (or not) your JVM but it also slows down so much the application that today almost nobody is using it in production.

Personally I tend to ensure the outbounds of my application are really secured:

- HTTP has security
- JMS doesn't use java serialization or equivalent (see the 0-day vulnerability) and connection is secured
- if using a local file, ensure it is signed or so etc...

Going deeper in the security - for instance using some crypto for locally cached data - would be an overkill which can lead to not be worth caching at all and is not really useful from a security perspective since if you need to be able to decrypt it an attacker able to access the cache would be able to do it as well.

Romain
Hi Alex,

Globally yes, the small side note is that not portable features can depend on the container. But concretely Spring is embed - in terms of design - so depends on EE in general to scale.
If you remove EE from Spring you don't run anymore in 90% of the cases. So it is really about the facing API more than the technology stack.  You will likely always use both
but as a developer you can only see Spring but your ops will see EE.

Romain
Hi Paul and Tim,

@Paul: yes the pools are tackled in the book (http, stateless, ee concurrency utilities, connection, ...).

Tim is also right: you need to verify any assumption and not work against some "I suppose that". This is the approach I took in the book and why I spend time explaining how to instrument the application
to only work on actual issues. The "don't sit down" is also very true to avoid surprises and the reason I explainin the book how to write tests to validate the performances but also run them (which environment etc).


Romain

Hi R.J.,

The target audience for the book is developers and ops people. The approach is to give the needed keys to anyone to be able to work on performances of any JavaEE application.
Examples are often related to the web but most of the book can be applied to daemon and batch applications as well.

Cheers,
Romain
Hi Barbara,

Developping your own annotation is not more complicated than creating a class by itself (replace "class" by "@interface" and you are almost done).

However JavaEE gives you the ability to bind some behavior behind this API, for example:

- CDI will let you define an @Interceptor annotation which will enrich a method/constructor execution (you can add metrics around the execution, you can add logging, security validation, ...)
- Bean Validation will let you add some validation on fields, parameters or classes as you mentionned
- JAX-RS/Servlet will let you add some filters around stream processing to gzip the response, log in a user etc...
- ....

So yes, with JavaEE you have a lot of power to bind any of your business needs pretty easily behind a simple annotation.

Romain
HI Germán,

Yes, the idea is to center the topic on the performances and to show how to work on them in the context of a JavaEE application.
The chapter explains some good - generic - patterns and applies them to JavaEE with concrete examples. On concrete example
is the "context" handling and how using bulkhead can require to use message passing pattern to ensure you have the right state all along the processing chain.

Romain
Hi Vaibhav,

Yes, JMS is the specification (which defines the API and the behavior associated) and ActiveMQ (5 or Artemis which is the version 6) is an implementation of that API.

ActiveMQ/Kafka/RabbitMQ are all message brokers. In these three only Kafka has no JMS support at all. However it is important to mention that ActiveMQ is a JMS provider so intends to implement the specification whereas RabbitMQ is a broker before all and has a JMS plugin. This implies the JMS support is not a very high priority. Concretely today it only supports JMS 1.1 whereas ActiveMQ Artemis is JMS 2.0 already.

Romain
Hi Alex,

This is a good question. What is important to see is that the scope of JavaEE and Spring (boot or not) are overlapping but not the exact sames.

JavaEE covers the very low levels to the "medium" layers - let's say "usable layer", whereas Spring covers from just before this medium layer to the very fancy and advanced layer.
To put some features on that  statement:

- JavaEE has in its stack the connection (under Servlet API for HTTP or JMS for a more raw connection type), Spring doesn't have that and always relies on a 3rd party
- JavaEE has JPA which allows to abstract a database under an object model but Spring doesn't have that
- Spring has spring-data which allows to go further than JPA with a more advanced API (JavaEE had CMP which was the same design but far before annotation time which led to something poorly usable)
- JavaEE has CDI and Spring has spring-context to manage beans (this part is concurrent)

These small examples intend to show that both technologies have competing solutions for parts of an application for historical and technical reasons but actually both go well together. Spring is even designed to reused the portable parts of JavaEE and to be deployable in a JavaEE container (even Spring Boot).

You mentionned Spring Boot but if you have a web server you will likely use Tomcat, Jetty or Undertow which are all Servlet container (so a JavaEE technology).

Historically you can also see that they both helped each others:

- JavaEE created CDI because its programming model was too old compared to its competitors (Spring and Seam): Spring inspired JavaEE
- Spring created Spring Boot because its programming model was too complicated (too much configuration) compared to JavaEE: JavaEE inspired Spring

So in my opinion, and even if some of the guys of "both sides" like to put them one against the other, Spring and JavaEE don't really compete. It is perfectly fine to hide JavaEE behind Spring (or Spring Boot) but you still use it and need to understand what it does (otherwise you will use the old N+1 queries pattern with spring-data  for instance). They also help each other - even if it is not always intended ;).

In terms of stack you can discuss that Spring has more advanced API but that it brings back a huge dependency stack etc...
On my side I tend to make it simpler: if you are used to Spring then use Spring, if you know JavaEE then use a JavaEE container and if you miss a few feature look at DeltaSpike which brings a set of utilities for common needs in a natural fashion for JavaEE.

Performances of both stacks are very close (<5% of difference between a spring-web and JAX-RS applications on Apache Tomcat+Spring/Apache TomEE), so in my humble opinion the efficiency to look for is the developers one before all.

Romain
Hi Paul,

From my experience, the biggest bottleneck in web applications is always the actual backend. You can see some "locking" before you see the backend as the biggest hotspot but you always end up pretty quickly to rework the application
to hit the database (RDBMS or NoSQL) as a bottleneck. Why that? Mainly because it is a *remote* system. This has a direct consequence in our modern world: microservices becomes a bottleneck driven architecture since most of the system parts are remote.

There is no magic solution when you work with a remote system but some practises can help to limit the effect on the performances:

- If you have reference data (understand by that, data which don't change very often or have a very high accuracy requirement) then you can cache them *locally* and bypass the actual backend (database or remote microservice) for some time. This is generally the solution giving the best results but has the high entry cost to require you accept to have potentially outdated data for a period of time.
- If you control the infrastructure you can ensure the network is adapted to the performances you want to reach and that communicating services (your application and a database for instance) are in the same subnetwork to limit the network latency as much as possible
- Often forgotten but if you are in a microservice architecture you can just merge the microservices in the same JVM - either in a single application or if you need isolation in a single container with classloader isolation (one war per microservice). In the worse case you will use the local loop (localhost) to communicate which will be faster than any other network interface and in the best case you can go through local invocations avoiding you the network connection+serialization roundtrips.
- Ensure the connections are reused. HTTP is stateless but it doesn't mean you have to create a new socket for each remote invocation. If you always call the same remote system - which is generally the case - then ensure to have a connection pool which is correctly sized for your application (tip: set the wait timeout to 0 to retrieve a connection, it will throw a connection if too low and let you size it correctly). For HTTP the gain will already be important but for HTTPS (which should be the case everywhere today) the gain will be huge because the SSL handshade is a slow operation (since it implies cryptographic operations).

Romain
Hi Thomas,

When it comes to concurrency, the goal is to avoid locks as much as possible. A Simple example is the cache one: if you put some caching to make some database calls faster allowing to skip them but that the cache access requires a lock on the whole application
then your optimization will quickly become a degradation and instead of seeing a performance improvement you will see worse figures.

What is interesting with Java 8 is that there are new API allowing to handle that more smoothly and naturally.
The nice part of these new API is that they have been integrated with JavaEE (or are easy to integrate) pretty quickly allowing you to use the best of both worlds without much efforts.

To illustrate that I'll take a simple example: until Java 7/JavaEE 7 the asynchronism was mainly handled through futures and there was no natural way to be notified of the completion of the asynchronous task.
Only available option was to block to get the result (or to test if you have the result). This is quite a poor solution and enforces you to "poll" the result to know it is available which implies using another thread (or thread pool) in the best case.
Since Java 8 you have the CompletionStage (we often know the CompletionFuture which is the default implementation of a CompletionStage). The nice thing about that new JavaSE API is it allows to chain some processing on the result before it is available. So no need of this old polling pattern anymore and no need to become blocking at all, you can be 100% reactive and wait it is available to process the data (convert them, store them etc...).
CDI 2.0 embraced this API with its asynchronous event API and firing an asynchronous CDI event you retrieve the result as a CompletionStage which allows you to chain all the processing without waiting for the data to be here.
Servlet layer has since JavaEE 6 an AsyncContext which is used by JAX-RS 2.0 (JavaEE 7) to handle its AsyncResponse. All that means you can now (JavaEE 8) be asynchronous from the network layer (NIO) using JAX-RS AsyncResponse and complete your (http) response thanks to a CompletionStage you got from CDI for instance. The threads will only be used to process data and not to wait for some data availability!

This is only one way to become reactive in JavaEE 8, in the book I show how to do it from a WebSocket layer for instance, but the spirit is the same.

In terms of performance this has indeed an overhead but you quickly gain in scalability become you optimize the CPU and threads usage (goal is to use it only when you have some processing to do and not to wait for a response to come).

With this new development pattern, the tricky part is probably the exception handling. It is not more a try/catch but you need to rely on callbacks (as for the main processing) to do it. It is not hard by itself but requires to change a bit your mind
so can need some time to be used to that kind of thinking.

The other tricky part in EE with concurrency can be the context propagation. When you use ee concurrency utilities (the thread pools for JavaEE to summarize it), you will execute some task in another thread than the caller in general.
The question is: what is my "EE context" in this new thread? Is my @RequestScoped bean the same as before? etc... All that can lead to some surprises. For instance if you use a @RequestScoped which is injected in a bean which is triggering a lambda using the request scoped field then the lambda will likely use another instance of the request scoped bean because you will get one instance per "thread". The book has a part explaining what the container does which should give you the needed knowledge to let you identify this kind of issue quickly.

This is the approach I took with this book: give to the reader enough knowledge to let him not be lost when needing to work on an application, even not having coded it himself.

Romain