Jakarta EE 9 - 2019 Outlook
As presumably well known by now, Java EE is in progress of being transferred to the Eclipse Foundation. A lot of work, partially behind the scenes, has been done to make his happen. This work included discussions between vendors and other interested individuals, the vetting of the code in the Java EE repo at GitHub, actually transferring the code from the Java EE repo to the Eclipse repo, and most recently the preparation of the transferred code to be buildable on Eclipse Foundation infrastructure and changing the Maven coordinates over from javax.* to jakarta.*
At the time of writing many individual Java EE 8 components have been re-released as a Jakarta artefact with Eclipse licensing. It's only a matter of time now for a full GlassFish 5 build to be released [editor: has been released now] as a Jakarta artifact as well. Purely from a code based view, this release would hit a major milestone that was set out on the transfer road map earlier.
In this blog post we'll take a look at some of the plans, and specifically Payara's plans that come after this milestone.
One of the first things we're going to do is to adopt the newly re-released Jakarta versions of many of the Java EE and GlassFish components into Payara. For some components, such as the JASPIC and JTA APIs, this will be relatively straightforward. For others such as Mojarra we'd first need to re-align our patched version with the upstream Jakarta version. We'd expect, without guarantees of course, to have a bunch of this work done for the coming Payara 5.191 release.
For the implementation bits of the Jakarta components, that is, those bits not covered by the Java EE specs, we'll likely see a steady stream of new releases. For instance a Mojarra 2.3.10 is being planned, as is a Soteria 1.0.1 among others. We also plan to continue to update HK2, which is the JSR 330 (AtInject) implementation internally used in GlassFish and Payara, and a string of internally used components like these.
The most interesting part however is arguably how the existing specs and APIs in Java EE 8 are going to be evolved and how that brings us to a Jakarta EE 9. It is here that things start to look a bit less clear at the moment. In order to evolve these, at least two things need to happen:
- The Java EE specs need to be transferred as well
- Eclipse and Oracle have to reach an agreement about the use of the javax.* packages
Both things have not been done yet. Currently the Java EE API code, the direct implementations of that API and various supporting libraries (from the GlassFish project) have been transferred, as well as the TCK, and all existing issues for both of these projects. This combined is an immense amount of code and huge amounts of work have gone into transferring it, but it just doesn't allow us yet to release a JSF 3.0 or an EE Security 1.1.
Assuming that these things will eventually be taken care of, some projects have indeed started working towards their next major API version. We'll briefly look at some of these and discuss what Payara's preliminary ideas are for the next EE iteration. Note that these are preliminary and most of them well need further input from other vendors and the community.
Work for JSF 3.0 started a while ago in the master branch of the EE4J Mojarra project. JSF 3.0 will first and foremost remove a bunch of the old cruft that has been building up over the years, and has been retained because of the strict backwards compatibility requirements. This will include for instance the support for JSF's own expression language, which pre-dates the unified expression language from around 2005(!), as well as the support to use JSP as a templating engine for JSF (this was effectively deprecated in 2009 when JSF 2.0 was released). Of specific note is that the JSF native managed bean system, which itself was one of the inspirational sources for CDI, will now finally be fully removed after having been deprecated in stages ever since JSF 2.0.
This therefore means that JSF 3.0 will not be backwards compatible, although strictly speaking only the oldest of JSF 1.1 applications will not run on JSF 3.0 anymore. Most modern applications should not find much difficulties to upgrade.
While breaking backwards compatibility is never a step that should be taken lightly, we and the other JSF committers found that the transfer to Jakarta, as well as the fact that Java SE has been breaking backwards compatibility as well, would be a good moment to take this difficult step.
Beyond removing deprecated things from JSF, JSF 3.0 is planned to continue on the path of moving more of its own artefacts to CDI, which is something JSF had started doing in JSF 2.2 (FlowScope) and JSF 2.3 (many JSF artefacts injectable via CDI).
As for new features, one of the things currently in scope is adding an action module to JSF. While JSF has been moving towards a more hybrid MVC model when it added first class support for GET requests in JSF 2.0 and adding things like view parameters and view actions, it's not exactly an action framework of course. Such action module has already been prototyped by one of the JSF committers and can be found here: https://github.com/manorrock/oyena/tree/master/action
Smaller things that are considered include making extensionless mapping (meaning no file extensions are used/needed when requesting JSF views) a default, with a simple option to switch it off again.
EE Security 1.1
For EE Security 1.1 some work has started as well, although for now only relatively small things have been added (two wrapper classes and making CallerPrincipal serializable).
This new version will likely focus mostly on the authorization concerns, an epic which we didn't come to in EE Security 1.0. First on the list will be a CDI compatible @RolesAllowed alternative. Compared to this existing annotation, which is in Common Annotations and can be interpreted by whatever technology in whatever way, this replacement will be more clearly defined as a CDI interceptor binding annotation and using the EE Security architecture. A simple version of such interceptor is already present in the Payara API as a vendor feature. A new feature we'll be looking at is having the interceptor just throw an exception when access is denied (like @RolesAllowed in EJB now does), or having it trigger an authentication dialog when access is denied (like @ServletSecurity in Servlet now does).
Another larger item on the list is allowing for custom authorization rules. Such rules for instance allow users to attach logic to simple roles checks, like defining that the role "employee" is only valid between business hours. A prototype for this too was created quite a while ago: https://arjan-tijms.omnifaces.org/2016/07/simplified-custom-authorization-rules.html but mostly due to time constraints it wasn't included in EE Security 1.0.
Technically custom authorization rules have been possible for quite some time in EE using the JACC API, but this has been difficult to use in practice largely because the current API is an all or nothing affair; you replace all rules (including the standard behaviour for @RolesAllowed etc) for all applications on the entire server. EE Security 1.1 will essentially be what EE Security 1.0 was to JASPIC; a usability layer on top of the existing JACC API. In this case that would mean users will be able to simply add rules (no need to replace the entire machinery) and will be able to do this per application.
Authentication will not be forgotten though, and the plans are to at least add some additional authentication mechanisms such as OAuth2 and Open ID Connect (both already ship with Payara as proprietary features and are fully based on EE Security). MicroProfile's JWT may be considered as well, though this also depends on if/how/when MicroProfile and Jakarta are or are not merging.
Another authentication related concern that we may look at is having different authentication mechanisms in an application for different paths (e.g. a FORM one on /ui and a BASIC one on /rest), and different authentication mechanisms for a single path and letting the user choose which one to use (e.g. log in with Google, log in with Facebook, log in with email, etc).
Jaspic is the SPI underlying the authentication parts of the EE Security API and not so much intended to be used by application developers. For a 1.2 release a list of mostly spec clarifications was defined quite some time ago, but were never added to the spec. In the meantime most JASPIC implementations do the right thing anyway, but it would still be good to add the clarifications to the spec. Updating the API to Java 5 (using generics) is long, long overdue and is planned as well.
Also in the planning are to include some extra status codes, for instance to let a SAM indicate it "did nothing", and another context variable in the message info map to indicate whether a SAM was invoked at the start of the request or via an explicit authenticate() call.
In order to be more suitable for inclusions in pure Servlet environments we may look at a "Servlet Container Profile-lite" as well. This profile could possibly remove some of the unnecessary classes for a Servlet environment, and additionally add a method to JASPIC's main factory to just register a SAM.Another potential area to look at is adding a "JAX-RS Container Profile", which would make JASPIC and by extension EE Security directly usable for JAX-RS. Currently this happens via an implicit dependency on Servlet. Despite the fact that the overwhelming majority of JAX-RS implementations depend on Servlet anyway, some people like to avoid an explicit Servlet dependency for JAX-RS environments such as MicroProfile.
JACC is the SPI underlying the authorization parts of the EE Security API, and just as JASPIC not so much intended to be used by application developers.
One of the things most desperately missing in JACC is the ability to install JACC providers (authorization modules) per application, just like in JASPIC where it's possible to install SAMs per application. In Payara this is already possible, so we would like to bring this feature back into the spec.
The other thing that is really missing in JACC is having access to a portable group to role mapper. JACC providers almost always need this mapper (even when 1:1 mapping is used), but JACC has never defined one. This is one thing we would really like to add.
For some reason, one that has largely been lost in time, JAX-RS uses its own dependency injection system based on @Context instead of CDI's /ATInject @Inject. While JAX-RS was updated at the last moment before its initial release to have some level of support for CDI, the fact that JAX-RS resources are not CDI beans has unnecessarily hold back the spec and has caused confusion even since JAX-RS was introduced in EE 6 (2009).
The plan is therefore to make JAX-RS use CDI instead. This changeover to CDI could possibly happen in 2 steps; in JAX-RS 2.2 everything that can now be injected by @Context should also be injectable using @Inject and JAX-RS resources would be CDI beans by default (perhaps unless explicitly disabled). At the same time @Context would be deprecated. In JAX-RS 3.0 @Context would then be actually removed.
JEE Concurrency 1.1
While EJB had lots of initial issues, it did and does contain a number of useful services. The problem with EJB is that it tried to become a facade for all other technologies in Java EE and at the same time pushed for a one size fits all model. This means that in EJB one annotation often gives you a lot of things at the same time. While this can certainly be handy, often people's mental model is more in tune with accumulating various services instead.
Enter CDI and the Intercepters spec. Together these made it possible to let other specs build on CDI and provide EJB-like functionality via a a la carte model. The first one taking advantage of this was the JTA spec, where the @Transactional annotation effectively did what is the default in EJB bean types like @Stateless. Other services were expected to follow suit, but alas it didn't happen. For Java EE 8 it was discussed that several things like the EJB timer service and the @Asynchronous annotation would move to EE Concurrency. Unfortunately, there was the problem that the Concurrency JSR wasn't open at the time, and it could not be opened since it was not planned to be opened (a big problem with the Java EE and JCP process back then).
So among the plans for EE Concurrency 1.1 is to execute this earlier plans: move the EJB timer service and the @Asynchronous annotation in updated versions to EE Concurrency. Potentially the implicit pooling feature of EJBs, which has always been touted as a mechanism to throttle concurrency, will be moved to EE Concurrency as well. A missing element of EE Concurrency is that the various concurrency services it provides, like the managed executor service, can only be configured in a vendor specific way, and typically not from within the application. Especially for cloud deployments this is often inconvenient, so we'd like to add portable ways to define and configure the concurrency services.
Yet another, but not less important, omission in EE Concurrency is the fact that context and scope propagation is not fully defined. EE Concurrency specifically doesn't say anything about CDI, which is quite problematic in current day EE programming. We intend to better specify this and/or provide a means to control propagation in code.
Note that a parallel and largely overlapping effort has started at MicroProfile. Since Jakarta EE and MicroProfile are often implemented by the same vendors and even the same people within those vendors, but officially are not merged, it's not very clear yet how to resolve this duplication.
While often thought of as being a part of CDI, Interceptors is actually a separate spec, albeit (perhaps surprisingly) officially a sub-spec of EJB. Since it's a relatively small and focussed spec there are not that many changes in scope, although one change that we are considering to propose is adding the ability for an interceptor to change not only the method target and its parameters, but the bean target as well. This would make things such as an @Poolable annotation far more straightforward to implement, since in such case an interceptor would grab a bean instance from a pool and continue the call on that.
Expression Language 3.1
Expression language 3.0 has support for lambdas and streams, but since it was conceived before Java SE 8 was released and targeted Java EE 7 (which was SE 7 based) EL lambdas and Java 8 lambdas do not map to each other. We plan to define this mapping.
Another possible thing to look into is the info one can obtain from Method- and Value Expressions in code. There's the MethodInfo and the ValueReference for that now, where the MethodInfo contains information about the actual method the expression evaluated to. Such info is however not directly available for Value Expressions only for Method Expressions, so a potential enhancement is to add this (indirectly Evaluation Listeners can be used though).
Though expression language is quite easy to use in Java since Expression Language 3, we feel that a fluent API could possibly make this a bit easier still. As part of the effort for Expression Language 3.1 we may investigate the feasibility of such API.
Requestlets 1.0 [Note: This is still in the idea phase]
Besides evolving existing specs we're contemplating proposing a new spec; Requestlets. Note this idea is still pretty much a draft and very preliminary.
In a way Requestlets is about evolving a spec though, namely the Servlet spec. It will attempt to address two issues.
The first is that in CDI the HttpServletRequest is being produced by a so-called build-in bean. HtppServletRequest is however not a native CDI type, but obviously a Servlet type, and should thus be produced by the Servlet spec (just like e.g. FacesContext is produced by the JSF spec, IdentityStore is produced by the Security spec, @Transaction is provided by the JTA spec, etc). The reason it's currently in CDI is partially out of early necessity, and partially because of an early confusion: should CDI simply become an EJB2 and be a facade for all other specs, or should all other specs build on CDI instead. The consensus is now that all other specs should build on CDI, but this wasn't so clear in the beginning.
So the natural path forward would be to have Servlet contain producers for the various types it maintains. These producers would be small factory like classes, that would essentially just allow us to get an artefact like HttpServletRequest using the CDI APIs. Exactly this was attempted before, but the major problem appeared to be that not everyone over at the Servlet spec understands what CDI is, therefore making it hard to accept the request.
This potential new spec, Requestlets, could therefore be the place to put the various producers for Servlet artefacts instead.
The second issue it may address is that currently Servlets themselves are injectable by CDI, but they are not CDI beans themselves. This means for instance that interceptors and decorators cannot be applied to them, and neither can scopes. Requestlets intends to introduce a pure CDI version of Servlets; CDI beans that respond to simple HTTP requests and are very close to plain Servlets. For example, given the following plain Servlet:
A Requestlet equivalent would look like this:
As can be seen the two are quite close and that's of course intentional. The Requestlet however is a true CDI bean, meaning that we could make myMethod directly transactional by applying the @Transactional annotation (this wouldn't be super useful here, but just for the example). Additionally, a Servlet doesn't have a specific scope, although it's basically a shared singleton. In this example we gave the Requestlet a request scope, meaning that one could use instance variables here and they wouldn't interfere with other requests.
Also, because there is no practice of a general service method calling doGet etc methods, we can protect our requests with a CDI based @RolesAllowed like interceptor (such as proposed for EE Security 1.1), which altogether leads to a more consistent programming model.
Note that while the above may look a little like JAX-RS resources, and the @RequestMethod(GET) vs @GET annotations may certainly be a consistency concern, Requestlets are definitely not intended to take over any of the JAX-RS use cases and the stated goal will be to remain as close to Servlets as possible. As noted above, the Requestlet idea at this point is very preliminary and it we may not actually propose it, or propose something quite different from what it presented here. This idea outlined here is just to give an initial impression and to solicit feedback.
There's obviously quite a bit more in the pipeline for Jakarta EE 9, and we have only gone through some of the specs that Payara is leading or contributing to. For instance, we haven't discussed CDI, Batch, JPA, BeanValidation or the newly proposed NoSQL spec which is currently in early planning.