Stop repeating “heavyweight”
- Transfer
Author: Sebastian Daschner
Original: https://blog.sebastian-daschner.com/entries/stop_saying_heavyweight (April 09, 2016)
Translation: Semyon Soldatenko
When developing enterprise Java applications, you have to choose whether to use Java EE or some other “lightweight” framework . But what makes a corporate framework lightweight?
As developers, we mainly need to take care of the development process. Our time is precious (and expensive) and the less time we spend on overhead, the better.
This time mainly consists of the time to compile, deploy and test the application - locally or in a special environment. To keep the time for the full circle as short as possible, the compilation should not last more than a few seconds. Yes seconds.
Using Java EE has the great advantage that the developer can rely on a standard that allows you to develop based on APIs - basically just interfaces and annotations - while the actual implementation of the framework is not included in the application. Actually, the Java EE dependency is “delivered” by the application server, which means that it is required only for compilation, and is not included in the installation package. This has a side effect which is that the war file basically remains empty - it contains only the class files of your application. And everything else must be provided by the Java EE implementation.
As long as you remain skinny and minimalistic, which means using only the Java EE API (7) and not third-party dependencies - unless there is a real need for your business cases - you can achieve compilation time within a few seconds. The main reasons for slow assembly are either slow (integration) tests or large installation packages, which accordingly require a lot of copying.
A typical simple Java EE war file is about several hundred kilobytes in size compared to 50 or more megabytes if you supply an implementation of even a small (well, you know, “lightweight”) framework with it.
If you take into account the application server plus your application then the result for the Java EE case will be greater. But: In general, the development process will be faster, since every time you build, kilobytes are created. The application server is usually already installed on your development machine — or in any other environment — and the moving parts remain small. As a result, we get a shorter build and deployment time both on the developer's machine and on the Continuous Integration server. Also: When you place your installation packages in a centralized repository (Nexus or Maven central, etc.), you also save both time and traffic.
All modern Java EE 7 application servers (such as Wildfly, TomEE, Glassfish / Payara, WLP) show a very short time for application deployment. As part of their modular system (such as OSGi), they can only download the necessary components and run the application in a few seconds.
Comparing with another framework (such as Spring) running on Tomcat, the shortest deployment time that I have ever measured was at least 15 seconds - for a simple "Hello World" application - when measured on the same machine.
In the new world of microservices, it is customary to supply applications in the form of independent jar containing both the developed application and the implementation of the framework. In Java EE, this can be achieved using technologies like Wildfly Swarm or TomEE Embedded.
However: As I said above, I do not recommend making your installation packages so large. The biggest problem with this approach is the build time, since you have to copy a lot of things each time from A to B. Also: When deploying using containers like Docker, it becomes unimportant whether your application comes with the server or the server is part container.
If the container already includes the installed application server, you can save a lot of build time (container). In this case, your basic image does not change, and you only add your (only a few hundred-kilobyte-byte) application - which is achieved almost without a waste of time.
Since the days of old J2EE, there is a myth that "heavy" application servers consume a lot of memory as soon as they start. Adam Bien posted an interesting video showing the actual memory overhead of modern Java EE application servers.
From my point of view, one of the most “lightweight” solutions for enterprise applications is as follows:
From the translator:
Semyon Soldatenko, CC-BY-NC-SA 4.0
translation Stop Stop “heavyweight” , Sebastian Daschner, CC BY-NC-SA 4.0
Original: https://blog.sebastian-daschner.com/entries/stop_saying_heavyweight (April 09, 2016)
Translation: Semyon Soldatenko
When developing enterprise Java applications, you have to choose whether to use Java EE or some other “lightweight” framework . But what makes a corporate framework lightweight?
As developers, we mainly need to take care of the development process. Our time is precious (and expensive) and the less time we spend on overhead, the better.
Build time
This time mainly consists of the time to compile, deploy and test the application - locally or in a special environment. To keep the time for the full circle as short as possible, the compilation should not last more than a few seconds. Yes seconds.
Using Java EE has the great advantage that the developer can rely on a standard that allows you to develop based on APIs - basically just interfaces and annotations - while the actual implementation of the framework is not included in the application. Actually, the Java EE dependency is “delivered” by the application server, which means that it is required only for compilation, and is not included in the installation package. This has a side effect which is that the war file basically remains empty - it contains only the class files of your application. And everything else must be provided by the Java EE implementation.
As long as you remain skinny and minimalistic, which means using only the Java EE API (7) and not third-party dependencies - unless there is a real need for your business cases - you can achieve compilation time within a few seconds. The main reasons for slow assembly are either slow (integration) tests or large installation packages, which accordingly require a lot of copying.
Installation Package Size
A typical simple Java EE war file is about several hundred kilobytes in size compared to 50 or more megabytes if you supply an implementation of even a small (well, you know, “lightweight”) framework with it.
If you take into account the application server plus your application then the result for the Java EE case will be greater. But: In general, the development process will be faster, since every time you build, kilobytes are created. The application server is usually already installed on your development machine — or in any other environment — and the moving parts remain small. As a result, we get a shorter build and deployment time both on the developer's machine and on the Continuous Integration server. Also: When you place your installation packages in a centralized repository (Nexus or Maven central, etc.), you also save both time and traffic.
Deployment time
All modern Java EE 7 application servers (such as Wildfly, TomEE, Glassfish / Payara, WLP) show a very short time for application deployment. As part of their modular system (such as OSGi), they can only download the necessary components and run the application in a few seconds.
Comparing with another framework (such as Spring) running on Tomcat, the shortest deployment time that I have ever measured was at least 15 seconds - for a simple "Hello World" application - when measured on the same machine.
Thick JARs / Container Integration
In the new world of microservices, it is customary to supply applications in the form of independent jar containing both the developed application and the implementation of the framework. In Java EE, this can be achieved using technologies like Wildfly Swarm or TomEE Embedded.
However: As I said above, I do not recommend making your installation packages so large. The biggest problem with this approach is the build time, since you have to copy a lot of things each time from A to B. Also: When deploying using containers like Docker, it becomes unimportant whether your application comes with the server or the server is part container.
If the container already includes the installed application server, you can save a lot of build time (container). In this case, your basic image does not change, and you only add your (only a few hundred-kilobyte-byte) application - which is achieved almost without a waste of time.
Memory consumption
Since the days of old J2EE, there is a myth that "heavy" application servers consume a lot of memory as soon as they start. Adam Bien posted an interesting video showing the actual memory overhead of modern Java EE application servers.
Conclusion
From my point of view, one of the most “lightweight” solutions for enterprise applications is as follows:
- Java EE 7 and Java 8 using only the API provided by the server
- A small war file containing only business logic plus minimal configurations (such as JAX-RS resources or JPA)
- Fast unit tests without test frameworks with embedded container (only simple JUnit)
- Deployment based on containers from basic images containing all the necessary components, with the exception of the application
- A build process based on Continuous Delivery that deploys the application into containers per commit
- Automatic system testing of the application deployed in the container (to confirm the high quality of the application without the need for integration testing; at the same time, developers will also receive a quick response)
From the translator:
- Enterprise Application - Enterprise Application
- Framework - Framework
- Installation Package - Deployment artifact
- Business Case - Business use case
Semyon Soldatenko, CC-BY-NC-SA 4.0
translation Stop Stop “heavyweight” , Sebastian Daschner, CC BY-NC-SA 4.0