You probably heard of "MicroProfile" launch some months ago. It is "just" JAX-RS + CDI + JSON-P so it looks easy to build and maintain on your own and therefore for a company it sounds like an opportunity to get rid of a very expensive support or even just server costs for some of them.

Well, it is only half true. If you are able to assign this responsability to one team on your company this can be valid but if you are 100% business oriented it will be quite hard. Let's see what are the challenges there and why you should rather either continue to pay for your server - whatever you choose - and be part of Open Source projects to make it reliable.

Custom + quality = high investment

Let's use the microprofile as an example of that statement but keep in mind more you will add specifications/features to the game, more complicated it will be, the curse is likely exponential and not linear!

Choose the implementations

First challenge you will hit is to choose the implementations you want: jersey, Resteasy or CXF for JAX-RS? Reference implementation or Johnzon or Jackson or ... for JSON-P? Weld or OpenWebBeans for CDI? etc...

This looks easy but each choice can be impacting for other ones since each vendor has some natural preference and integration is more or less natural depending which choice you do. Therefore you can need to build a quite complex compatibility matrix to have a valid choice making the integration smooth.

This is the first pitfall and requires some cost to overpass it and keep in mind you will have to pay it for each significative upgrade.

Let's assume you did it and chose an Apache stack, you will likely end up with these implementations:

Implementations
Specification Implementation
JAX-RS CXF
CDI OpenWebBeans
JSON-P Johnzon

Find the right dependencies

Each vendor try to have the modularity he thinks right. This means that once the stack choice done you need to find the right dependencies for your runtime. This is not the hardest part but this is another cost to pay before getting started. Some will be trivial but some other can require some knowledge and even to enter into the code to understand if you need a module or not.

A Specification can hide another one

At that point you are very happy to have done the choices and you can ask a developer (if not doing it yourself) to implement the microprofile.

You start, let's assume it is smooth, you compile and...nothing happens or you have exceptions. Of course cause JAX-RS - for instance - doesn't define a transport even if it is quite linked to HTTP. With CXF for instance you can use JAX-RS with HTTP (through Servlet or not), through JMS or even "locally" (in memory bus).

What does that mean? You are almost back to the first step: choose a transport....and once decided an implementation of that transport.

For microprofile, most of the time, you will decide to go with HTTP transport so you need to choose a HTTP server. We'll skip the "housemade" ones and concentrate on Servlet ones which are "well-known" so we need to decide mainly between Tomcat and Jetty. We decided in the first step to go with an Apache stack so we natural end up with Tomcat, right?

You add tomcat, you run and it fails. Why? Cause Tomcat requires since some versions jaspic too. Note that depending the version and integration you use OpenWebBeans can require Expression Language too.

What does that mean? Your JAX-RS+CDI+JSON-P quickly becomes JAX-RS+Servlet+Jaspic[+EL]+CDI+JSON-P. Not a big deal right? Well it also means you need to maintain the unexpected part to ensure it - at least - runs with the mandatory choices.

Cleanup the stack

Once you got all dependencies you probably have some useless dependencies making the stack bigger than needed and potentially leading to conflicts with the business code. Then you need to ensure to remove all these libraries from your runtime. This requires a good knowledge of the stack and its usage, don't underestimate this part!

Configure the boostrap

At that point you can think you are done? Almost but not yet. You still need to ensure JAX-RS is configured and started with a deployment, that JSON-P is used by JAX-RS etc... With microprofile - which is a very simple stack - it already makes these steps:

  • CDI starts
  • JAX-RS deploys and can use CDI
  • JSON-P is used by JAX-RS

If you add the fact we went with Tomcat you can add:

  • Servlet container is started
  • JAX-RS is deployed in the Servlet container
  • CDI reuse Servlet deployment (to scan properly web applications). Here for instance, OpenWebBeans can't reuse war:file:... URLs of Tomcat and needs to enforce unpackWARs property of Tomcat otherwise you don't have scanning at all.
  • ...

Keep a good integration

Once you did everything you think you are done and can start to hack a business applicaton, right? It would work but you can notice your application is slow to deploy. This is important cause it makes your tests cycles slower and therefore your delivery slower.

What happens? Each technology is not integrated together. Concretely Tomcat scans for the Servlet container (@WebServlet@WebListener@WebFilter, @HandlTypes...), CDI scans for the CDI container (all your beans concretely), potentially JAX-RS scans for resources (@Path) etc...

This means you can check your classloader/classpath 3 times for each deployment. If you deploy nothing it is fine but if you deploy a real application with dependencies you can bet it will be slow since the scanners will need to open all jar/folders in your classloader. For small jars it can be fast but suppose you use bouncycastle which is signed and big then you will be slow x3!

Scanning is a single example of the integration needs. Another classical one is the logging! Each library you choose can use its own logging framework. Best case you will need to use the pluggability designed for that purpose to ensure they all log to the same logger implementation but in some cases you will just be stucked to one implementation!

Produce launchers

You now have an usable server...but how should it be launched in production and configured? You need to write a CLI or a script letting operation team(s) configuring the server for production purpose. This is another debt you will need to create and maintain.

Development stack

Assume you passed all these steps, then you need to keep your server usable. Developers are used to rely on a maven or gradle plugin to start the server, to have a JUnit/TestNG/Arquillian integration for their tests etc... As much integrations you will need to reimplement and maintain.

Maintenance

Now you built a full stack, you still need to maintain your stack and ensure you can upgrade when new releases of your stack is released. The minimum reason there are security fixes but new features can also be part of the choice. Since you needed to integrate with internals it requires to follow all changes and have some harnessing of your server which is another cost to take into account choosing to go with a proprietary home made solution.

How to have its own server then?

Even if it looks simple to build a small stack and that you will make very fast some progress, completing the integration to ensure it is usable is a real challenge for a company getting revenue from that. So the business game will be to ensure the responsability of the server is owned by somebody else.

In this game you have two choices:

  • pay a lot a company to do it
  • pay an employee to participate full or part time to an open source project you will use

Pay for support

The first solution depends the relationship you have with the company you choose and what you accept to pay. Keep in mind you acn pay a lot to get almost no response :(. Also part of this choice you need to ensure the company is actually really active in the stack you will rely on: some companies sell support on a server they never wrote a line of!

Interact with open source

The alternative is to work with open source. There you need to ensure the community is healthy. This can mean a lot of things and you need to ensure you define what it means for your needs. Here some common criteria:

  • the community is not owned by a single backing company
  • the community commits regularly (X/week)
  • the community releases regularly (X/year)
  • the mailing list is active
  • community support is reactive (keep in mind there you don't have any guarantee so that's an overall feeling)
  • the product adds regularly new features
  • the product follows what it implements: for instance if it implements a EE specification, it follows the EE releases "fast enough" for the company
  • ...

This allows you to choose a community and then your investment will be to participate. Depending the one you choose it can just be through the mailing list or go to sending patches/code/documentation/pull-requests and really be active on the product.

Conclusion

"This is not because it looks easy than it is" is probably the summary of this post. Microprofile looks quite trivial on the paper but for a company it is already a huge investment.

This is why it is probably good, before deciding to go "home made", to review what is done out there and maybe choose to integrate a community instead of going alone and even potentially open sourcing later your code hoping you will get some help - this rarely happens.

Side note on the microprofile initiative : OpenWebBeans community is working on a proposal - code name "microwave" - you can checkout at http://svn.apache.org/repos/asf/openwebbeans/microwave/trunk/. It globally reuses the stack described in this post. Don't hesitate to send a mail on that topic on openwebbeans lists if you want to be part of this initiative!

From the same author:

In the same category: