One thing to keep in mind is that all those implementations are not all completely unique. There are a dozen or so Java EE implementations, but there are most definitely not a dozen of JSF implementations (in fact there are only two; Mojarra and MyFaces).
Java EE implementations in some way are not entirely unlike Linux distributions; they package together a large amount of existing software, which is glued together via software developed by the distro vendor and where some software is directly developed by that vendor, but then also used by other vendors.
In Java EE for example JBoss develops the CDI implementation Weld and uses that in its Java EE servers, but other vendors like Oracle also use this. The other way around, Oracle develops Mojarra, the aforementioned JSF implementation, and uses this in its servers. JBoss on its turn then uses Mojarra instead of developing its own JSF implementation.
In this post we'll take a deeper look at which of these "components" the various Java EE servers are using.
One source that's worth looking at to dig up this information is the Oracle Java EE certification page. While this does lists some implementations for each server, it's unfortunately highly irregular and incoherent. Some servers will list their JSF implementation, while some others don't do this but do list their JPA implementation. It gives one a start, but it's a very incomplete list and a list that's thus different for each server.
Another way is to download each server and just look at the /lib or /modules directory and look at the jar files being present. This works to some degree, but some servers rename jars of well known projects. E.g. Mojarra becomes "glassfish-jsf" in WebLogic. WebSphere does something similar.
Wikipedia, vendor product pages and technical presentations sometimes do mention some of the implementation libraries, but again it's only a few implementations that are mentioned if they are mentioned at all. A big exception to this is a post that I somehow missed when doing my initial research from Arun Gupta about WildFly 8 (the likely base of a future JBoss EAP 7) which very clearly lists and references nearly all component implementations used by that server.
A last resort is to hunt for several well known interfaces and/or abstract classes in each spec and then check by which class these are implemented in each server. This is fairly easy for specs like JSF, e.g. FacesContext is clearly implemented by the implementation. However for JTA and JCA this is somewhat more difficult as it contains mostly interfaces that are to be implemented by user code.
For reference, I used the following types for this last resort method:
- Servlet - HttpServletRequest
- JSF - FacesContext
- CDI - BeanManager
- JPA - EntityManager
- BV - javax.validation.Configuration, ParameterNameProvider
- EJB - SessionContext
- JAX-RS - ContextResolver, javax.ws.rs.core.Application
- JCA - WorkManager, ConnectionManager, ManagedConnection
- JMS - Destination
- EL - ELContext, ValueExpression
- JTA - TransactionManager
- JASPIC - ServerAuthConfig
- Mail - MimeMultipart
- WebSocket - ServerWebSocketContainer, Encoder
- Concurrency - ManagedScheduledExecutorService
- Batch - JobContext
Without further ado, here's the matrix of Java EE implementation components used by 10 Java EE servers:
|Servlet||Undertow||Tomcat derivative & Grizzly||Nameless internal||Tomcat/Jetty||Tomcat||Nameless internal||Nameless internal||Nameless internal (jeus servlet)||Nameless internal||Tomcat + Jetty*|
|JSF||Mojarra*||Mojarra||Mojarra||MyFaces||MyFaces||MyFaces*||MyFaces*||Mojarra*||Mojarra*||Mojarra (def) + MyFaces*|
|CDI||Weld||Weld*||Weld*||OWB||OWB||OWB*||OWB*||Weld||CanDI (semi internal)||Weld*|
|JPA||Hibernate||Eclipselink+||EclipseLink+||OpenJPA||OpenJPA||OpenJPA*||OpenJPA* Future version will be EclipseLink*||Eclipselink*||Eclipselink*||Hibernate (def) + EclipseLink (certified with)*|
|BV||Hibernate Validator||Hibernate Validator*||Hibernate Validator*||BVal||BVal||BVal*||BVal*||Hibernate Validator*||Hibernate Validator*||Hibernate Validator*|
|EJB||Nameless internal||Nameless internal (EJB-container)||Nameless internal||OpenEJB||OpenEJB||Nameless internal||Nameless internal||Nameless internal||Nameless internal||EasyBeans|
|JCA||IronJacamar||Nameless internal (Connectors-runtime)||Nameless internal||Nameless internal (Geronimo Connector)||Nameless internal (Geronimo Connector)||Nameless internal||-||Nameless internal||Nameless internal||Nameless internal|
|JMS||HornetQ||OpenMQ||WebLogic JMS (closed source)||ActiveMQ||ActiveMQ||SiBus (closed source)||Liberty messaging (closed source)||Nameless internal||Nameless internal||JORAM|
|EL||EL RI*||EL RI||EL RI||Apache / Jasper / Tomcat(?) EL||Apache / Jasper / Tomcat(?) EL||Apache / Jasper / Tomcat(?) EL*||Apache / Jasper / Tomcat(?) EL*||EL RI*||Nameless internal||EL RI + Apache / Jasper / Tomcat(?) EL*|
|JTA||Narayana||Nameless internal||Nameless internal||Nameless internal (Geronimo Transaction)||Nameless internal (Geronimo Transaction)||Nameless internal||Nameless internal||Nameless internal (jeus tm)||Nameless internal||JOTM|
|JASPIC||Part of PicketBox||Nameless internal||Nameless internal||Nameless internal (Geronimo Jaspi)||-||Nameless internal||-||Nameless internal||-||-|
|JavaMail RI*||JavaMail RI||JavaMail RI||(Geronimo?) JavaMail||(Geronimo?) JavaMail||JavaMail RI*||-||JavaMail RI*||JavaMail RI*||JavaMail RI*|
|WebSocket||Undertow||Tyrus||-||-||-||-||-||Nameless internal (jeus websocket)||-||-|
|Concurrency||Concurrency RI*||Concurrency RI||-||-||-||-||-||Nameless Internal (jeus concurrent)||-||-|
|JBatch||JBeret||JBatch RI (IBM)*||-||-||-||-||-||JBatch RI (IBM)*||-|
Looking at the matrix we can see there are mainly 3 big parties creating separate and re-usable Java EE components; Red Hat, Oracle and Apache. Apache is maybe a special case though, as it's an organization hosting tons of projects and not a vendor with a single strategic goal.
Next to these big parties there are two smaller ones producing a few components. Of those OW2 has a separate and re-usable implementation of EJB, JMS and JTA, while Resin has its own implementation of CDI. In the case of Resin it looks like it's only semi re-usable though. The implementation has its own name (CanDI) but there's isn't really a separate artifact or project page available for it, nor are there really any instructions on how to use CanDI on e.g. Tomcat or Jetty (like Weld has).
Apart from using (well known) open source implementations of components all servers (both open and closed source) had a couple of unnamed and/or internal implementations. Of these, JASPIC was most frequently implemented by nameless internal code, namely 4 out of 5 times, although the one implementation that was named (PicketBox) isn't really a direct JASPIC implementation but is more a security related project that includes the JASPIC implementation classes. JTA and EJB followed closely with 8 respectively 7 out of 10 implementations being nameless and internal. Remarkable is that all closed source servers tested had a nameless internal implementation of Servlet.
At the other end of the spectrum in the servers that I looked at there were no nameless internal and no closed source implementations of JSF, JPA, Bean Validation, JAX-RS, JavaMail and JBatch.
It's hard to say what exactly drives the creation of nameless internal components. One explanation may be that J2EE started out having Servlet and EJB as the internal foundation of everything, meaning a server didn't just include EJB, but more or less WAS EJB. In that world it wouldn't make much sense to include a re-usable EJB implementation. With the rise of open source Java EE components it made more sense to just reuse these, so all newer specs (JSF, JPA, etc) are preferable re-used from open source. One exception to this is however JEUS, which despite being in a hurry to be the first certified Java EE 7 implementation still felt the need to create their own implementations of the brand new WebSocket and Concurrency specs. It will be interesting to see what the next crop of Java EE 7 implementations will do with respect to these two specs.
An interesting observation is that WebSphere, which by some people may be seen as the poster child of the closed source and commercial AS, actually uses relatively many open source components, and of those nearly all of them are from Apache (which may also better explain why IBM sponsored the development of Geronimo for some time). JavaMail for some reason is the exception here. Geronimo has its own implementation of it, but WebSphere uses the Sun/Oracle RI version.
Another interesting observation is that servers don't seem to randomly mix components, but either use the RI components for everything, or use the Apache ones for everything. There's no server that uses say JMS from JBoss, JSF from Oracle and JPA from Apache. An exception to the rule is when servers allow alternative components to be configured, or even ship with multiple implementations of the same spec like JOnAS does.
We do have to realize that a Java EE application server is quite a bit more than just the set of spec components. For one there's always the integration code that's server specific, but there are also things like the implementation of pools for various things, the (im)possibility to do fail-over for datasources, (perhaps unfortunately) a number of security modules for LDAP, Database, Kerberos etc, and lower level server functionality like modular kernels (osgi or otherwise) that dynamically (e.g. JBoss) or statically (e.g. Liberty) load implementation components.
JEUS for instance may look like GlassFish as it uses a fair amount of the same components, but in actuality it's a completely different server at many levels.
Finally, note that not all servers were investigated and not all components. Notably the 3 Japanese servers NEC WebOTX, Fujitsu Interstage and Hitachi Cosminexus were not investigated, the reason being they are not exactly trivial to obtain. At the component level things like JAX-RPC, JAX-WS, SAAJ, JNDI etc are not in the matrix. They were mainly omitted to somewhat reduce the research time. I do hope to find some more time at a later stage and add the remaining Java EE servers and some more components.