Tuesday, April 29, 2014

What should be the minimum dependency requirements for the next major OmniFaces version?

For the next major version of OmniFaces (2.x, planned for over a few months) we're currently looking at determining the minimum version of its dependencies. Specifically the minimum Java SE version is tricky to get right.

OmniFaces 1.x currently targets JSF 2.0/2.1 (2009/2010), which depends on Servlet 2.5 (2006) and Java SE 5 (2004).

In practice relatively few people appear to be using Servlet 2.5 so for OmniFaces 1.x we primarily test on Servlet 3.0. Nevertheless, Servlet 2.5 is the official minimum requirement and we sometimes had to go to great lengths to keep OmniFaces 1.x compatible with Servlet 2.5. As for the Java SE 5 requirement, we noted that so few people were still using this (especially among the people who were also using JSF 2.1) that we set Java SE 6 as the minimum. Until so far we never had a complaint about Java SE 6 being the minimum.

For OmniFaces 2.x we'll be targeting JSF 2.2 (2013), which itself has Servlet 3.0 (2009) as the minimum Servlet version and Java SE 6 (2006) as the minimum JDK version.

So this begs the question about which Servlet/Java EE and Java SE version we're going to require as the minimum this time. Lower versions means more people could use the technology, but it also means newer features can't be supported or can't be used by us. The latter isn't directly visible to the end-user, but it often means OmniFaces development is simply slower (we need more code to do something or need to reinvent a wheel ourselves that's already present in a newer JDK or Java EE release).

One possibility is to strictly adhere to what JSF 2.2 is depending on. This thus means Servlet 3.0 and Java SE 6. Specifically Java SE 6 is nasty though. It's 8 years old already, currently EOL even and we'll probably have to keep using this during the entire JSF 2.2 time-frame. When that ends it will be over 11 years old. At OmniFaces and ZEEF (the company we work at) we're big fans of being on top of recent developments, and being forced to work with an 11 years old JDK doesn't exactly fits in with that.

The other possibility is to do things just like we did with OmniFaces 1.x; support the same Servlet version as the JSF version we target, but move up one JDK version. This would thus mean OmniFaces 2.x will require JDK 7 as a minimum.

Yet another possibility would be to be a little more progressive with OmniFaces 2.x; have the technology from Java EE 7 as the minimum requirement (JSF 2.2 is part of Java EE 7 after all). This would mostly boil down to having Servlet 3.1 and CDI 1.1 as dependencies. Taking being progressive even one step further would be to start using JDK 8 as well, but this may be too much for now.

Besides the version numbers, another question that we've been struggling with is whether we should require CDI to be present or not. In OmniFaces 1.x we do use CDI, but mainly because Tomcat doesn't have CDI by default we jump through all kinds of hoops to prevent class not found exceptions; e.g. using reflection or using otherwise needless indirections via interfaces that don't import any CDI types, which are then implemented by classes which do, etc.

As CDI is becoming increasingly more foundational to Java EE and JSF is on the verge of officially deprecating its own managed beans (it's pretty much effectively deprecated in JSF 2.2 already), plus the fact that CDI is pretty easy to add to Tomcat, such a requirement may not be that bad. Nevertheless we're still pretty much undecided about this.

Summing up, should OmniFaces 2.x require as a minimum:

  1. Exactly what JSF 2.2 does: Servlet 3.0 and JDK 6.0
  2. Same pattern as OmniFaces 1.x did: Servlet 3.0 and JDK 7.0
  3. The versions of Java EE 7 of which JSF 2.2 is a part: Servlet 3.1, CDI 1.1 and JDK 7.0
  4. An extra progressive set: Java EE 7 and JDK 8.0

What do you think? If you want you can vote for your favorite option using the poll at the top right corner of this blog.

Arjan Tijms

9 comments:

  1. Hi! I really like the one version back as buffer model. This would mean that you support JDK 7, JSF 2.1, 2.2, CDI 1.0 and CDI 1.1.

    If you roll with the Apache stack Java EE 7 is not available yet so I would be locked out. Then again supporting just Weld might be OK for you.

    To be honest I am not very found of the static helpers and that stuff in Omnifaces, it does not match the modern programming model of Java EE. I would stop with that, demand CDI 1.0. Stopping with the static stuff also means adding a api.jar imo.

    I would love for example if you allowed me to @Inject a richer API than facescontext. All the information you usually try to parse out yourself from facescontext, externalcontext, request etc should be readily available in that api instead. Like this:

    @Inject // figure out a better name
    OmniContext omniContext


    //...

    String currentPage = omniContext.getView();

    Also if you go ahead and read this: http://zeroturnaround.com/rebellabs/watch-out-for-these-10-common-pitfalls-of-experienced-java-developers-architects/

    You realize that OmniContext object is nice but you should go further:

    @Inject
    @CurrentPage
    String page;


    These annotations should be in a seperate jar (api).

    Thx for Omnifaces!

    ReplyDelete
    Replies
    1. Thanks for the comment!

      It's certainly an idea to look into injecting the items which are now provided by the static methods. We have actually been toying with the idea, but couldn't find the right level of abstraction yet.

      As you mentioned more or less, just injecting what is now the Faces class as an instance might not be super useful, but creating an annotation for each and every method in Faces (and some of the other utility classes)... well, that will be quite a lot of annotations.

      Having the annotations in one jar, maybe all default producers for that in another jar, and then OmniFaces as its now in the normal omnifaces jar would maybe be an option, although we kind of have a one-jar philosophy and such setup doesn't quite play well with that.

      Delete
    2. Yes it is true that god objects are bad but scattering your api across many annotations or classes is not helpful either :-) Perhaps collect not so common things in ExtendedWebContext object, commons are in WebContext. Everything in webContext is also directly injectable

      About jars...
      You can do both. Many frameworks offer both a god.jar and then a modular structure as well. I think weld is packaged this way for example. OWB only offers the modular structure but probably should offer OWB-all as well.

      omnifaces-simple -> no cdi dependency and only omnifaces 1.x features and whatever you felt for adding. Here users with plain jsf projects can be supported still.

      omnifaces-all -> Everything

      Internally you have four modules and you offer those as separates as well. jsf-core cdi-core and api-core. Yes this means that committer x and y that joins omnifaces can add spring-core if they want. It also means someone can create a custom backend when they mix jsf with other tech.

      Delete
  2. At least option 2, but I would choose option 3. Every JSF developer should use Java EE 7 nowadays.

    ReplyDelete
    Replies
    1. That's basically my idea as well, or more accurately I'm more of the opinion that if you use JSF 2.2 from Java EE 7 you'd probably want the rest of Java EE 7 as well. Unbalanced stacks, like using Servlet from Java EE 5, CDI from Java EE 6 and then JSF from Java EE 7 have never been my thing really.

      To clarify though; Option 3 (Servlet 3.1, CDI 1.1 and JDK 7.0) does not require the whole of Java EE 7, but just Servlet 3.1 and CDI 1.1 from Java EE 7. So Tomcat users have to add CDI separately, while Java EE users won't have any extra dependency to add.

      Option 4 is really asking for Java EE as a requirement, meaning we could theoretically make use of JMS or the Timer Service if so needed in a non-optional way.

      I know btw that the options are not perfect. More accurate would be to have 4 separate questions for the Servlet version, JDK version, etc, but I created a limited number of "logical groups" to limit the permutations somewhat.

      Delete
    2. So weld only then? A fat slice of users to cut off

      Delete
    3. Definitely not Weld only. IFF we would require CDI as a dependency then it would just be the CDI APIs and no particular implementation of CDI would be assumed.

      Meaning you'd be fine with either Weld, OpenWebBeans, CanDI or whatever else implements the CDI APIs.

      Delete
    4. Ok. Hopefully OWB CDI 1.1 is done before Omnifaces 2 then

      Delete
    5. We'll keep an eye out for it for sure. You may want to ping the OWB guys and ask them when they plan to have their 1.1 or 1.2 implementation (there was a small MR release a short while back).

      Also note that we're just investigating and gauging now. Although it's not an option in the poll, we could for instance also decide to go with Servlet 3.0 + CDI 1.0 + JDK 7, or maybe Servlet 3.0 + CDI 1.1/1.2 + JDK 7.

      There really are many permutations, and we didn't want to present them all to make the poll simpler. Yet, if the majority of users would be okay with adding a CDI 1.1 dependency, we guess they wouldn't have an issue with having CDI 1.0 as a dependency instead.

      OmniFaces 2 which will require JSF 2.2 may also take some time, and although we haven't decided about it either we could theoretically also opt for supporting OmniFaces 1.x with some new features for a little while (until we're sure that pretty much everyone who can update to JSF 2.2 can also update to CDI-something, Servlet-something etc).

      As said, we're just doing very preliminary research now and absolutely nothing has been decided yet ;)

      Delete