This content was deleted by the author. You can see it from Blockchain History logs.

Java EE—the Most Lightweight Enterprise Framework?

image.png
source images

It used to be J2EE and, most of all, application servers considered too bloated and "heavyweight." It can be very tedious and discouraging for developers to use the technology to develop applications. But since the J2EE framework name changed to Java EE, that assumption is not true anymore. How does Java EE compare to other enterprise frameworks and what criteria make the framework lightweight?

When choosing a technology, one of the most important aspects to consider is developer productivity during the development process. Engineers should spend as much time as possible to implement use cases and revenue-generating features, as this will drive the company to its goal.

Selected technologies and methods must minimize the time spent by developers waiting for creation, testing and deployment; configure the application; apply irrelevant plumbing for business use cases; and configure the build environment and external dependencies. But the majority of available technology does not do this.

Why Standard?

One of Java EE's biggest advantages compared to other frameworks is the standardization of used APIs. Standards may sound boring and not innovative enough - and, essentially, this is true, because Java Specification Requests (JSRs) carve out well-proven stones in the past in the industry. But using this standard has several advantages.

Integration Specification

Specific APIs within the Java EE umbrella - such as Context and Addiction Injection (CDI), JAX-RS, JSON Processing (JSR 353), and Bean Validation - work together very well and are meant to be merged with each other seamlessly. Best of all, CDI is used as a "glue" between application components. The specification contains words like "If the container supports A and B specifications, then A should integrate and work well with B seamlessly."

For example JAX-RS supports JSONP types such as JsonObjectused as request or response entities, and supports Bean Validation function call functions-including the correct HTTP status code if validation fails (see Listing 1).

1.png

Code 1. Integration of JSONP and Bean Validation of JAX-RS

Using the JSONP type implies that the content type will have application / jsondan HTTP 400 Bad Name code will be sent if validation fails. This is all done without writing any configuration code.

Another example is that CDI allows developers to inject nuts and user-defined objects into Java EE components managed via @ Inject. See list 2 for Validatory bean validation using other CDI-managed coffee beans directly.

GameNotPlayedValidator public class implements ConstraintValidator

2.png

List 2. Integration of soy beans CDI

Integration is a key aspect of the specification and enables a straight forward developer experience. Developers can rely on an application server for integration and configuration work and can instead focus on the application's business logic.

Conventional development

Due to the convention-oriented approach of Java EE, most real-world applications do not require a lot of configuration. The days of complex XML descriptors are over. For a simple Java EE application, you do not need a single XML file.

Thanks to declarative annotations, simple annotated Java objects (POJO) handle HTTP requests (@Path), or serve as Enterprise JavaBeans (EJB) (@Stateless) beans, including transactions, monitoring, or interceptors. In the past, this approach has proved very well in various frameworks and has been standardized in Java EE.

The XML descriptor can still be used for configuration deployment times if there is a need for this, but the over-convensional configuration helps maximize developer productivity.

External Dependency

A small number of real-world enterprise projects work without additional dependence being sent in the implementation artefact. But the justification for these dependencies is primarily driven by technology-such as mapping or entity mapping frameworks or public libraries like Apache Commons or Google Guava-not with use cases.

Java EE 7-especially when used in conjunction with Java 8-comes with enough functionality to cover most use cases without other dependencies. What is not contained outside the box can mostly be realized with minimal amount of code, such as injection configuration via CDI manufacturers, circuit breakers through interceptors (see Adam Bien's open source library), or sophisticated collection operations via Java 8 lambdas and rivers.

Of course, you can argue not to rediscover the wheel here. But it actually does not make sense to include megabytes of external dependencies into the deployment artifact just to store a few lines of self-written code.

And experience shows that the biggest problem is not the immediate dependency, but the transitive problem. Transitive dependency very often collides with existing versions of libraries on the application server and causes challenging conflicts. At the end of the day, the developer spends more time managing the conflict than it takes to apply a small feature into the project. This is especially true for cases with technology-based dependencies, non-use-cases, dependency.

See Listing 3 for a simple Java EE 7 project The project model project Maven (POM) is inspired by Arcetsype Java EE 7 Essentials Adam bien

3.png

Listing 3. Java EE 7 Maven POM file

Of course, sometimes applications do need to integrate libraries that are critical to meeting software goals. However, this dependency needs to be justified by business requirements. In general, it makes sense and saves time and effort to minimize external production libraries.

To test dependencies, this is a different story, because libraries - such as JUnit, Mockito or, in some cases, Arquillian - are very important to include. But again, it makes sense to keep an eye on the list of test dependencies as well.

Thin Spread Artifacts

Because the application server knows about the Java EE API, the API should not be included in the installation artifact. Only business logic is included-with a minimum of glue code and cross sectoral considerations.

Therefore, these kilobytes-sized artifacts make it possible to have a very short wake time, because the process of making it does not need to copy many things. This can make a difference of a few seconds on each building. If you summarize all the additional time spent by developers and sustainable integration servers (CIs), it will be very different. The more often the project is built - and this is especially true for sustainable delivery scenarios (CDs) - the greater the impact.

In addition to short development time, small dispersal artifacts also ensure short publishing time and implementation. The moving part is minimal in all cases, due to the fact that the implementation is already contained in the runtime.

Ideal Framework for Dockers

This is the reason why Java EE is the perfect framework for use in container technologies like Docker. The Docker image is based on the layer and when the image is created, the base image already contains the operating system, Java runtime, and applications. So the only thing that is added to each building is a thin layer of kilobytes spread artifacts. It saves time and storage-not just on every building but also when images are being versioned or shipped-as opposed to fat WAR or a standalone JAR approach.

It does not matter at which stage, having thin introduction artifacts enables a very fast and productive deployment pipeline.

Modern Application Server

The J2EE application server is the embodiment of heavyweight software in terms of start time and deployment, installation size, and resource footprint. But in the new world of Java EE, this is not true anymore.

All modern Java EE 7 application servers, such as WildFly, Payara, WebSphere Liberty, Profile and TomEE, start and deploy it in seconds. Due to their internal and comprehensive modularity, they can only load the required components and apply thin application artefacts as quickly as possible.

The size of the installation and the current site is very reasonable. The application server does not consume more than just a simple servlet container but is then equipped with complete Java EE capabilities. Funnily enough, the example of a currently running browser is spending more memory.

Therefore, it is possible and sensible to apply only one application per server-both in containers and in places. With the "one application per application server per container" approach, you then have a highly productive yet flexible solution for modern microservice architecture.

Packaging

When it comes to packaging, there is no reason to keep using EAR files. The approach to having the entire app on a dedicated server requires you to have all the components in that environment, and thus save more creation and deployment time. In addition, it also avoids class loading hierarchy problems that may be caused by EAR files.

In most cloud and microservice deployments, standalone JAR packages are used. It contains application and runtime implementation. In the Java EE world, this approach can be realized by using vendor-specific toolchains, such as WildFly Swarm, Payara Micro, or Tomee Embedded.

However, due to the reasons mentioned above, I strongly recommend to separate the business logic from runtime time if possible. This means packing apps in a WAR file that contains only the application code.

In my opinion, a standalone JAR file is a useful solution if it is not possible to control the installation or operation process because of a "corporate" political problem rather than a technical reason. Then sending all that is needed in the deployment artifact and requiring only a Java runtime can resolve some non-technical issues.

Recommendations for the Productive Development Process

One of the most productive solutions for corporate projects is as follows:

  • Use Java EE 7 and Java 8 only with the API provided
  • Build a kilobyte size WAR file containing only business logic plus minimal pipeline (such as JAX-RS or JPA resources)
  • Build Docker image-add only WAR files to the base image containing the application server configured
  • Delivery via a CD pipe that deploys the application using the container

Conclusion

The days of "Java EE heavyweight" are definitely over. The APIs contained in the Java EE umbrella offer a productive and fun developer experience and seamless integration in the standard. Specifically, the approach to separating application code from the runtime enables a fast and productive development process.

With the new MicroProfile initiative initiated by multiple vendors, it will be possible in the future to further reduce the required JavaEE components.



Posted on Utopian.io - Rewarding Open Source Contributors