Hi, Habr! We recently published the book "
Learning Java EE. Modern programming for large enterprises " from the German Java-champion Sebastian Dashner.
Mr. Dashner actively writes and speaks on topics related to modern Java EE, so his blog also paid attention to the general design principles for the Jakarta EE platform, which is currently being developed by Eclipse. Translation of this particular article (June), we offer today to your attention.
The Jakarta EE platform gradually comes into its own, and with it new specifications for enterprise development appear. To harmonize the various standards and technologies that are about to take shape, the entire Java EE community will benefit if it is possible to develop general design principles for the Jakarta EE specifications.
I believe that Java EE technology has proven so successful thanks to just a few principles. Below, I present my point of view as to which design principles established in Java EE seem to me the most important, which are worthy of further elaboration and can potentially serve as recommendations for designing in Jakarta EE.
I decided to write this article, inspired by Dmitry Kornilov’s proposals on the direction in which the technical development of Jakarta EE should go.
First of all - business logicThe Java EE programming model allows the developer to focus precisely on what is required - that is, on business logic. No need to inherit API classes; the developer can express the logic of his subject area in the usual Java language and mainly declaratively (using annotations) control the behavior of the application server. Thus, the framework seamlessly integrates into your code and, in essence, it is just as easy to remove it from there. When designing, rely not on reuse, but on easy disposal.
However, implementations should relieve the developer from the most difficult work to the maximum - that is, allow him to distract from technical requirements not related to business logic. Examples are multithreading, transactions, control inversion, or HTTP request processing. On the application side, tediousness is a blessing :)
It seems to me important that the framework not only does not interfere with the implementation of business logic, but also stimulates programmers to quickly develop production capabilities into production. There is no need to polish the framework to shine - it is better to bring the code of business logic to the ideal. Compare modern Java EE or Spring with old-fashioned versions of J2EE - I think you will immediately understand what I mean.
Jakarta EE should develop along the same lines and, accordingly, focus on specifications that allow developers to implement business logic as quickly as possible.
Configuration conventionsIn Java EE, the configuration needed to define a typical enterprise application is minimized. In most practical situations, agreements work right out of the box, no configuration is required. So, no more XML files are needed to configure a simple Java EE application. Another example is that JAX-RS provides default HTTP response codes corresponding to the return values of the JAX-RS methods.
Java EE does have enough flexibility to modify behavior and implement more complex scenarios; however, there is no agreement on this.
Jakarta EE should continue to turn the simple into the easy, and the complicated into the possible.
Interoperability specificationsJakarta EE should continue and extend the interoperability of specifications. In Java EE, the existing specifications and the functionality present in them, which has already become part of the standard, are respected.
Developers can rely on the fact that the disparate specifications will work well with each other, and no configuration is required. Standards were required: if the runtime environment supports both specification A and specification B, then A + B must interact with each other. Examples: component validation, JAXB or JSON-B can be used in the JAX-RS resource classes, and no further configuration is required.
Dependency Injection and CDIOf course, it is undesirable for Jakarta EE to reinvent those things that already exist — for example, dependency injection related to CDI. It is desirable that the specifications use and highlight the strengths of the JSR 330 or, if necessary, CDI.
A
UriInfo example is the use of
UriInfo from JAX-RS in resource methods. The
@Inject annotation
@Inject not yet support the implementation of methods of this type. The more convenient it is for a programmer to work, the more he relies on a universal mechanism.
Another specific measure is as follows: specifications should provide CDI providers, and if necessary, typesafe qualifiers for the types that need to be created. So, at present, an instance of the JAX-RS client can only be obtained programmatically through the API
ClientBuilder . Manufacturers and qualifiers simplify the work of the programmer because they provide declarative definitions.
Declarative ApproachesWith all this, the Java EE API relies heavily on a declarative approach, using control inversion. Thus, developers do not call the functionality directly; the container is responsible for calling the functional, and we rely on the code definitions. Examples (of the most modern specifications) are JAX-RS, JSON-B or CDI.
Jakarta EE not only provides more comprehensive software APIs, but should further promote the use of declarative definitions and control inversion.
Deployment strategiesThe most characteristic feature (and in my opinion, a great advantage) of Java EE is that the deployment model proposed here, in which business logic problems are separated from implementation. The developer programs exclusively for an API that is not part of the deployment artifact and is implemented by the application container.
Such compact deployment artifacts simplify and speed up the delivery of a program, including assembly, publication, and deployment as such. They are also compatible with the levels of the container file system used, for example, in Docker. In the process of assembly, you only need to rebuild or resubmit the changed elements.
Ideally, deployment artifacts should contain only business logic and nothing else; runtime implementations and potentially added third-party libraries are delivered at a lower level, for example, in application server libraries added in the previous container assembly step.
In Jakarta EE, expanded artifacts must also be considered first-class entities. Perhaps there will be an opportunity to further tighten the execution time environment based on the specification required by the application. However, in Jakarta EE it is supposed to pay maximum attention to the business logic and developer productivity, and the fine-tuning of the execution time is already secondary.
TestabilityApplying the above principles, especially preferring declarative programming and dependency injection, we improve the testability of the business code. Thus, developers can directly instantiate objects in test scripts, since they no longer need to inherit the API classes or call the inconvenient functionality that they would previously need to simulate.
However, in Jakarta EE, it is required to seriously refine the standardization of integration testing at the code level, so that it does not depend on the manufacturer. Earlier, it was with this that we had to deal with Arquillian. In real projects, such a standard would be useful, which allows declaring only test deployment scenarios and invoking functionality for one or several components. Earlier, I wrote that I did not consider overly important integration testing at the code level, for example, when running an application in embedded containers. However, if you standardize integration tests at the code level, this clearly will have a positive effect.
ConclusionI think it is no coincidence that Java EE APIs are so widely used in real projects: these APIs are well thought out and designed in accordance with clear principles, thanks to which it was possible to unify not even a single specification, but an entire platform. They allow you to use several specifications in one spirit at once. Here we managed to get rid of artificial obstacles that only complicate the work of the programmer - therefore, I think, all enterprise development has become much more pleasant.