Showing posts with label Weld. Show all posts
Showing posts with label Weld. Show all posts

18 July 2012

OSGi and CDI Combined

Pax CDI is a new OPS4J community project I've started to combine the best of OSGi and CDI.

Once you've worked with CDI or with an up-to-date annotation-based flavour of Spring, the service registry API or XML-based dependency injection in the Blueprint or Declarative Services style suddenly appears rather verbose.

On the other hand, even though Java EE 6 is more lightweight than ever, its monolithic nature feels rather a burden when you're used to OSGi.

Why not have the best of both worlds? The idea is not new, it has been implemented to some extent both in weld-osgi and in the FighterFish subproject of GlassFish.

Unlike these two projects, Pax CDI is independent of any given CDI, Java EE or OSGi implementation. The first proof-of-concept release is based on Apache OpenWebBeans and Equinox. In contrast to weld-osgi, which required some modifications in Weld itself, Pax CDI works with an unmodified version of OpenWebBeans.

Trying to do the same with Weld is one of the next goals for Pax CDI.

An alpha release Pax CDI 0.1.0 is available from Maven Central.

24 May 2012

OSGi, Java EE and CDI Integration Testing with Pax Exam 3

In-container testing is an approach shared by many testing frameworks like Pax Exam, jeeunit, Arquillian and Spring's test context.

Pax Exam 2.x is a mature solution for testing OSGi bundles and applications, jeeunit was created to simplify Java EE 6 integration testing and has been extended to handle stand-alone CDI applications and non-CDI setups based on Tomcat and Spring.

Taking the best of both worlds, the next major release line Pax Exam 3.x is designed to provide a unified testing experience by incorporating additional test containers for Java EE and CDI from jeeunit while staying backward compatible with Pax Exam 2.x for OSGi.

The first public milestone release Pax Exam 3.0.0.M1 is now available from The Central Repository (aka Maven Central), including test containers for GlassFish, OpenWebBeans and Weld.

While jeeunit works with Embedded GlassFish which lacks all OSGi capabilities of the GlassFish server, the Pax Exam GlassFish Container launches GlassFish 3.1.2 on top of an OSGi framework, enabling users to deploy or provision both WAR modules and OSGi bundles, thus providing a test environment for hybrid Java EE/OSGi applications.

A plain old JUnit test class can be turned into an in-container integration test simply by adding a @RunWith(PaxExam.class) annoation and some configuration data in a properties file.

See the Pax Exam 3.0.0.M1 Release Notes for more details and use the OPS4J mailing list (general@lists.ops4j.org) for feedback and support.

25 January 2012

Integration Testing for JBoss AS7, Tomcat and Weld SE

Initially, the jeeunit Integration Testing framework was exclusively focused on Java EE 6, supporting GlassFish 3.x, which was the only Java EE 6 compliant server at that time. Support for Resin 4.x has been added in subsequent releases.

With the current release 0.9.1, jeeunit supports JBoss AS 7, as well as alternative containers and injection methods beyond the scope of Java EE 6. You can now run jeeunit tests on Tomcat 6 and 7 and Weld SE containers.

Tomcat can be combined either with Spring 3.1 or with CDI (Weld Servlet) to inject dependencies into jeeunit tests.

And there's more to come: While jeeunit will continue a life of its own for a while, I'm planning to merge it step by step into Pax Exam, the OSGi testing framework of the OPS4J community.

Pax Exam and jeeunit both implement an in-container testing approach - while Pax Exam focuses on OSGi alone, jeeunit now supports various other containers, but no OSGi at all.

The Pax Exam/jeeunit merger opens interesting perspectives for hybrid applications, i.e. enterprise applications composed of traditional WARs and OSGi bundles. GlassFish 3.x supports this hybrid application model, implementing a subset of the OSGi Enterprise specifications.

For Pax Exam, the road towards the next major release 3.0.0 will be marked by a sequence of milestone releases, each of which is to incoporate a new container adapted from jeeunit.

A Pax Exam GlassFish Test Container is the goal of the first proof-of-concept milestone 3.0.0.M1. This is work in progress on a dedicated branch exam3-milestones in the Pax Exam GitHub repository.

Stay tuned...

07 June 2011

Java EE 6 Server Comparison: Glassfish

In April 2010, I started a Java EE 6 project, and Glassfish 3.0 was the obvious server choice, or rather, the only option at that time. For the next couple of months, I spent a considerable amount of time not working on my application, but analyzing, reporting and working around bugs in the server, mainly in the CDI and JPA areas. This appeared to be the price you had pay for being an early adopter of the new Java Enterprise standard.

18 December 2010

An Update on Memory Issues in Glassfish and Weld

Using the most recent Glassfish milestone build 3.1-b33, I took another look at the memory issues that had plagued my project on Glassfish 3.0.1. The last build I tried was b30, which did not even let me deploy my application.

Just in time for Christmas, there are Good Tidings - Weld has improved a lot, and I can no longer see any suspicious memory usage related to Weld. I took my Wicket+EJB+OpenJPA+PostgreSQL application packaged in a single WAR and deployed it to several different Glassfish versions from the command line. Then I used the Eclipse Memory Analyzer to a create a heap dump of the running Glassfish instance.

The Total Heap column in the following table is the total size of the heap as reported by the Memory Analyzer. The Shallow, Retained, and Percentage Columns refer to the amount of heap memory consumed by instances of org.jboss.weld.introspector.weld.jlr.WeldClassImpl

Glassfish Version Total Heap Shallow Retained Percentage
3.0.1 412.1 MB 84.680 378.215.056 87.52 %
3.1-b26 335.3 MB 85.144 205.527.048 58.38 %
3.1-b33 149.6 MB 84.216 7.041.704 4.49 %

The retained heap of an object is the set of objects that will be garbage collected when the given parent object is garbage collected.

So in b33, Weld still holds 5 % of the total heap - whether or not this is still too much or just reasonable is surely debatable. But I'm really happy to see that Weld has improved a lot, so I would no longer consider it as a no-go.

The version of my application I used for these measurements is the last one that actually used Weld, before I decided in August to stop using CDI to get rid of most memory issues.

I took some more measurements with the successor version in which CDI was eliminated essentially just by replacing @Inject by @EJB throughout the sources. This is really the only difference between the two versions, and here are the total heap sizes:

Glassfish Version with @Inject with @EJB
3.0.1 412.1 MB 44.4 MB
3.1-b33 149.6 MB 138.3 MB

The illustrates, as claimed in my previous post, that I was able to save 90 % of heap memory by not using CDI on Glassfish 3.0.1. Doing the same on Glassfish 3.1-b33, I can still save about 9 %.

But I was really surprised to see the heap usage of my application increase by a factor of 3 between Glassfish 3.0.1 and 3.1-b33.

The Memory Analyzer reveals the culprit to be org.glassfish.hk2.classmodel.reflect.impl.TypesCtr with a retained heap of about 80 MB.

I have no clue what this class is doing, but it smells like another case of an oversized reflective model of the application, which was just the problem with earlier Weld versions.

GLASSFISH-15266 is the related issue in Glassfish JIRA.

01 December 2010

Glassfish and Weld: New builds, new bugs

My article about memory issues with CDI/Weld seems to have caused rather a wave. Someone (not me) posted a link on DZone, which triggered an unprecedented amount of traffic on this blog, there were discussions both in the Glassfish and Weld communities, and I was very happy to see that Weld appears to have made significant progress in terms of resource usage.

So the good news is: First, things are moving in the right direction with Weld, and second, blogging helps - at least in this case, it seems to have been a lot more effective than my previous bug reports and forum messages.

Unfortunately, there is also some bad news. Several users have already reported regressions with Glassfish 3.1-b29 and b30 related to Weld. My application fails to deploy on b30 with a stack trace which looks like a case of GLASSFISH-13131. So I'd better wait and try again with Glassfish 3.1 milestone 8.

04 November 2010

CDI - A Major Risk Factor in Java EE 6

Update 18 Dec 2010: This post mainly relates to Glassfish 3.0.1. As of 3.1-b33, the situation has improved a lot.

Evaluating platforms and architectures for a new enterprise web application earlier this year, around March/April, scheduled to be released in 2011, I was bold enough to settle on Java EE 6.

In retrospective, I do not regret this decision, but I had to spend a significant amount of time analyzing and debugging platform problems. Based on this experience with Java EE 6, which may not be representative of course, the only advice I can give is: When Java EE 7 is released, wait a year or two before using it for production, unless you have the time and resources to act as beta tester.

The Java EE 6 specifications were released in December 2009, together with Glassfish v3, the first "production-quality release" of a Java EE 6 server. "Marketing release" would have been more appropriate, since going by the number of bugs in Glassfish 3.0, the main driving factor for the release date was quite obviously not a quality benchmark, but simply the need for Sun as the Java EE champion to release a working server simultaneously with the specifications.

The Problem


Java EE 6 was advertised as the lightest Java Enterprise Edition ever, with Contexts and Dependency Injection (CDI, JSR-299) as one of the most prominent innovations. However, for my project, CDI in the guise of Weld, its reference implementation, turned out to be the largest single source of problems. In addition to a number of functional bugs where injection would not work in certain scenarios, there are at least two severe memory issues:
  1. Weld causes memory leaks on application redeployment.
  2. Even in the first deployment of an application, Weld uses enormous amounts of memory.
The first issue had plagued us for months, and my team had grown accustomed to kill all Glassfish and Eclipse processes after three or four redeployments and to re-initialize their entire workspace, which was rather a pain.
Investigating the memory leaks using the Eclipse Memory Analyzer, I realized that Weld claimed almost 90 % of the heap memory of my application. Most of this was due to instances of org.jboss.weld.introspector.weld.jlr.WeldClassImpl, which appears to be a reflective model of a class inspected by the CDI BeanManager. Some instances of this class were as large as 1 MB.

I should add that our application uses Wicket for the web front end, injecting EJBs into custom Wicket components. Custom components inherit from Wicket base classes with a fairly deep inheritance hierarchy and a large number of methods. This accounts for the size of the reflective models.

Our usage of CDI was fairly basic, so it was just an hour's work to replace all @Inject annotations by Java EE 5 style @EJB annotations. After that, the heap usage of our application was reduced by 90 %, we no longer had any memory leaks, and we finally had a hassle-free edit-save-debug cycle in our development environment.

The figure of 90 % heap usage by Weld was observed on Glassfish 3.0.1, running on a 32-bit JVM on Windows XP.

This week, I retested the same application with Glassfish 3.1-b26 (using a newer version of Weld), running on a 64-bit JVM on Ubuntu 10.04. The result was not as drastic as before, but still about 50 % of my heap memory was consumed by Weld.

Alternatives


This article is mainly about problems with the CDI reference implementation Weld, not about CDI as such. But these implementation details have a ripple effect:
  • Glassfish 3.x still is the only certified Open Source Java EE 6 server. It uses a newer version of Weld in the current 3.1 promoted builds, but I can see no indication of the Weld issues being solved in time for the 3.1 release.
  • JBoss AS 6 is likely to be the next in line for full Java EE 6 compliance. However, JBoss also includes Weld, so you're bound to run into the same kind of problems on JBoss.
  • There are alternative CDI implementations, CanDI from Caucho and OpenWebBeans from Apache. Unfortunately, unlike JPA, there is no pluggable CDI provider interface that would allow you to simply replace Weld by some other CDI implementation on Glassfish or any other server.
  • I tried running my application on Resin 4.0.8 to see if CanDI was any better than Weld. However, Resin had bugs in the JPA and EJB areas and I was unable to deploy my application, let alone run and monitor it. (Resin only aims at supporting the Java EE 6 Web Profile, but that would have been sufficient for my case.)

Conclusion


All in all, if you want to work with Java EE 6, there is currently no way around Weld. And until Weld reaches production quality, the only way to build production quality applications on Java EE 6 is to avoid using CDI.

Free and Open Source Software is all about choice - so I would really love to see a pluggable CDI provider interface that would allow users to work with Glassfish and some CDI implementation other than Weld.

The second best solution might be to join forces from different CDI project to make Weld stable enough for production usage.

The third option would be another fully Java EE 6 compliant Open Source server (maybe Geronimo?) not including Weld.

No idea if any of these options is realistic, but this is on my wishlist for 2011.