Archive

Author Archive

The curious case of JBoss AS 7.1.2 and 7.1.3

January 9, 2013 14 comments

At the moment of writing, JBoss AS 7.1.1 is the latest version of JBoss AS that can be downloaded from their usual download page.

This release is nearly 1 year old, and contains quite a lot of really serious bugs. There is a JBoss AS 7.2 in the works, but since not even an alfa, milestone or beta version has been put on the download page, it might not be unrealistic to surmise a release of that is still at least some time away. For JBoss AS 5 it took over two years (2006-11-17 to 2008-12-05), for JBoss AS 6 one year (2009-12-02 to 2010-12-28) and so on. Although for smaller releases the time is typically shorter, e.g. 7.1 was just below three months (2011-11-22 to 2012-02-16).

JBoss AS 7.2 will undoubtedly fix many of the open bugs in 7.1.1, but because it will contain many exciting and fancy new features, it will almost surely also contain many not so exciting new bugs.

So, why doesn’t JBoss just fix a bunch of bugs in 7.1.1 without introducing any new features? Why isn’t there say a JBoss AS 7.1.2, 7.1.3 etc. Why do we have to wait so long for a new version only to get more new bugs?

Well, actually, this is exactly what they do. There is a 7.1.2 and 7.1.3 in which an enormous amount of bugs are fixed. The only thing is, those aren’t put on the regular download page, but on a ‘special’ download page that’s behind a login. Oh, and to make it kind of look like it’s another product the name is changed from JBoss AS to JBoss EAP and the version numbering is changed as well. 7.1.2 becomes 6.0.0 and 7.1.3 becomes 6.0.1. The WTP server runtime offered by JBoss Tools also plays this game along and puts the runtimes for those EAP builds under a different category. So with the “JBoss 7.1 Runtime” you can start JBoss AS 7.1.0 and 7.1.1, but for something that’s effectively JBoss AS 7.1.2 you need the “JBoss EAP 6.0 Runtime”.

Downloads are available from access.redhat.com/downloads, from which you have to click on “Evaluations and Demos”, and then on “JBoss Enterprise Application Platform Evaluation”. The download of the actual Application Server can then be found all the way at the bottom, called “Application Platform 6.0.1” in the case of JBoss AS 7.1.3 (aka EAP 6.0.1). There is a direct link, but it probably won’t work directly as you have to accept an evaluation license first.

But wait, evaluation license? Doesn’t that mean this is a derivate that’s not open source anymore? As it appears, this is not the case. These EAP builds are still fully open source, and a source archive is even provided as a download from the same page. But despite the fact that it’s still open source, the binary build cannot be used freely. I’m not a lawyer, and thus it’s a bit difficult to understand how this can be true. How something can be a derivative of a fully open source product, be a fully open source product it self, but still can not be used freely. Undoubtedly JBoss has this legally covered, but for a simple user such as myself it’s not easy to understand.

There is a large discussion about this on the JBoss community forum and Jason Greene (project lead) goes to great lengths to explain the situation, but a lot of questions remain. One way around the restrictions imposed by the evaluation license is to build the code from source:

Jason Greene:

Self build and support EAP – You get some of the benefits of the enterprise releases (e.g. patches to older major versions and so on), but you have to invest time and energy to build and maintain/verify your app server distribution bits.

However Rich Sharples remarks:

Right now we do not have a way of making EAP easily buildable for the general public (nor does the L-GPL or GPL require us to)

Until thus far this situation has not been resolved. One detail that comes up often is that EAP provides patches for “older” releases. In that thinking, if you want the latest and greatest you can get the community edition (AS), and if you want stability and accept older functionality, then you can buy the enterprise version (EAP). However, for nearly a year now, the EAP version is the latest and greatest. The last community release as mentioned is 7.1.1, so for all intends and purposes, the EAP versions corresponding to 7.1.2 and 7.1.3 are both the latest and greatest as well as the most stable release.

But about how many bugs are we exactly talking? Is all of this really worth the trouble? Let’s take a look.

There were 400 bugs fixed for JBoss AS 7.1.2.Final.

Then there were some 234 fixes for JBoss AS 7.1.3.Final.

Additionally there are even more fixes done. Namely, the mentioned 7.1.2.Final and 7.1.3.Final are just tags in the JBoss AS repository. This tag is presumably cloned into another repository, and there more fixes are done. Eventually, 7.1.2.Final became 7.1.2.Final-redhat-1 when it was released and 7.1.3.Final became 7.1.3.Final-redhat-4. Those additional fixes are mostly publicly tracked. Mostly, because there seems to be some tracking going on at restricted pages.

For 7.1.2.Final-redhat-1 there are 40 issues mentioned.

For 7.1.3.Final-redhat-4 there are 36 issues mentioned, but there are 3 intermediate versions with 126, 34 and 86 issues fixed.

Of those additional issues, further complicating the AS/EAP split is that an amount of them are direct clones from issues in the JIRA for AS. Those start with the word “CLONE”.

In total we have thus at least 634 fixes, and then some estimated 150 additional fixes (guessing the overlap is about 50%). So this are approximately 750 fixes, among which are some that are just by themselves a blocker for using JBoss AS 7.1.1 (depending on your use case). It thus definitely seems to be worth it to go for the 7.1.3 release instead of the 7.1.1 one.

Even though the EAP builds are open source and have their source available for download, there doesn’t seem to be a public repository for those ‘additional fixes’. The 7.1.2.Final and 7.1.3.Final tags however are directly accesible on Github. Since those are just tags, and not actual releases, there are no artifacts available for them in a Maven repository. For the EAP builds, there is as mentioned above no source repository available. Instead there is a public FTP server where the source is hosted (this is the same source as is also available as an archive from the restricted download page). Additionally, there is a Maven repository. There is the following somewhat disheartening disclaimer though at the root:

Red Hat reserves the right to modify the behavior and content of this repository or remove it completely with little or no notice.

The question after all of this is though, why does JBoss do all of this? Why does it hide the releases with bug fixes and why does it try so hard to keep up the illusion that JBoss AS and JBoss EAP are two completely different products?

The answer as stated in the above referenced forum discussion is that it mostly has to do with monetization. JBoss as any other company does have to pay its developers. Even open source developers of course need to be able to buy food at the end of the day. The thinking goes that if all binary builds were freely available, then less people would be inclined to buy a support contract. The support contract not only provides you with support, it also gives you access to the binary builds without the restrictions as opposed by the evaluation license. So with this setup, JBoss benefits from open source in that a lot of people from the community are able to report bugs with a detailed analysis of where things go wrong in source, possibly even with patches attached that fix said problem. Simultaneously they also, kind of, benefit from the closed source model, where you can charge customers for the software itself.

It’s undoubtedly a difficult balance, since as said even the restricted JBoss EAP builds are still open source and JBoss remains an open source company. The split between AS and EAP must eat away at least some resources as well. The clone into another repository, the merging of changes done there back to the mainline, keeping duplicated (cloned) issues, creating Eclipse server runtimes that are nearly identical, a separate Maven repository, etc etc.

Personally I wonder if in the end all of this is really worth the trouble. Why not just release every version as “JBoss AS”, put every version on the public download page, and then offer a support contract independent of access to the binary builds. If it’s really needed, some versions could be tagged as being specifically allegeable for support. Just like Canonical does with Ubuntu. Every version is freely downloadable and support can be bought separately. Some versions are supported for a longer time and get the “LTS” tag.

At the very least, JBoss could probably do a better job in advertising that there even is a 7.1.2, 7.1.3 etc available that are bug fix releases. I’ve been a JBoss user for some time and it wasn’t after some years that I finally discovered what was going on with EAP. Before that I just thought that EAP was the name of their support program. I literally had no idea that there were entire series of JBoss releases that were only available via EAP and thus didn’t appear on the public download page.

Categories: java, java ee

Popularity of UI technology on Devoxx ’12

November 21, 2012 Leave a comment

The wildly popular Java conference Devoxx was held last week in the beautiful city of Antwerpen.

Besides talks and lab sessions, Devoxx has another interesting concept: a bunch of whiteboards on which people can write stuff and where other people can react to. In this time and age and especially given the target crowd of Devoxx it’s a very low-tech solution, but interesting nevertheless.

The Devoxx organization posted pictures of all those whiteboards on Flickr. My eye felt on the following picture, which asked people to vote on their favorite UI technology:


(Source: Flickr (C) BeJUG)

Counting the votes gives us the following list:

  • JavaScript/HTML 5 (43)
  • Vaadin (22)
  • JSF (17)
  • JSP/SpringMVC/Struts (17)
  • GWT (17)
  • JavaFX (11)
  • Wicket (10)
  • Swing (8)
  • RCP (7)
  • Angular (6)
  • ZK (5)
  • Grails (4)
  • OmniFaces (3)
  • Play! (3)
  • DART (2)
  • Flex (2)
  • Java Applet (1)
  • AWT (1)
  • India (1)
  • REST + JS (1)
  • SAP v15 (1)

We must realize that this kind of voting is of course not very formal. There is no telling whether someone didn’t vote twice or more, or whether some votes weren’t ‘accidentally’ wiped out. That said, assuming people aren’t too malevolent there are a couple of interesting things to note here.

First and foremost is the analysis of the actual question: “I prefer to build business app UI with”. This question is interesting, since it specifically asks what people prefer to use, not what they actually use. It’s a shame perhaps nobody had the wits to pose a followup question on another whiteboard asking what people actually use. Also of interest is that the question does not specifically refer to a segment of technology. I.e. there’s no mention whether the question is about mobile-, desktop-, or web apps. Just that it’s about “business apps” (whatever that means).

Regarding the actual votes it’s remarkable how many votes went to a non-Java solution, given that Devoxx is a Java conference. The majority vote went to JavaScript/HTML 5 with some 43 votes. The figure is even higher considering that the Angular and REST + JS votes are pretty much the same thing. I dare say that REST + JS is the exact same thing even, bringing JavaScript/HTML 5 to 44 votes. My guess is that Angular is a subset of the JavaScript/HTML 5 votes. People voting that one first, and then more specifically use Angular for their JavaScript needs. Another popular subset that wasn’t asked for is probably jQuery.

Next up is the divide between client and web technologies.

RCP, JavaFX, Swing, AWT, Java Applets and Flex are clearly client technologies that can mostly be used for ‘regular’ desktop applications. Of these, JavaFX got the popular vote, but the often criticized Swing is not that far behind. Amazingly, one loner still preferred plain AWT and judging from the handwriting plain Java Applets as well.

Vaadin, JSF, JSP, Spring MVC, Struts, GWT, Wicket, ZK, Grails, OmniFaces, and Play! are all web technologies. GWT code essentially compiles into a (JavaScript) client application, but nevertheless is part of the web framework ecosphere. Of these, Vaadin got the popular vote. Maybe this has something to do with the Vaadin team having a presence on Devoxx (of course it’s perfectly okay for them to vote on their own framework), or maybe the votes are all from non-Vaadin developers. JSF, “JSP/Spring MVC/Struts”, and GWT together share the second place in the web framework ranking with 17 votes each.

A look of disgust will surely come over Matt Raible’s face upon learning that developers in fact DO prefer JSF, despite his personal bias 😉 This time around, Matt can’t ask “but who actually likes JSF” (as opposed to who’s using it), since the question is already about preference.

The entry about “JSP/Spring MVC/Struts” is a little problematic. I’m not sure what the idea here was, but I figure someone thought it was a good idea to suddenly introduce the category of “request-based frameworks”. We thus don’t really know who voted for any of these 3 technologies separately, although I hope most people just ignored Struts here and took the question as asking for using SpringMVC with JSP (as opposed to with Thymeleaf). Furthermore, OmniFaces is a case of its own as well. This is by itself not a UI framework, but a utility library for JSF. In a similar vain, things like PrimeFaces, RichFaces, etc aren’t themselves UI frameworks either, but component libraries/sets for JSF. In a way, DevRates makes the same kind of ‘mistake’.

Remarkable is the low score of the much hyped Scala framework Play!, with only 3 votes (the same amount as utility library OmniFaces). This is extra remarkable since Typesafe was present on Devoxx as well and has undoubtedly been bussy bringing Play! to the attention of the Devoxx attendees. Groovy framework Grails didn’t got so many votes either. Both frameworks typically end a bit higher in polls and surveys.

As mentioned in the beginning of this article the results here should be taken with a grain of salt due to the informal setup. Maybe next year Devoxx can have an electronic voting system, where visitors can add their own questions and answers, but where voting happens with the RFC based wristband?

Categories: java

Is there such a thing as the NoMock movement?

September 11, 2012 19 comments

One of the things that’s often advocated for a good software development process is having unit tests.

The more of those tests we have, the better. Having them increases our confidence that our code works as we think it works, isolates issues quickly to the area where they are introduced and thus increases our ability to do refactoring.

Central to unit testing in object oriented systems is the concept of a “Mock”. Those software systems largely exist out of objects that collaborate with each other in some way. Objects having internal references to other objects are said to be having dependencies on those other objects.

In unit testing we would like to test the smallest possible unit, which represents a single code path through a single method. As soon as that code calls a dependent object, we can’t call it a unit test anymore. In order to restore balance, and make the world perfect again, all those dependencies should be replaced by fake objects, called Mocks. See e.g. When Should I mock.

For years we have learned that we all should do this. Unit tests are good, unit tests need mocks. Therefor we unit test, and therefor we mock. Life was simple.

Lately however a growing group of people seem out to disturb our perfect little world. Their creed: “Mocks are wrong. We should use real objects”. They don’t seem to have a name yet, but following the NoSQL movement, let’s call them the NoMock movement.

Among them are people like Bill Burke, Dan Allen, Andrew Lee Rubinger, Augie Fackler, Nathaniel Manista and Stan Silvert.

They spread their ideas in blogs and presentations, e.g.:

So what exactly did we thought mocks bought us and what parts of that are those NoMock guys rebutting?

One benefit of mocks that comes up often is performance. Surely mocks are much faster than using say a real EJB as a dependency that requires starting up a WebSphere server that takes 30 minutes for a cold start alone, and then some unholy amount of time to deploy the actual application that among thousands of other beans contains this single bean we need.

While this may have been true in the past, it’s indeed true that the current crop of application servers starts up in a second or less on modern hardware. Via tools such as Shrinkwrap it’s easy to define micro-deployments and deploy those with another tool like Arquillian in mere milliseconds.

Another much touted benefit of mocks is the ability to run tests independently of some global resource. For a large number of cases, this global resource is then the main database on which an application depends.

In this case we could ask ourselves whether this global resource is really a global one. Many databases can be installed locally with great ease (think PostgreSQL and MySQL). A best practice in software development is to be able to install the entire application stack that you’re developing on your local workstation anyway. Sure, there are exceptions if big external mainframes are involved, but for many common types of development this should be possible. If for some reason this is difficult or even impossible, then the team likely has much bigger problems to worry about. Namely, more often than not that difficulty is caused by things like software depending on “some server” that “someone once installed” and now “nobody knows what it exactly does”. This will not only make (unit) testing extraordinary difficult, but will also impede proper debugging and staging.

So, with some exceptions, could we perhaps say that mocks in this case are used to cover up another code smell? Surely this can’t be a good practice, can it?

A more profound statement uttered by the NoMock movement is that testing with mocks simply isn’t really useful. By extension they thus seem to be saying that unit tests are just not really useful.

Obviously, this is a controversial statement that goes against common wisdom, and it surely may shock people who always did unit testing “because it’s what we should do”, without giving it much thought. (will people who did think it through not be shocked, and will they simply revolt against such a statement?)

The canonical unit test example is that of the calculator. Here we test an add() method by providing it with some well chosen sample points. Two positive numbers, a negative and a positive number, two negative numbers, etc. Every time we check that the output is what we expected. Without a doubt unit tests are very helpful here.

But the simple add() method didn’t had any dependency that we needed to mock. It’s a pure “functional” thing; the output depends only on the input, and nothing else.

Let’s now look at an example that does use dependencies. Better yet, let’s dive in deep and go straight to an example where a collaboration between objects is the main goal. For that, consider a typical Service facade where a method starts a transaction and calls two DAOs that persist something to a DB. The idea is that both DAOs join the transaction, and that either the data from both DAOs ends up in the DB, or none at all. The DB has some contraints set for the data that we are persisting.

This is what the class looks like:

@Stateless
public class ServiceFacade {

    @EJB
    private DAO1 dao1;

    @EJB
    private DAO2 dao2;

    public void doStuff(SomeObject someObject) {
        dao1.foo(someObject);
        dao2.bar(someObject);
    }

}

Per the rules of the unit test, we now have to mock our two DAOs and then our test will swap in those mocks before calling the method that we want to test. In order to do that, we first need to add two setters for those mocks:

@Stateless
public class ServiceFacade {

    @EJB
    private DAO1 dao1;

    @EJB
    private DAO2 dao2;

    public void doStuff(SomeObject someObject) {
        dao1.foo(someObject);
        dao2.bar(someObject);
    }

    public void setDAO1(DAO1 dao1) {
        this.dao1 = dao1;
    }

     public void setDAO2(DAO2 dao2) {
        this.dao2 = dao2;
    }
}

Now we also need to create our mocks. Let’s create a mock that just remembers if it’s being called. A mock for DAO1 could look like the following:

public class MockDAO1 implements DAO1 {
    private boolean isCalled; // + getter

    public void foo(SomeObject someObject) {
        isCalled = true;
    }
}

The mock for DAO2 will look the same. Now we’re ready to do our test:

DAO1 dao1 = new MockDAO1();
DAO1 dao2 = new MockDAO2();
ServiceFacade serviceFacade = new ServiceFacade();
serviceFacade.setDAO1(dao1);
serviceFacade.setDAO2(dao2);

serviceFacade.doStuff(new SomeObject());

assertTrue(dao1.isCalled());
assertTrue(dao2.isCalled());

After we run this code, the test passes and we’re happy. The code works! YES! 😀

Taking a step back; what did we *really* test? Well, uhm, we tested that Java was able to call two methods on two objects. Great, it’s able to do that.

What we however really wanted to test was whether the data actually ended up in our DB and whether both DAOs joined the transaction to see if the effects of DAO1 are correctly undone (rollbacked) when DAO2 throws. In our test with mock objects, we could build a mock DAO2 that throws an exception, but this will surely not make DAO1#isCalled false again.

Now we could try to build some mock transaction manager, perhaps store it in TLS, then make our mock objects “mock transactional” objects, and then we could… but who are we kidding here? What would we *actually* be testing?

Aren’t we not blindly following the rules of the unit test here, without giving it a second thought of why we are actually doing it and what benefit it brings us? It’s this a bit like putting auto-generated comments above our methods, just to make the code analyzer happy?

Maybe those NoMock guys got me to rethink my strategy…

The state of @DataSourceDefinition in Java EE

June 30, 2012 3 comments

Traditionally, Java EE favored deploying applications with so-called unresolved dependencies. I talked about this in some more detail in a previous blog entry, but practically it boils down to the fact that a Java EE application can rarely be run as-is on an Application Server (AS hereafter).

Instead, specifically for the application that you want to run, all kinds of things have to be created and configured on the AS. Of course, this is different for every other implementation of such an AS, like JBoss, GlassFish, WebLogic, etc. So Java EE applications that are in theory portable, aren’t so in practice because of this ‘little’ thorny issue.

Worse, even if the application is to be run only on say JBoss, you traditionally can’t just take the .war or .ear and deploy. It has to be accompanied by some readme that explains which datasources, jms queues, roles etc need to be created. In JBoss AS 7 for example, all this has to be added to a single .xml file inside the AS.

So even if you only want to quickly test a single application, you’ll have to make many modifications to your installed AS. Imagine that every time you wanted to run a Windows or OS X application, you first had to thoroughly study some readme, make a ton of changes to your internal OS configuration files and only then after some trial and error would be able to run the app. Without a shadow of doubt, this would not fly with many people.

So do we really need to accept this for Java EE applications?

The short answer is “still a little, but it’s getting better”.

As an important step towards ready-to-run applications, Java EE 6 has standardized the way a data source is defined. This can be done via either an annotation (@DataSourceDefinition) or an element in web.xml, ejb-jar.xml or application.xml (data-source). Although the Java EE specification is rather clear in what has to be supported, its weak point is in enforcing that it’s actually supported. This mainly happens via the often criticized TCK (Technical Compliance Kit), which seems to spot check for features and behavior instead of exhaustingly making sure each and every thing specified is present.

On top of that, some vendors (notably JBoss), didn’t seem particularly thrilled about this approach. As a result, adoption of standardized internally defined data sources was initially slow.

However, the situation has greatly improved lately. After initially flat out refusing to support embedded data sources, JBoss has given in to support it anyway (via their proprietary -ds.xml mechanism). Up until the latest JBoss AS release (7.1.1) the standardized data source definition didn’t work really well, but in the recently released JBoss EAP 6.0.0 (a branched JBoss AS 7.1.2) it finally seems to work. JBoss EAP 6.0.1 (a branched JBoss AS 7.1.3) was also tested and luckily it also still works there.

To see how a variety of servers was doing, I tried to run the application I discussed at my above given previous blog entry on them, without making any modifications. The follow is the result:

Name Works Embedded driver Remarks
JBoss EAP 6.0 (AS 7.1.2) V V After AS shut-down, Hibernate tries to drop schema, but DB already closed at that point.
GlassFish 3.1.2 V X
WebLogic 12.1.1 V V Seems to start embedded DB twice, leading to locking errors in case of H2 on disk. Workaround by following strict shut-down/restart pattern
TomEE 1.1nightly V V After AS shut-down, DB tries to close itself, but classes already unloaded at that point. Note that TomEE 1.1 hasn’t been released yet.
Resin 4.0.28 V V
Geronimo v3.0 X V Doesn’t deploy when persistence.xml references datasource. Seems to be able to load driver from war, but lots of exceptions and failures everywhere.

As can be seen, two AS implementations struggle with an embedded DB that closes itself. Both JBoss EAP 6 and TomEE 1.1 threw exceptions at shut-down, though quite different ones. WebLogic had the reverse problem, instead of issues at shut-down time the issues were at start-up time, but only when restarting the server “the wrong way” (described here).

GlassFish was the only AS unable to load the DB driver from within the .war. This is a shame, as this is a very important feature for embedded databases (the driver jar -is- the DB in that case) and thus still requires the user to change something to the installed AS.

Geronimo was the only AS that didn’t work at all. As soon as the datasource was referenced in persistence.xml deployment of the application failed. Apparently the JPA processor can’t find the datasource when it’s setting up the persistence units. Removing JPA and attempting to inject the datasource directly semi-worked. Deployment succeeded and injection happened, but Geronimo appeared to be unable to set the vitally important url property. An issue has been created for this at their JIRA. On the plus side, it did seem Geronimo was able to load the driver from the war, but without anything else working this isn’t of much use in practice.

Finally, the perhaps somewhat lesser known Resin 4.0.28 was surprisingly the only AS that didn’t seem to exhibit a single problem on my test application with respect to the embedded data source (it was however rather noisy when running this test application, throwing various kinds of “warning exceptions” about backing beans and even some internal JSF artifact not being seriablizable).

So overall the results are rather good. Some minor issues, but no real show-stopper as before. Unfortunately JBoss still tries to scare their users away from these embedded data sources, by explicitly calling it “for development & testing only“, but they do support it now and seem to support it rather well.

Java EE 7 will introduce various additional standardized embedded resources, like JMS queues and possible even an embedded platform default database, which further widens the options applications that need to be ready-to-run have.

I would like to stress that Java EE applications with unresolved dependencies are absolutely useful for those situations where they need to integrate into existing infrastructure managed by operations teams. This is especially true if operations and developers don’t 100% trust or even know each other. Places like these is where Java EE was traditionally used a lot, but with the current crop of lightweight* application servers, Java EE has the opportunity to branch out to many more places, including those that don’t need or want to use a strict separation between application and resources.

(* to give an indication; the example app is small, but does use JSF, EJB, JPA and BeanValidation, which means the container needs to start up a lot of services. Yet, a cold startup of every Java EE server tested with the app already deployed to it, took in the range of 1 to a few seconds at most)

Further reading

Categories: java, java ee

Is WebLogic 12c a heavy-weight enterprise solution?

May 1, 2012 2 comments

There are quite a lot of Java EE implementations, among which open source and closed source implementations.

The closed source implementations are traditionally not only known for their “closed sourceness”, but also for their “enterprise aspects”. Developers themselves typically associated them with the term heavy weight. Where TomEE needs just 25MB for the entire Java EE 6 WebProfile and GlassFish 3.1.2 81MB for the full profile, the closed source implementations are assumed to be many gigabytes in size (including all kinds of “middleware” and “value added business solutions”), unobtainable via a public download (a salesperson will contact you if interested), take up to half an hour just to bootup and will use gigabytes of memory.

But is all of this still true? To test this I tried to obtain, install and run a very simple CRUD application on WebLogic 12c.

The results of this exercise were rather good, although there are some points open for improvement.

First of all, WebLogic can simply be downloaded just like all open source implementations. The download size is 183MB, which happens to be the exact same size that JBoss AS 6.10 was (AS 7.1 has since been slightly trimmed to 127MB). Yes, there are the ye olde 1GB+ downloads as well, but the 183MB one is the default. The text on the page is initially slightly confusing. At first glance it looks like you need a 997MB download for 64-bits VMs, but apparently this is only if you want the installer version.

So far so good, but then a slightly disappointing experience: you don’t just need to accept the license, no, you need to register first despite the promise that you can “download the software now”. I can only imagine many developers drop off here and download JBoss instead. (The company I work for among others investigates these kinds of flows and the drop off rate for each such hurdle is indeed dramatic)

The ones who do proceed to register, hoping for a quick “username + password” form are disappointed again. Here WebLogic/Oracle shows its enterprise face, as you have to fill out a huge form asking among others for your company and business phone. “Business phone”? Really!? Whoever made this form might not have had developers trying out things as their prime audience in mind. I filled out the form though and at least the download starts immediately after.

Hereafter I tried the usual steps to start the AS:

  1. Unzip downloaded archive
  2. Point Eclipse WTP server runtime to unzip directory
  3. Start AS via said server runtime

Unfortunately the server runtime didn’t recognize the directory where I unzipped WebLogic or any of its sub-directories. I quickly found a getting started by Arun Gupta and it appeared some scripts had to be run first. This getting started was a big help (thanks Arun!).

Running these scripts is not difficult really, but as I just blindly copy/pasted the commands I wonder why this can’t be automated or if it wouldn’t be possible to create a slightly smarter setup archive so this wouldn’t be needed at all. As said, it’s not difficult, but it’s a tedious chore, especially if you want to experiment with different installations. Things like this sadly contribute to the feeling of something being heavy-weight.

After this the dialog in Eclipse for creating the WTP server runtime recognized the WebLogic install immediately. A few remarks here though: for some reason I have to manually enter an external JDK home here. This feels sloppy, as the norm for Eclipse plug-ins is to offer the user a choice between the JDKs that are registered with Eclipse. On the same dialog there was also a text that “Server extensions Java Persistence 2.0” were enabled. I guess this is a left-over from an older WebLogic version where JPA 2.0 wasn’t yet the standard. I’m not sure this text still makes any sense for a Java EE 6 AS, but if anyone knows why this text is there please let me know.

I then finally started up WebLogic 12c and it surely didn’t take the many minutes people claim that this kind of software takes. Deploying the actual CRUD app didn’t take any significant amount of time either and my system certainly didn’t instantly started to swap. Strong points for WebLogic 12c here.

The default logging when starting up is also reasonably sane. The LoggingService is a bit noisy after the first startup, repeating the message about the log being rotated 3 times, but it’s certainly not page after page of unintelligible mumble jumble. To compare, the startup logs of JBoss AS 6.x and TomEE are much noisier. Here’s what the startup log looked like at my system:

<Apr 29, 2012 3:15:30 PM CEST> <Info> <Security> <BEA-090905> <Disabling CryptoJ JCE Provider self-integrity check for better startup performance. To enable this check, specify -Dweblogic.security.allowCryptoJDefaultJCEVerification=true> 
<Apr 29, 2012 3:15:30 PM CEST> <Info> <Security> <BEA-090906> <Changing the default Random Number Generator in RSA CryptoJ from ECDRBG to FIPS186PRNG. To disable this change, specify -Dweblogic.security.allowCryptoJDefaultPRNG=true> 
<Apr 29, 2012 3:15:30 PM CEST> <Info> <WebLogicServer> <BEA-000377> <Starting WebLogic Server with Java HotSpot(TM) 64-Bit Server VM Version 20.6-b01-415 from Apple Inc..> 
<Apr 29, 2012 3:15:31 PM CEST> <Info> <Management> <BEA-141107> <Version: WebLogic Server Temporary Patch for 13340309 Thu Feb 16 18:30:21 IST 2012
WebLogic Server Temporary Patch for 13019800 Mon Jan 16 16:53:54 IST 2012
WebLogic Server Temporary Patch for BUG13391585 Thu Feb 02 10:18:36 IST 2012
WebLogic Server Temporary Patch for 13516712 Mon Jan 30 15:09:33 IST 2012
WebLogic Server Temporary Patch for BUG13641115 Tue Jan 31 11:19:13 IST 2012
WebLogic Server Temporary Patch for BUG13603813 Wed Feb 15 19:34:13 IST 2012
WebLogic Server Temporary Patch for 13424251 Mon Jan 30 14:32:34 IST 2012
WebLogic Server Temporary Patch for 13361720 Mon Jan 30 15:24:05 IST 2012
WebLogic Server Temporary Patch for BUG13421471 Wed Feb 01 11:24:18 IST 2012
WebLogic Server Temporary Patch for BUG13657792 Thu Feb 23 12:57:33 IST 2012
WebLogic Server 12.1.1.0  Wed Dec 7 08:40:57 PST 2011 1445491 > 
<Apr 29, 2012 3:15:32 PM CEST> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to STARTING.> 
<Apr 29, 2012 3:15:32 PM CEST> <Info> <WorkManager> <BEA-002900> <Initializing self-tuning thread pool.> 
<Apr 29, 2012 3:15:32 PM CEST> <Notice> <LoggingService> <BEA-320400> <The log file /Users/henk/eclipse37ee/wls1211_dev/mydomain/servers/myserver/logs/myserver.log will be rotated. Reopen the log file if tailing has stopped. This can happen on some platforms, such as Windows.> 
<Apr 29, 2012 3:15:32 PM CEST> <Notice> <LoggingService> <BEA-320401> <The log file has been rotated to /Users/henk/eclipse37ee/wls1211_dev/mydomain/servers/myserver/logs/myserver.log00018. Log messages will continue to be logged in /Users/henk/eclipse37ee/wls1211_dev/mydomain/servers/myserver/logs/myserver.log.> 
<Apr 29, 2012 3:15:32 PM CEST> <Notice> <Log Management> <BEA-170019> <The server log file /Users/henk/eclipse37ee/wls1211_dev/mydomain/servers/myserver/logs/myserver.log is opened. All server side log events will be written to this file.> 
<Apr 29, 2012 3:15:34 PM CEST> <Notice> <Security> <BEA-090082> <Security initializing using security realm myrealm.> 
<Apr 29, 2012 3:15:34 PM CEST> <Warning> <Store> <BEA-280109> <Unable to load the native wlfileio library for the persistent file store "_WLS_myserver". The store will use buffered I/O. The store is still operating in a transactionally safe synchronous mode. See store open log messages for the requested and final write policies.> 
<Apr 29, 2012 3:15:34 PM CEST> <Notice> <LoggingService> <BEA-320400> <The log file /Users/henk/eclipse37ee/wls1211_dev/mydomain/servers/myserver/logs/access.log will be rotated. Reopen the log file if tailing has stopped. This can happen on some platforms, such as Windows.> 
<Apr 29, 2012 3:15:34 PM CEST> <Notice> <LoggingService> <BEA-320401> <The log file has been rotated to /Users/henk/eclipse37ee/wls1211_dev/mydomain/servers/myserver/logs/access.log00018. Log messages will continue to be logged in /Users/henk/eclipse37ee/wls1211_dev/mydomain/servers/myserver/logs/access.log.> 
<Apr 29, 2012 3:15:35 PM CEST> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to STANDBY.> 
<Apr 29, 2012 3:15:35 PM CEST> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to STARTING.> 
<Apr 29, 2012 3:15:35 PM CEST> <Notice> <LoggingService> <BEA-320400> <The log file /Users/henk/eclipse37ee/wls1211_dev/mydomain/servers/myserver/logs/mydomain.log will be rotated. Reopen the log file if tailing has stopped. This can happen on some platforms, such as Windows.> 
<Apr 29, 2012 3:15:35 PM CEST> <Notice> <LoggingService> <BEA-320401> <The log file has been rotated to /Users/henk/eclipse37ee/wls1211_dev/mydomain/servers/myserver/logs/mydomain.log00018. Log messages will continue to be logged in /Users/henk/eclipse37ee/wls1211_dev/mydomain/servers/myserver/logs/mydomain.log.> 
<Apr 29, 2012 3:15:35 PM CEST> <Notice> <Log Management> <BEA-170027> <The server has successfully established a connection with the Domain level Diagnostic Service.> 
<Apr 29, 2012 3:15:35 PM CEST> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to ADMIN.> 
<Apr 29, 2012 3:15:36 PM CEST> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to RESUMING.> 
<Apr 29, 2012 3:15:36 PM CEST> <Error> <Server> <BEA-002606> <The server is unable to create a server socket for listening on channel "Default[2]". The address xxxx:0:0:0:0:0:0:1%0 might be incorrect or another process is using port 7001: java.net.BindException: Can't assign requested address> 
<Apr 29, 2012 3:15:36 PM CEST> <Error> <Server> <BEA-002606> <The server is unable to create a server socket for listening on channel "Default[3]". The address xxxx:0:0:0:xxxx:off:xxxx:d7%0 might be incorrect or another process is using port 7001: java.net.BindException: Can't assign requested address> 
<Apr 29, 2012 3:15:36 PM CEST> <Notice> <Server> <BEA-002613> <Channel "Default[1]" is now listening on xxx.xx.xx.x:7001 for protocols iiop, t3, ldap, snmp, http.> 
<Apr 29, 2012 3:15:36 PM CEST> <Warning> <Server> <BEA-002611> <The hostname "localhost", maps to multiple IP addresses: 127.0.0.1, 0:0:0:0:0:0:0:1, fe80:0:0:0:0:0:0:1%1.> 
<Apr 29, 2012 3:15:36 PM CEST> <Notice> <Server> <BEA-002613> <Channel "Default" is now listening on xxx.xxx.x.xxx:7001 for protocols iiop, t3, ldap, snmp, http.> 
<Apr 29, 2012 3:15:36 PM CEST> <Notice> <Server> <BEA-002613> <Channel "Default[4]" is now listening on 127.0.0.1:7001 for protocols iiop, t3, ldap, snmp, http.> 
<Apr 29, 2012 3:15:36 PM CEST> <Notice> <Server> <BEA-002613> <Channel "Default[5]" is now listening on 0:0:0:0:0:0:0:1:7001 for protocols iiop, t3, ldap, snmp, http.> 
<Apr 29, 2012 3:15:36 PM CEST> <Notice> <WebLogicServer> <BEA-000331> <Started the WebLogic Server Administration Server "myserver" for domain "mydomain" running in development mode.> 
<Apr 29, 2012 3:15:36 PM CEST> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to RUNNING.> 
<Apr 29, 2012 3:15:36 PM CEST> <Notice> <WebLogicServer> <BEA-000360> <The server started in RUNNING mode.>

Then I tried to request a page on localhost:8080, but no response. After a cursory look at the log shown above, it appears that WebLogic listens to HTTP at port 7001 instead of the usual 8080. I’m not sure why WebLogic has chosen 7001 here. Is it a port that WebLogic started using before the convention of using port 8080 was established, or is it a deliberate choice, “Think Different”?

Using port 7001 I could now request the CRUD form of the sample app, but unfortunately, I couldn’t post back this form as a ViewExpiredException was thrown. It appeared that my browser (Safari) didn’t accept the JSESSIONID cookie being send:

Set-Cookie:JSESSIONID=k2yPPcdFtLyyQL2vBmjt1G2PkV3YJGhyPvnYZhDZmn0TGC5GjLsN!-180841883; path=/; HttpOnly

I posted about this on the Oracle forum (hey, one advantage of the registration, I could post right away) and continued using Chrome, which did accept the cookie.

Right after the post back of the form I immediately got another exception:

java.lang.IllegalArgumentException: No persistence unit named 'entityManager' is available in scope jsf_ejb_jpa. Available persistence units: []

Suspecting the datasource in web.xml wasn’t supported I tried to find out how to define a WebLogic-specific datasource in a war. When this didn’t seem to be possible after reading articles and Googling for the better of an hour, I created an EAR with such datasource. Unfortunately still the same exception.

By this time I was also frequently getting the following exception:

Caused By: weblogic.common.ResourceException: Database may be already in use: "Locked by another process". Possible solutions: close all other connection(s); use the server mode [90020-161]
	at weblogic.jdbc.common.internal.XAConnectionEnvFactory.makeConnection(XAConnectionEnvFactory.java:498)
	at weblogic.jdbc.common.internal.XAConnectionEnvFactory.createResource(XAConnectionEnvFactory.java:175)
	at weblogic.common.resourcepool.ResourcePoolImpl.makeResources(ResourcePoolImpl.java:1310)
	at weblogic.common.resourcepool.ResourcePoolImpl.makeResources(ResourcePoolImpl.java:1227)
	at weblogic.common.resourcepool.ResourcePoolImpl.start(ResourcePoolImpl.java:250)

I’m using the embedded H2 database here in disk mode, which uses a lock. For some reason WebLogic seems to initialize the datasource twice. Once when starting up, and once when deploying the application containing this (app scoped) datasource, which causes a lock conflict. After some twiddling, the right sequence to get rid of this is:

  1. Undeploy app while WebLogic is running.
  2. Shut down.
  3. Delete locks on filesystem.
  4. Start up.
  5. Hot deploy app.

This kind of problem doesn’t occur when using H2 in memory or server mode, or using other ‘regular’ databases, but it’s peculiar that of the servers I tested the CRUD app on (JBoss AS, GlassFish and TomEE), only WebLogic has this problem with the on disk locks.

After some more experimenting, it appeared the entityManager problem isn’t related to WebLogic 12c itself, but appears to be a known issue with the WebLogic 12c WTP Server runtime and exploded deployments. After deploying the packaged war, everything worked.

Better yet, of all the Java EE 6 implementations I tested, WebLogic 12c scores best here. It’s able to process the datasource in web.xml AND is able to load the JDBC driver jar from the war. In contrast, GlassFish required this driver to be internally installed. JBoss AS can load the driver from a war as well, but currently has some major problems with transactional datasources. TomEE’s beta 2 also didn’t work correctly (but this will most likely be fixed in their 1.0 release).

So to conclude, despite the problems I ran into, I’m fairly positive about WebLogic 12c from the perspective of a developer trying out Java EE 6 code. The supposed real power of WebLogic is in quite another area (scalability, fail-over, etc), but for developers to even consider WebLogic and not have it merely forced upon them by management, it should have the basics right too and I think it has.

To summarize, WebLogic with respect to a casual developer trying out Java EE 6:

Strong points

  • Downloadable
  • Reasonable download size (183MB)
  • Good startup time
  • Startup log is not overly verbose
  • Can load JDBC driver from war
  • Processes data-source element in web.xml correctly

Points that could possible be improved upon

  • Elaborate required registration before downloading
  • Simple, but required installation scripts after download
  • Port 7001 for HTTP is uncommon
  • Eclipse plug-in asks for external JDK

The one thing that is and remains an issue for developers in WebLogic is that it’s closed source. It does pack an amount of open source code, like Mojarra (JSF) and EclipseLink (JPA), but the general inability to step into source in order to find the root of an issue would personally hinder me in my day to day development. I’m aware though that not all developers frequently step into the internals of their AS 😉

To conclude; WebLogic 12c is by no means the heavy-weight beast that common knowledge claims it is.

Categories: java, java ee Tags:

JSF2 + Primefaces3 + EJB3 & JPA2 Integration Project

April 15, 2012 14 comments

Software developer Eren Avşaroğulları recently wrote an interesting blog posting about integrating JSF2, PrimeFaces3, Spring3 and Hibernate and a similar version without Spring.

In this blog posting I would like to present a third variant where EJB3 is used instead of Spring. Additionally, in true open source spirit I also present several code changes that hopefully improve the original code a little (some are taken from the comments on Eren’s article). What I did not do is add features or change the structure. This is as much as possible kept the same so the implementations remain comparable.

I’ll adhere to the same steps as the Spring blog uses.

Used Technologies:

JDK 1.6.0_31
Java EE 6 (JBoss AS 7.1.1, or Glassfish 3.1.2, or TomEE, or …)
PrimeFaces 3.1.1
H2 1.3.166

 

STEP 1: CREATE MAVEN PROJECT

Instead of a maven project, I created a dynamic web project in Eclipse:

 

STEP 2: CREATE USER TABLE

Automatically created by JPA (see below)

 

STEP 3: LIBRARIES

Most libraries (JSF, EJB, JPA, Bean Validation, etc) are already part of Java EE 6 and put on the class-path by an Eclipse Java EE 6 Runtime Server (I used the one from JBoss tools). I downloaded PrimeFaces and H2 separately and put it in WEB-INF/lib (for Glassfish, H2 needs to be put in [GLASSFISH_HOME/lib]). If you do use Maven, I guess this would be in pom.xml:

<dependencies>
    <!-- Java EE 6 dependency -->
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>6.0</version>
        <scope>provided</scope>
   </dependency>

    <!-- Primefaces dependency -->
    <dependency>
        <groupId>org.primefaces</groupId>
         <artifactId>primefaces</artifactId>
        <version>3.1.1</version>
    </dependency>
</dependencies>

 

STEP 4: CREATE USER MODEL CLASS

The model is in the core the same as Eren’s original. Following the advice from Clean Code, I removed the comments since they basically said the same thing that the code was already saying. I also removed the @Column annotations, since all the names already exactly corresponded to the target table. The nullable and unique attributes are only used for schema generation, which wasn’t used in the original. For the @Id annotation, nullable and unique is already implied (it’s a PK) and for the other columns an annotation that’s actually processed at run-rime is much more convenient. I choose to use @Size here, which implies not null and at the same time makes specifying this same constraint in the view later on redundant.

For the toString method I made a small improvement using StringBuilder instead of the unnecessarily synchronized StringBuffer and the builder pattern.

package com.example.model;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Size;

/**
 * 
 * This entity represents the human user.
 * 
 * @since 12 Apr 2012
 * @version 1.0.0
 * 
 */
@Entity
public class User {

    private int id;
    private String name;
    private String surname;

    @Id
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Size(min = 5)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Size(min = 5)
    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    @Override
    public String toString() {
        return new StringBuilder()
            .append("id : ").append(getId())
            .append(", name : ").append(getName())
            .append(", surname : ").append(getSurname())
            .toString();
    }
}

 

STEP 5: CREATE USER MANAGED BEAN CLASS

I made some bigger changes here. In Eren’s version there’s a managed bean that backs both the index and success views. I think it’s a better practice to split those up into one bean per page, adhering to the rule that a backing bean should back one page only. The names of the beans were thus changed to reflect the page they’re backing, instead of having some service like name. There’s also no need to explicitly specify the bean’s name in the annotation. There’s a default, which is good enough here.

I also made the beans @ViewScoped, since there’s no need to do any re-creation of data after postbacks (e.g. when validation of user entered data fails) and in case of the list page (success.xhtml) to reload the data from the DB every time the table is sorted or paged (which isn’t used in this example btw).

A more severe issue was that the original code used the scatter/gather anti-pattern. Here, the properties of the user were scattered into properties of the backing bean and upon saving gathered again in the model object. In JSF there is no need for this. A backing bean can directly return the model object and UI components can directly bind to those properties.

Navigation rules were also done away with in favor of implicit navigation. Navigation rules may have their place, but often you’re better off using the simpler implicit navigation, and I think this is one of those cases. I also removed the explicit navigation to a general error page. This can already be handled application wide by Java EE’s error-page mechanism. Therefor I just let the exception propagate. If a specific message would have to be shown on screen via a faces message for specific exceptions from the EJB bean, a try/catch would of course still be the best mechanism.

The smallest, but main point of this entire variant of Eren’s version, is that an EJB bean is injected instead of a Spring bean.

Finally, here too I removed comments that didn’t told us anything that the code wasn’t already telling.

index.xhtml backing:

package com.example.backing;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import com.example.dao.UserDAO;
import com.example.model.User;

/**
 * 
 * This backing bean backs index.xhtml, which allows adding a new User.
 * 
 * @since 12 Apr 2012
 * @version 1.0.0
 * 
 */
@ViewScoped
@ManagedBean
public class IndexBacking {

    private User user = new User();

    @EJB
    private UserDAO userDAO;

    /**
     * Adds a user to persistent storage
     * 
     * @return String - navigation to the success page
     */
    public String addUser() {
        userDAO.add(user);
        return "success?faces-redirect=true";
    }

    /**
     * Resets the user data back to the initial values.
     * 
     */
    public void reset() {
        user = new User();
    }

    public User getUser() {
        return user;
    }

}

success.xhtml backing:

package com.example.backing;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import com.example.dao.UserDAO;
import com.example.model.User;

/**
 * 
 * This backing bean backs success.xhtml, which shows a list of all users.
 * 
 * @since 12 Apr 2012
 * @version 1.0.0
 * 
 */
@ViewScoped
@ManagedBean
public class SuccessBacking {

    private List<User> users;

    @EJB
    private UserDAO userDAO;

    @PostConstruct
    public void init() {
        users = userDAO.getAll();
    }

    public List<User> getUsers() {
        return users;
    }

}

 

STEP 6: CREATE IUserDAO INTERFACE

I took over most of the DAO interface, but made some small changes again.

For starters, I don’t think the interface should mention that it’s an interface, so I removed the I from the name. Continuing with naming, the DAO is already about entity User so I simplified the method names by removing this term from them.

In Eren’s code the methods all had the public access modifier, but for interfaces this is already the default and can thus be safely removed. Finally, there was again comment that said the same as the code was saying, so I removed that too.

package com.example.dao;

import java.util.List;

import com.example.model.User;

/**
 * 
 * Interface for DAOs that know how to perform persistence operations for User entities.
 * 
 * @since 12 Apr 2012
 * @version 1.0.0
 * 
 */
public interface UserDAO {

    void add(User user);

    void update(User user);

    void delete(User user);

    User getById(int id);

    List<User> getAll();
}

 

STEP 7: CREATE UserDAO CLASS

The main meat of this variant of the example application is a DAO implemented with EJB instead of Spring. Since the implementation class uses a specific technology, I named this after the technology. Since both JPA and EJB are used, one possible name could have been EjbJpaUserDAO, but feeling this was a bit over-the-top I settled for JpaUserDAO instead.

With respect to the JPA code being used, I took advantage of typed queries, where the original code used untyped queries with casts and raw collection types. For the getAll query I used a named query in a separate XML file, instead of embedding JPQL inline. To keep the example short, embedding JPQL would certainly be preferable, but I feel JPQL is best at home in its own file.

package com.example.dao.jpa;

import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import com.example.dao.UserDAO;
import com.example.model.User;

@Stateless
public class JpaUserDAO implements UserDAO {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public void add(User user) {
        entityManager.persist(user);
    }

    @Override
    public void update(User user) {
        entityManager.merge(user);
    }

    @Override
    public void delete(User user) {
        entityManager.remove(
            entityManager.contains(user) ? user : entityManager.merge(user)
        );
    }

    @Override
    public User getById(int id) {
        return entityManager.find(User.class, id);
    }

    @Override
    public List<User> getAll() {
        return entityManager.createNamedQuery("User.getAll", User.class)
                            .getResultList();
    }

}

META-INF/jpql/User.xml:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd">
    
    <named-query name="User.getAll">
        <query>
            SELECT
                _user
            FROM
                User _user
        </query>
    </named-query>

</entity-mappings>

 

STEP 8: CREATE IUserService INTERFACE

STEP 9: CREATE UserService CLASS

Here I made the opposite decision as I made for the separate JPQL file and decided to skip the service. As in Eren’s example the service doesn’t add any code and just wraps the DAO, I felt it wasn’t necessary here. Normally having a separate service layer, where services aggregate multiple DAOs and perform additional tasks other than just plain persistence (like e.g. validation) is a good thing of course.

 

STEP 10: CREATE applicationContext.xml

The file applicationContext.xml is a Spring specific artifact and thus doesn’t appear in this Java EE example. Nevertheless, some elements have Java EE equivalents and need to be created as well.

The first three entries in Eren’s applicationContext.xml concern the declaration and injection of Spring beans. In Java EE this is done via annotations and doesn’t need to be declared in an XML file.

We do need a datasource though. In case of JBoss AS, the simplest thing for an example would be to use the default datasource (which points to an internal embedded database), but to stay closer to Erin’s example we’ll define a datasource ourselves. And this brings us to a sore point in Java EE.

In the traditional Java EE philosophy, a datasource is akin to an environment variable. It’s defined completely outside the application and the application only refers to it by name and expects nothing more than the javax.sql.(XA)DataSource interface.

This is all fine and well for decoupling and giving AS implementations the opportunity to introduce fancy optimizations, but it necessarily means a Java EE application has to be packaged with unresolved dependencies. Eventually someone has to resolve those, which means a traditional Java EE application needs to be accompanied by some kind of document intended to be read and interpreted by humans, who will then need to create all those dependencies in the local environment. If a new version of the application is shipped, some kind of document needs to be checked for changes, and someone has to apply those changes to the local environment.

Obviously some people are a big fan of this approach, but it’s not suited for everyone. Recognizing this, Java EE 6 introduced an alternative where the datasource is defined inside an application (just like Spring does). For this an annotation can be used (which might be suited for development/testing), an entry in web.xml (web apps) or an entry in application.xml (EAR apps).

Unfortunately, at the moment this approach hasn’t been fully adopted yet. JBoss for instance is apparently a big fan of the traditional approach and it seems that it has only grudgingly implemented the standard embedded datasource definition. It didn’t really worked at all in JBoss AS 6, and still doesn’t work completely in the latest JBoss AS 7 (it only works when transactions are turned off) and only seems to be recommended for testing and development. It’s also not really clear where the necessary JDBC driver has to be located. The spec is silent about this. As it turns out, Glassfish required the driver to be in glassfish/lib, while JBoss AS 7 allows the driver to be in WEB-INF/lib.

Despite the not entirely optimal situation, I’ll use the standard Java EE 6 datasource definition for this example. For serious production work the reader is advised to look into the implementation specific ways to do the same.

Finally, the Spring applicationContext.xml defines the SessionFactory, which directly corresponds to a Persistence Unit in Java EE. This is defined in META-INF/persistence.xml. Note that schema creation is not standardized in JPA, so it contains properties for both Hibernate, EclipseLink and OpenJPA to autogenerate the SQL schema. If you create the schema yourself, you obviously don’t need those.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    
    <persistence-unit name="example">
        
        <jta-data-source>java:app/MyApp/myDS</jta-data-source>
        
        <mapping-file>META-INF/jpql/User.xml</mapping-file>
        
        <properties>
            <!-- Hibernate -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="create-drop" />
            
            <!-- EclipseLink  -->
            <property name="eclipselink.ddl-generation" value="create-tables" />
            <property name="eclipselink.ddl-generation.output-mode" value="database" />

            <!-- OpenJPA -->
            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
        </properties>
        
    </persistence-unit>
</persistence>

 

STEP 11: CREATE faces-config.xml

In JSF faces-config.xml is optional, and since in Java EE all other elements are by default integrated with it and we didn’t used explicit navigation rules, I could leave it out.

 

STEP 12 : CREATE web.xml

In Java EE, web.xml is optional too if you’re happy with all the defaults. In this case I wanted to set an explicit welcome- and error page, as well remap the FacesServlet from it’s default of .jsf to .xhtml. Furthermore in a web application this is the place where the above discussed datasource definition needs to be placed.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
>

    <display-name>jsf_ejb_jpa</display-name>

    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>
    
    <error-page>
        <error-code>500</error-code>
        <location>/error.xhtml</location>
    </error-page>

    <servlet>
        <description>The JSF Servlet</description>
        <servlet-name>facesServlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>facesServlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

    <!-- Following param only needed for MyFaces (TomEE, etc) -->
    <context-param>
        <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
        <param-value>false</param-value>
    </context-param>
    
    <data-source>
        <name>java:app/MyApp/myDS</name>
        <class-name>org.h2.jdbcx.JdbcDataSource</class-name>
        <url>jdbc:h2:~/mydb;DB_CLOSE_DELAY=-1</url>
        <user>sa</user>
        <password>sa</password>
        <!--For JBoss AS 7.1.1 must be false. 
            For JBoss AS 7.1.2/7.1.3 (EAP 6.0.0/6.0.1) must be true
        -->
        <transactional>false</transactional>
        <max-pool-size>10</max-pool-size>
        <min-pool-size>5</min-pool-size>
        <max-statements>0</max-statements>
    </data-source>

</web-app>

 

STEP 13: CREATE index.xhtml

I made a few small changes here. Instead of the table tag I used the somewhat higher level panelGrid. I also removed the explicit Integer converter, and since the minimal length constraint is already on the model now (and JSF is capable of reading that) the validateLength validator wasn’t needed either.

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
    
    <h:head>
        <title>Welcome to the JSF EJB JPA example project</title>
    </h:head>
    
    <h:body>
        <h:form>
            
            <h:panelGrid columns="3">
                
                <h:outputLabel for="id" value="Id : " />
                <p:inputText id="id" value="#{indexBacking.user.id}">
                    <p:ajax event="blur" update="idMsg" />
                </p:inputText>
                <p:message id="idMsg" for="id" display="icon" />
                
                <h:outputLabel for="name" value="Name : " />
                <p:inputText id="name" value="#{indexBacking.user.name}">
                    <p:ajax event="blur" update="nameMsg" />
                </p:inputText>
                <p:message id="nameMsg" for="name" display="icon" />
                
                <h:outputLabel for="surname" value="Surname : " />
                <p:inputText id="surname" value="#{indexBacking.user.surname}">
                    <p:ajax event="blur" update="surnameMsg" />
                </p:inputText>
                <p:message id="surnameMsg" for="surname" display="icon" />
            
            </h:panelGrid>
            
            <p:commandButton id="addUser" value="Add" action="#{indexBacking.addUser}" ajax="false" />
            <p:commandButton id="reset" value="Reset" action="#{indexBacking.reset}" ajax="false" />
           
        </h:form>
    </h:body>
</html>

 

STEP 14: CREATE success.xhtml

Again a few changes here. For starters h:outputText wasn’t needed (and if it was needed could be collapsed). I placed the EL expression directly on the Facelet. Also, a PrimeFaces column has a headerText attribute, which is less verbose than a Facet, so I used that.

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
    
    <h:head>
        <title>List of all users</title>
    </h:head>
    
    <h:body>
        USERs:
        <h:form>
            <p:dataTable id="users" var="user" value="#{successBacking.users}" style="width: 10%">
                <p:column headerText="ID">
                    #{user.id}
                </p:column>
                
                <p:column headerText="Name">
                    #{user.name}
                </p:column>
                
                <p:column headerText="Surname">
                    #{user.surname}
                </p:column>
            </p:dataTable>
        </h:form>
    </h:body>

</html>

 

STEP 15: CREATE error.xhtml

On Eren’s version of this page a form was placed, but this isn’t needed for simple text output so I removed it. I also removed the h:outputText tag again and changed the text shown, since it’s really about any error and not just about transaction errors.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html">

    <h:head>
        <title>Application error</title>
    </h:head>
    
    <h:body>
        Error has occurred!
    </h:body>

</html>

 

STEP 16 : DEPLOY PROJECT

After the JSF_EJB_JPA project is deployed to a Java EE 6 implementation (JBoss AS, Glassfish, etc), the index page can be opened via the following URL: http://localhost:8080/jsf_ejb_jpa

That’s it! Thanks again to Eren AvÅŸaroÄŸulları for his inspiring series of articles and I hope my contribution is useful to someone.

Reply to Comparing Java Web Frameworks

October 12, 2011 10 comments

Last week Shaun Abram wrote an interesting blog about the talk Rickard Pack gave on JavaOne titled “Choosing Your Java Web Framework”

It basically said Grails, Tapestry, Wicket and GWT were 4 of the most popular web frameworks. JSF was left out because Richard didn’t have a very high opinion of it. Shaun mentioned Peter Thomas and Bruno Borgers agreed with that.

I initially posted a reply on Shaun’s blog, but because it became a bit longer than intended and didn’t seem to come through correctly, I’ll repost it on my blog here.

There are a few remarks I would like to make about Shaun’s post and Richard’s presentation. First of all, on what statistic is it based that Tapestry is among the 4 most popular web frameworks?

If you look at the poll held by zeroturnaround in 2011 year, Tapestry ends last:


(source: Java EE Productivity Report 2011)

Another zeroturnaround poll in 2011 held specifically for developers in India shows the same thing:


(source: Java Productivity Report 2011: India vs Rest of World)

In 2012, the zeroturnaround poll wasn’t that different, and again Tapestry ends last:

  • Spring MVC (30%)
  • JSF (23%)
  • Struts (17%)
  • GWT (14%)
  • Play! (8%)
  • Wicket (7%)
  • Grails (7%)
  • Vaadin (7%)
  • Stripes (2%)
  • Tapestry (2%)

Participants: 1100+
(source: Java EE Productivity Report 2012)

And in 2014, the zeroturnaround poll didn’t even list Tapestry directly anymore:

  • Spring MVC (40%)
  • JSF (21%)
  • Vaadin (16%)
  • GWT (10%)
  • Grails (7%)
  • Play 2 (6.5%)
  • Struts 2 (6%)
  • Struts 1 (4.5%)
  • Other (Wicket, Seam, Tapestry, Play 1, ZK, VRaptor, 40 others) (18.5%)

Participants: 2164
(source: Java Tools and Technologies Landscape for 2014)

If you take a look at the poll recently held by the German JAXenter, then Tapestry is at number 13, with again only a meager 1% of the votes:

Welches ist Ihr präferiertes Webframework?

    • Vaadin (18%)
    • JSF (16%)
    • Grails (15%)
    • Play! (10%)
    • Wicket (8%)
    • ZK (7%)
    • Spring MVC (6%)
    • GWT (5%)
    • Ruby on Rails (3%)
    • Lift (2%)
    • JAX-RS (Jersey) (2%)
    • Struts (1%)
    • Tapestry (1%)
    • Flex (1%)
    • Stripes (1%)
    • Spring Roo (0%)
    • Roma (0%)
    • JavaFX (0%)
    • Click (0%)
    • Anderes (4%)

Teilnehmer: 1463
(source: Und das populärste Webframework ist…)

In a survey by OIO, published in April 2012, Tapestry is not even present. JSF is the clear winner there, with second place Spring MVC a good deal behind:

Employed Web Framework
(source: OIO Compass: Java web frameworks)

Via a rather informal (to say the least) survey hold on Devoxx ’12, about the preferred way to build the UI of a business app with, nobody even bothered to mention Tapestry:

  • JavaScript/HTML 5 (43)
  • Vaadin (22)
  • JSF (17)
  • JSP/SpringMVC/Struts (17)
  • GWT (17)
  • JavaFX (11)
  • Wicket (10)
  • Swing (8)
  • RCP (7)
  • Angular (6)
  • ZK (5)
  • Grails (4)
  • OmniFaces (3)
  • Play! (3)
  • DART (2)
  • Flex (2)
  • Java Applet (1)
  • AWT (1)
  • India (1)
  • REST + JS (1)
  • SAP v15 (1)

(source: Devoxx ’12 whiteboard)

And just compare the jobs offered for e.g. JSF vs Tapestry:

In absolute numbers JSF dwarfs Tapestry. Now many smaller frameworks can claim some popularity based on relative growth (since it’s often easier to go from 1 to 2 jobs, than from 100000 to 200000), but even there Tapestry shows no growth and is dwarfed by JSF:

Relatively Tapestry is completely obliterated by GWT:

On StackOverflow JSF is also clearly much more popular than Tapestry:

stackoverflow_webframeworks
(source: Stack Overflow tag trends)

According to the above graph, on StackOverflow JSF, Grails and GWT are the biggest ones, while Tapestry is one of the smallest. JSF in particular is even more popular on StackOverflow than the above graph suggest, since a lot of questions use the “JSF-2” tag instead of “JSF” and tags at StackOverflow are not hierarchical. JSF + JSF-2 is much bigger than just JSF.

When looking at just JSF and Tapestry, the difference becomes even more clear:

stackoverflow_jsf_tapestry

(source: Stack Overflow tag trends)

If I play with the numbers using various other sources (forums, amazon books, postings on dzone, etc etc) they all show the same thing: Tapestry does not seem to be very popular.

So again, I wonder why Richard came to the conclusion that Tapestry is among the top 4? I personally don’t think Tapestry is bad or anything, but I just don’t see it being so popular.

Then specifically about JSF, citing Peter Thomas and Bruno Borges about not liking JSF is questionable at best. Both these two are very much hardcore Wicket evangelists, who seem to have a hard time accepting JSF is apparently more popular than their favorite Wicket. Look at Bruno’s comments on the outcome of the zeroturnaround poll where JSF scored high, and where he tries to downplay the outcome by using the “JSF is not a free choice” card (but the other polls and the amount of open source projects based on JSF prove this is nonsense).

A lot of anti-JSF feelings are based on the older 1.x series (especially 1.0 and 1.1), which indeed wasn’t so good. But from 2.0 onwards, JSF is really a very good web framework and it’s hard to find a lot of concrete faults with it.

For instance, JAXEnter did a direct and in-depth comparison between Wicket and JSF 2.0 and there is no mention at all of the supposed facts that Wicket is so much superior to JSF and that JSF has so many faults. Instead, the article explains both frameworks have strong points and neither is fundamentally ‘bad’.

If you look at the blog of Peter Thomas, all the things he cites are for JSF 1.x. Among his latest additions are that the JSF EG had disbanded after 2.0 with no people to continue it (obviously nonsense, since 2.1 has been released since and 2.2 is in progress, see What’s new in JSF 2.2?), and that James Gosling said he hated JSF (this was nonsense; it’s well known he meant to say JSP).

Shaun mentioned the following in his blog:

[I] have heard enough negative comments on JSF to not want to touch it.

I think Shaun should really give the latest JSF 2.1 release a try. It’s absolutely really good and a completely different experience compared to the old 1.x releases. See  Minimal 3-tier Java EE app, without any XML config for a very simple introduction and JSF 2.0 tutorial with Eclipse and Glassfish  plus Communication in JSF 2.0 for a more elaborate introduction.

JSF being the standard from Java EE and Oracle just naturally attracts more negative comments since it’s well, just popular to bash all things Oracle (and before Sun). I’ve seen people screaming how bad EJB is without ever once having tried it 😦 Anyway, there are also plenty of negative comments about the other web frameworks (note that I don’t necessarily agree with all of them). E.g.

Play:
Play! Framework Un-features That Really Irk My Inner Geek
Why I’m Moving Away from the Play Framework
Play Framework 2.1: The Bloom is Off The Rose

GWT:
Why Google Web Toolkit Rots Your Brain
Google Web Toolkit Follow-up
I hate GWT
When not to use Google Web Toolkit?
Why I give up using SmartGWT (not GWT itself, but popular extension)
Addressing Misconceptions about Google Web Toolkit
GWT – Common Problems with Solutions
Extra comment for the above link
GWT is cool, but not complete
The disadvantages of the Google Web Toolkit

Tapestry:
Tapestry 5, and how not to treat HTML
tapestry sucks

Wicket:
What I hate about Wicket Framework
Apache Wicket
GWT critics

Categories: java Tags: , , , , , ,