Sunday, August 22, 2010

Java EE 6 doesn't "just work" in even trivial real-world uses

Lincoln Baxter III writes that with Java EE 6, It all “Just works”.

Personally, I have not found that to be the case in even simple, toy applications.

I suspect it'll be true in a few years, probably after a much needed "Java EE 6.2" and some major bug-fixing. Right now it all "just works" ... except when it doesn't, which is frequently, due to spec oversights, bugs, and a general lack of real-world use and testing.

Using CDI "just works" until you realize that @Inject isn't supported in obvious places like a @FacesConverter due to limitations in JSF2/CDI integration. OK, that's easily worked around by looking up a managed bean from the FacesContext and getting the desired EJB from the @Inject site on that managed bean. Except that the ejb injection site is null during that phase of processing, having been helpfully cleared by CDI, so you get a null pointer exception that looks downright inexplicable until you figure out that CDI is clearing the injection site behind your back. (See: this report and this Mojarra bug). In that case I eventually found out how to look up the desired EJB via the BeanManager (See: http://dominikdorn.com/2010/04/cdi-weld-manual-bean-lookup/) but it certainly doesn't "just work" even between ostensibly co-operating, integrated technologies.

I hit that roadblock *after* getting stuck on a Glassfish/CDI integration bug (https://glassfish.dev.java.net/issues/show_bug.cgi?id=13040) that means that those nice new no-interface views of local EJBs don't actually work if you inherit methods from a superclass and are using Glassfish (even 3.1 as of build 15).

To add to the confusion, often using the JSF2 injection support to do something works, but CDI doesn't, or vice versa. And where the JSF2 or CDI injection support works on Glassfish it'll often fail on the (admittedly alpha) JBoss AS 6 or vice versa.

This is in my first JSF2 project on a Glassfish 3.0.1 container, using all the new "just works" stuff, and I must say that it sure as hell doesn't "just work" some of the time.

Another factor that doesn't help is all the legacy surrounding Java EE / J2EE. It's hard for someone trying to learn Java EE 6 to separate it from all the JE22 4 and Java EE 5 stuff. Even within Java EE 6 there's "new legacy", things that are effectively deprecated even though they've barely been released. Consider JSF2 scope annotations (replaced by CDI), JSF2 @ManagedBean (replaced by the Managed Beans specification, then promptly replaced again by CDI, all within the span of the Java EE 6 spec) and JSF2 injection support (replaced by CDI). It takes a great deal of sorting out before you can have much idea what the real, practical difference is between:

@javax.faces.bean.ManagedBean
@javax.faces.bean.SessionScoped

and:

@javax.inject.Named
@javax.enterprise.context.SessionScoped

let alone @javax.annotation.ManagedBean (hooray pointless duplication).

Then there's un-muddling the chaos of @Inject, @EJB and @Resource (which I'm still struggling with, since @EJB seems to be used by CDI in a *completely* *different* context), the difference between injecting an EntityManager via @PersistenceContext vs @Inject, etc.

No, it really, really doesn't "just work". It's a nightmare of overlapping, muddled conflicting specs and half-integrated half-co-operating implementations with weird quirks and holes in their support. It really needs an EJB 6.2 release that clearly deprecates all the old stuff and documents how it all interacts.

I've finally got to the point, in my efforts to learn about Java EE 6, where I'm starting to see the bigger picture of how it's *supposed* to work, and supposed to fit together. I can see now how it's meant to be simple to use, and if you don't hit any of the exciting bugs it even can be simple to use and nice to use.

The biggest single improvement that could be made to Java EE 6 is the heavy use of the @Deprecated annotation on 80% of the existing public interfaces, and the option to deploy an app in a CDI-only, no-JSF2-injection, legacy-free environment where attempts to use legacy container services are detected as errors (in development mode) or are ignored/fail (in production mode).

It'd also help to have some centralized documentation that's not focused on one particular implementation, framework, etc, and clearly takes account of spec versions so as to disambiguate discussion about J2EE4, Java EE 5, Java EE 6, and Java EE 6.1.

9 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. I don't disagree with a lot of the frustrations you have, though, I think that the primary cause is due to something you mentioned in your last statement.

    ( http://ocpsoft.com/opensource/the-problem-is-not-the-system-the-problem-is-education/ )

    Working on that part ;)

    ReplyDelete
  3. Also, you should look at the JBoss Seam 3 project. http://seamframework.org, the frustrations you're having about lack of CDI integration are specifically addressed by these projects.

    Consider EE to be a launching point, designed to be extended by 3rd party frameworks like Seam, which make things much easier to use and be productive.

    Seam faces in particular:

    http://docs.jboss.org/seam/3/faces/reference/snapshot/en-US/html_single/

    Specifically addresses most of your JSF concerns about injection in Converters and Validators, and I know that JSF 2.1 is also going to be fixing that in the core JSF framework itself.

    If you look deeper, you'll see that folks are aware of the problems, and are working on providing solutions. As you said, though, it is new, and it's still getting better :)

    ReplyDelete
  4. Lincoln,

    Thanks for taking the time to read and think about this, and for your comments.

    I'm aware of SeamFaces (and want to thank you for your work on it and in improving JSF in general) but I'm also aware it's prerelease code. There's no clear indication of *how* prerelease it is - whether it's at the "not production tested, but feature complete" or "beware, eats kittens" level of readiness. The release plan on the project page says:

    "(status: draft) - This plan is still being defined."

    and the release plan shown suggests that it's about half-way to feature-complete. It looks like something to watch, but not to use even in new code a long way from release.

    OTOH, yesterday I found a Seam status update:

    http://planet.jboss.org/post/seam_3_status_update

    that suggests that it's closer to beta status, though it gives no indication of what that means in this case or what the status of the various components in SeamFaces is.

    I'm usually more than happy to work with pre-release code - I learn more and faster that way, and by the time my code is ready to be deployed the bleeding edge has generally turned into the current stable version. OTOH, it needs to be finished enough to work for the intended purpose, and from the site it's hard to tell if Seam Faces 3.0 fits that description yet.

    Perhaps some edits to the SeamFaces page that provide an indication of what's ready for wider testing and non-production use would help?

    The other problem is that you need to know it exists, and that you need it. It takes a while to get to the point of realizing that FacesConverters aren't *supposed* to support injection, let alone finding out that there are efforts underway to address that limitation. Again, the issue is with the lack of broad overview documentation as much as anything.

    I'd be interested in what you think of the Java EE 6 conceptual overview I'm working on here:

    http://soapyfrogs.blogspot.com/2010/08/java-ee-6-is-not-product-you-can.html

    ... as I'm trying to put something together that'll help someone who doesn't already know EE 5 figure out how it all fits together, where the pitfalls are, etc.

    Anyway, I actually really like what I've seen of the EE 6 stack so far, I just took issue with your suggestion that it "just works". Between bugs, spec oversights and documentation issues, it doesn't "just work" - but once you know where the potholes are and how to avoid them, it does work and work well, and continues to improve. I just hope EE 6 can be polished for a while before an EE 7 sweeps through breaking things all over again...

    ReplyDelete
  5. Hmm. Just found the real status list for the modules, which isn't exactly hidden, though it'd help if the SeamFaces page referenced it.

    http://seamframework.org/Seam3/ProjectStatusAndDirection

    It doesn't provide much detail or any real indication of whether each module is in a potentially usable state, though. The lack of milestone releases for "less broken" snapshots of SeamFaces and the currently broken build doesn't reassure.

    Also: The issue with injection into converters doesn't appear to be covered in the seam JSF 2.1 wishlist , which is surprising for an acknowledged issue in the spec.

    ReplyDelete
  6. Hmm. No go with SeamFaces so far. Updated the project to Maven 3, added the required repositories, enabled access to the snapshots, and added a dependency on org.jboss.seam.faces:seam-faces:3.0.0-SNAPSHOT. It pulled in version 3.0.0-20100824.040350-4 (the latest). However, if seam faces is in the dependency list and therefore bundled into the .war, the app fails to deploy on Glassfish 3.0.1 even if it doesn't explicitly use seamfaces anywhere:

    org.glassfish.deployment.common.DeploymentException: WELD-001408 Injection point has unsatisfied dependencies. Injection point: field org.jboss.seam.faces.transaction.TransactionPhaseListener.transaction; Qualifiers: [@javax.enterprise.inject.Default()]


    (Full error here: http://pastebin.com/sScywJWf)

    There's no alpha release later than April, and the CDI support for FacesConverter was added after that according to the roadmap.

    Could try on Glassfish 3.1...

    ReplyDelete
  7. Don't use the snapshot. Use Alpha3

    ReplyDelete
  8. An update on this: With Seam 3 now at release quality, it reduces the pain of using EE 6 significantly. There are still plenty of pain points and using Seam 3 on Glassfish requires some additional work but it's a big improvement.

    ReplyDelete
  9. Just to add my 2p - I've developed in a lot of other languages (From Pascal/BASIC through to C#) and am currently required to migrate some of our C# code to Java for a specific deployment. As a newbie to the arena, I can say that I'm finding Java to be incredibly frustrating. It feels like for everything I'd normally do in 2 lines, I now need to use 20 and edit some config files. Added to that, I've had to start over 3 times now because it turns out that the tutorial I'm following is out of date.

    Right now, I'd kill for an MSDN equivalent with the "correct" (or at least latest) way to do something and - dare I say it - _good_ code examples.

    At the moment, all I keep thinking is "What a lot of effort for something that should be simple". I'm spending far tooo much time reading up on 30 different approaches, each with their own set of deficiencies/quirks, etc, when all I actually want to do is solve the business problems I have.

    Surely the dev tools/environment/etc... Should be there to make solving real problems easier? Not make me learn 10 different ways to retrieve/parse JSON from a RESTful API before finding a suitable one?

    ReplyDelete