Then, in my current project, we started with EJB 3 (in late-2008). Mostly because it's standard. It is surely much easier, with annotations and such. However, the project has security requirements way beyond the standard JAAS can handle. Besides roles (the only concept handled by JAAS in EJBs), we have permission sets, which can be applied to either groups or individual users, and they can be dynamically changed by the application admins. So we had to create some sort of custom mechanism to check permissions. However, we still need JAAS to propagate the user identity (we use remote EJB interfaces).
Ok, but why am I so disappointed with EJBs? Here are some points:
- To propagate the caller identity we need JAAS. It is insufficient to the application I'm working on (and would be too for some others which I had already worked, so, either I'm too unlucky or the standard is weak).
- Again on JAAS: For the application side, it's standard. However, for every application server out there, there is a distinct way to configure it. Ok, for applications which find users and plain or hashed passwords in a DB table, probably there is an easy way to configure some sort of login module with an SQL query. However, in our application, the credentials are dynamic as well, depends on the application configuration and on the application channel being accessed, and, as logic to validate all those is on the application, I'd like to use the application itself to validate users. However, in some containers, it's quite complicated to invoke the application to validate users. Go figure...
- Once again on JAAS: Because the JAAS configuration is specific for each application server, it's virtually impossible to just deploy an application in more than one application server without headache. So, if you code your application in an standard way, and cannot reliably deploy that same application on distinct standard-compliant application servers, then that standard is void and defective by design. In the other hand, a self-contained web application can be deployed on ANY web container (as long as you don't use that little friend, JAAS).
- Application servers take a lot of time to startup and deploy the application. Even though they are faster than some years ago, they are still slow. Compare the startup time with a simple web application running on a Tomcat or Jetty - just (very) few seconds.
- JPA has it's share of guilty in the slow startup times. For the current project, Hibernate alone takes about 30-40 seconds to map every entity (about 200 tables).
- The runtime performance for EJBs is also likely to be slower than a regular web applications. You can cluster, I know. But there are way too much proxies, interceptors, lookups, injections... I can't prove with numbers. But common sense tells me that.
- The standard API for type-safe queries in JPA (criteria API) is an abomination. But I had already discussed that, and solved it by using Querydsl.
Conclusions? For future projects I'll try to avoid EJBs as much as possible. Spring is likely to always be in the game for me, as it's a fantastic piece of software. Also, after so many years working with Hibernate (since 1.2.x) and later JPA, I'm pretty sure I would likely choose Querydsl SQL mode, which has no ORM, but has type-safe queries and DMLs (insers / updates / deletes). Also, it's metamodel is generated at compilation time, it has almost zero overhead on the application initialization (Hibernate as already stated, for us, takes 30-40 seconds just to initialize the persistence).
That is the beauty (but also for me, as a software architect, a frustration) of Java development. You have thousands of frameworks and libraries to choose from, and when most non-trivial projects are finished and set to production, they already use legacy technologies.