Java EE 8 wish list
Java EE 7 has been recently released and is a truly great release. While for most vendors the job to implement Java EE 7 has just started or may even still has to start ideas for the next version, Java EE 8, may already be shaping.
If history is anything to go by; last time Java EE 6 was released Dec 10, 2009 and we saw the first real Java EE 7 events about a year later, so we may have some time till Java EE 8 is really kicking off. Around the Java EE 7 kickoff time, Antonio Goncalves, presented a very interesting wish list of things that should be in Java EE 7. Interestingly 2 of his 4 items (flows and batch) indeed made it in Java EE 7, while a 3rd item (caching) would have been included but was dropped at the very last moment.
It's a bit early days, but in this article I'd like to present my wish list for Java EE 8:
- CDI everywhere
- More thorough Pruning & Deprecating
- A standardized caching API
- In-app alternatives for all "administrative objects"
- General modernized security framework
- Platform wide configuration
These items are discussed in more detail below.
This really means two separate things: making CDI available from places where it isn't available now, and implementing or retrofitting technology from other specs on top of CDI.
Make CDI available at more places
In Java EE 7 CDI was made available in a lot more places than before in Java EE 6. For instance CDI injection now works in most JSF artifacts and in e.g. the constraint validator from bean validation. Unfortunately, it thus only works in *most* JSF artifacts, not all. Missing are the converters and validators (OmniFaces 1.6 will add support for this, but it should really work out of the box).
JASPIC artifacts are not CDI aware either; injection doesn't work in them and even though the http request and session are available in a Servlet Profile SAM, the corresponding CDI scopes haven't been set up when a SAM is called. This means it's not even possible to retrieve request or session scoped beans programmatically using the bean manager.
A special case is that an assortment of platform artifacts have to be injected with alternative annotations (like @PersistenceUnit) and that the older general injection annotation (@Resource) is still required for many things such as a DataSource. Striking is that even artifacts introduced in Java EE 7, like the managed executor service, have to be injected with the ancient @Resource instead of @Inject.
Other specs building on top of CDI
CDI should definitely not try to absorb in its spec everything that other specs already address, but of course those other specs can implement their functionality on top of CDI, which typically means as a CDI extension. In Java EE 7 JSF 2.2 for instance provides a CDI compatible view scope as a CDI extension and its new flow scope was implemented right away as a CDI extension (there is no "native" variant anymore, a strong signal that JSF is likely to deprecate its own native managed bean facility).
Furthermore JTA 1.2 now provides a CDI extension via which transactions can be declaratively applied to CDI managed beans. Previously similar functionality was provided by EJB, which also used JTA behind the scenes but kept the declarative part inside the EJB specification. In this case however JTA directly implements the declarative transaction handling itself, but uses CDI to base this implementation on.
Although EJB beans since EJB 3 are very simple to use and at the same time very powerful, they have one big problem: it's simply a different component model than the one offered by CDI. No matter how useful the various EJB bean types are, having two component models within a single platform is very confusing for users and probably implementors as well. With the CDI component model you mix and match capabilities ala carte, with each annotation giving you extra capabilities. EJB is more of a "one off" model where a single annotation defines a specific bean type that gives you a lot of capabilities that typically work well together. You can partially disable the capabilities that you don't want. E.g. all bean types give you transactional support, but this can be turned off. For @Stateful beans passivation can be disabled, for @Singleton beans container managed locks can be disabled, etc.
Ultimately it would probably be better if EJB were to be retrofitted as a set of CDI extensions. There would only be one component model then but with effectively the same functionaly.
This means that EJB services like the timer service (@Schedule, @TimeOut), @Asynchronous, @Lock, @Startup/@DependsOn and @RolesAllowed should all be made to work with CDI managed beans. Furthermore the implicit features offered by the existing EJB bean types should then be broken down into individually applicable capabilities. Examples would be an @Pooled to mimic the container pooling offered by @Stateless beans and something like an @CallScoped to mimic the effect that every call to an @Stateless bean goes to a (potentially) different instance.
Of course very few people would like to annotate each class with @Pooled @CallScoped @Transactional @..., but this can be prevented by creating a couple of CDI stereotypes. It's a question though whether these should be given the same name as the existing EJB "bean defining" annotations but in a different package, or whether they should be given totally different names. The same names would make migration more straightforward, but some new users will undoubtedly choose the wrong variant at times (as can be seen today with the JSF @RequestScoped annotation vs the CDI one with the same name).
More thorough Pruning & Deprecating
Pruning is a process that was introduced in Java EE 6 and describes how deprecated functionality can be removed from the platform. In Java EE 7 a variety of technologies was pruned (made optional), meaning vendors can still include it if they want but they don't have to.
There is however more to prune. My personal favorite would be the JSF native managed bean facility (which ties in nicely with the "CDI everywhere" theme), the JSP view handler (which was effectively deprecated back in 2009) and an assortment of functionality in JSF that has been described as being deprecated in the spec document for quite some time.
It would maybe be nice if the EJB component model would be pruned as well (in favor of the CDI based version), but most likely this is much too early. A safer bet would be to first continue pruning everything related to the EJB 2 programming model, like the home interfaces that still linger around in Java EE 7.
A standardized caching API
This item can be kept short; a standardized caching API called JCache was set to be included into Java EE 7, but unfortunately it missed a few important deadlines. Hopefully it will make it into Java EE 8. If this spec finishes early in the Java EE 8 timeframe then it would be great if some of the other specs (like JPA) could rebase their own caching API on top of JCache.
In-app alternatives for all "administrative objects"
Java EE has a concept called an "administrative object". This is a resource that is configured on the AS side as opposed to from within the application itself. The concept is sometimes controversial. For application servers that run many external applications inside big enterprises, it can be a big advantage to have them. You typically don't want to open an externally obtained application to change the details of which database it connects to. If there's a strong separation between developers and operations in a traditional enterprise it can be benificial as well to have this separation reflected in the system setup.
However, for agile teams that deploy a single in-house developed application to its own application server (which is thus not shared by other applications) this separation is a big hurdle that only gets in the way and doesn't help at all.
Likewise for beginners, educational usage and even cloud deployments, this setup is highly undesirable as well. For beginners and educational usage specifically it means one part of the explanation of setting something up can be in general Java EE terms, and then another part has to say something like "see your own server for details on how to do ...". This is rather confusing to say the least.
Starting with the @DataSourceDefinition in Java EE 6 many resources that were previously "administrated objects" only can now be defined from within the application. These include JMS destinations, email sessions, and more.
Unfortunately this is still not true for all administrated objects. Striking is that the brand new Concurrency Utils for Java EE spec has explicitly opted to make its resources administrative objects only. It would be great if these could be configured in a portable way from within the application as well in Java EE 8. Even better would be if the platform would define a kind of guideline that strongly discourages resources to be administrative only. If a spec thinks a developer of whatever type can not be trusted with some resource type, and it should thus be administrative only, then the spec should be required to have a very good reason for this. "xyz does not belong with developers, period!" is of course not a valid reason.
General modernized security framework
Security has always been a thorny issue in Java EE. The lack of an overall and comprehensive security framework is not rarely mentioned as one of the main disadvantages of Java EE, especially in discussions or evaluations of Java EE against competing frameworks such as Spring.
It's not that Java EE doesn't have any provisions for security at all. In fact, it has a whole slew of them. There's JAAS, there's JASPIC, there's JACC, portions of the Servlet spec deal with security, portions of the EJB spec do as well, JAX-RS has its own API and if I'm not mistaken even JCA has some of its own security provisions.
There are however several problems with all of this. The first is simply that security is spread over so many specs, and that not all of those specs are available in the important Java EE Web Profile. This makes it hard to reason about -the- Java EE security framework, since there just isn't a single one.
This results in a number of practical problems. For instance, the recently introduced '*' role had to be specified and implemented individually in the Servlet, EJB and JACC specs. Checking if a user has a specific role is done inside a Servlet via HttpSerletRequest#isUserInRole, but inside an EJB it has to be done via EJBContext#isCallerInRole. Inside JAX-RS resources it's SecurityContext#isUserInRole, and how it has to be done from within a CDI bean is anyone's guess (in practice; via obtaining an HttpServletRequest in some way). It would probably be much clearer if there was something like a single SecurityContext that could be used by artifacts from all other specs instead of each spec having its own way to do the exact same thing.
Another example is asking the container for all roles that a given user has. This is supposedly possible via JACC, so other specs aren't eager to implement this (perhaps for the better to prevent more duplication). Unfortunately JACC is not available everywhere, so in practice this is not an optimal solution. Worse, the JACC code to do this is not really terse to say the least. I wonder how many people, even the more advanced Java EE developers, would be able to come up with such code themselves.
This brings us to the second main issue; the various security APIs haven't been modernized for quite some time. This holds especially for JASPIC and JACC. There have been various maintaince updates which fixed small but important issues, but never a full modernization like was done recently for JMS 2. JASPIC for example still targets Java SE 1.4 and as mentioned above has no knowledge whatsoever of things like CDI.
A third issue is that the individual security APIs JAAS, JASPIC and JACC are all rather abstract and low-level. This gives them great flexibility for vendors, but makes them not optimally suited to be used by regular application developers (who weren't already super thrilled to use them because of the non-modernized API). JAAS is especially troublesome here as its more aimed at providing priviledges to specific code bases for doing low-level operations (like reading a file, opening a URL, etc). This doesn't match well to Java EE, where it's extremely rare to run untrusted code and the emphasis is more on allowing resource access to (logged-in) users on a much higher level.
A fourth and very major issue is that security in Java EE has suffered from the same problem as the "administrative objects"; for a long time the so called declarative security model of Java EE assumed that the actual "how" of mainly the authentication process was solely configured and implemented in a vendor specific way at the AS side. This again made setting up security unnecessary hard for agile teams, beginners and educators. Indicative for this issue is that some of the great books about the Java EE platform as a whole, like Arun Gupta's Java EE 6 Pocket Guide and Antonio Goncalves' Beginning Java EE 7 do not address security at all! There is just hardly any "Java EE way" to do these tasks, but only a "JBoss way", a "GlassFish way" and a "Vendor XYZ way".
Specifically problematic is that many servers require a process often called "group to role mapping". This process is not always needed but mandated anyway, plus it's server specific meaning a user has to relearn it for every Java EE server he or she has to work with. This Java EE approach of having a "security view" of an application, which declares roles, and a deployer who maps and configures security at the application server is an approach that maybe nicely scales up to large enterprises, but doesn't scale down well to the level of an individual developer who is just trying out Java EE or even to small and agile devops teams who only deploy a single application to a single application server. It's again also not always ideal for cloud deployments.
In the perception of a user, the actual authentication modules are thus a bit of a black box. They are specific for a server, which hurts portability and requires a user to learn how they work for every other Java EE implementation. This hurts the perception of the Java EE security system being an integrated thing (different vendors have their own API styles, there own documentation, their own way of doing things, etc). JASPIC theoretically solves this problem, but not yet in practice.
As a consequence of the fourth issue, most vendors have elaborate but proprietary security frameworks in place and their own interfaces for external authentication modules. Perhaps because of this existing investment, vendors have been slow to pickup JASPIC. As JASPIC is mandatory for compliance with the full Java EE 6 profile vendors have implemented it, but some implementations that were actually certified were a bit incomplete and diverged at quite a number of points from the JASPIC spec. It's hard to imagine those vendors having really put a lot of effort into JASPIC at that point. Lately the situation has started to improve, but even after more than 3 long years none of the available JASPIC implementations do everything that the spec requires them to do. This thus means not only the spec and APIs need to improve, but most likely the TCK needs a big update as well. We'll have to see if this didn't already happen for Java EE 7, as currently only GlassFish 4 has been certified for Java EE 7 and GlassFish has a reasonably compliant JASPIC implementation (but it too is not 100% compliant, e.g. request wrapping doesn't work from a SAM).
All together these are quite some issues. Partially they could be addressed by how things have been going for the last few releases: gradually add small features and fix or clarify small issues. My wish for Java EE 8 is however that the issues will be addresses more thoroughly by a single overarching and modern security framework (building as much as possible on the existing security foundation).
Platform wide configuration
Java EE applications can be configured using deployment descriptors (such as web.xml), but it's painful to change these settings easily for various stages (such as DEV, BETA, LIVE, etc). The traditional way to configure a Java EE application for such stages is via the above mentioned "administrative objects" that reside at a specific server instance. Following this method, it are the servers that are configured instead of the application. Since the server corresponds to a stage, the setting automatically change between stages.
There are a number of issues with this approach though. First of all by its very nature configuring resources at the AS side is server specific. Looking up those resources may be standardized, but configuring them sure is not. This again makes things difficult for beginners, makes things difficult to explain and makes it difficult to publish (explanatory) ready-to-run applications. It also makes things unnecessarily difficult for small and agile devops teams, who now have to separate the configuration from the application for no good reason. For developers this situation is difficult too; with the JNDI approach it's necessary to have multiple duplicate instances of the AS used for developing each with their own configuration. This works, but is not exactly lightweight. Furthermore, when new or updated configuration is made available this typically has to be applied manually; someone sends an email around with instructions and then developers often have to apply these instructions to all their AS instances by interacting with a web console or CLI. This is MUCH more involved and error prone than just pulling in a new revision from e.g. Git.
Even if JNDI based configuration is used, there's the issue that not everything can be configured via JNDI. Setting e.g. the JSF staging mode or the Facelets refresh time are web.xml settings and not JNDI resources. Adding an extra debug Filter into the Servlet filter chain is not something that can be easily done via JNDI either. There are crude workarounds, but none of them are really optimal.
There are various possible alternative ways to configure a Java EE application, such as using (expression language based) placeholders in the deployment descriptors and making deployment descriptors themselves (or fragments) switchable. A number of specifications already allow for additional deployments descriptors to be specified (e.g. web.xml can specify additional faces-config.xml files and persistence.xml can specify additional orm.xml files), but there's no unified mechanism to do this for all available descriptors and no way to parameterize which extra files are to be included or excluded.
It would be great if Java EE 8 addresses these configuration issues in a thorough and platform unified way. It seems that something like this is indeed being planned. It will be interesting to see how this will develop.
As mentioned at the beginning of this article, it's still early days for Java EE 8 planning and anything can still happen. Hopefully some (or most ;)) of the points on the above presented wish list will be addressed in some way. I think "CDI everywhere" in particular stands a good chance as there seems to be much support for that and things are already moving in that direction. The big question is to what extend Java EE 8 can address that particular issue. The standardized caching API probably stands a very good chance as well, it was almost included in Java EE 7 and is still making good progress. Strange things would have to happen if with the current scope it again wouldn't be ready for Java EE 8. However, with the enormous amount of extra time available for JCache may come the risk (and even the expectation) to expand the scope and if the functionality associated with that expanded scope isn't ready on time, could it miss the deadlines again? Hopefully not! The portable in-app mechanism (read annotations) to declare resources fits in very well with the cloud theme and I guess has a reasonable chance as well.
The one I'm least sure about is the general modernized security framework. This has indeed been mentioned now and then by several EG members, but as far as I know nothing for this has been started yet. It'll most likely require a rather big effort needing support from quite a number of other specs, making this an overall difficult issue. Incidentally, security was the 4th item that Antonio Goncalves put on his wish list for Java EE 7 and the only one that didn't got addressed. Let's hope Java EE 8 will finally pick this one up!