Showing posts with label Glassfish. Show all posts
Showing posts with label Glassfish. Show all posts

05 November 2013

No More Commercial Support for GlassFish - So What?

"GlassFish reduced to toy product" and "R.I.P. GlassFish" are some of the headlines regarding Oracle's announcement to withdraw commercial support for the application server acting as Java EE reference implementation.

Oh well, I've stopped using GlassFish 3.x on a regular basis about a year ago when it became apparent that GlassFish 3.1.2.2 was a dead end for the Java EE 6 Open Source product (see comments of the linked blog post), and I've never really started using GlassFish 4.0 except for quick demos, knowing the release policy would be just the same as for 2.x and 3.x, where the Open Source release was more of a public beta for the closed-source commercial product.

It's nice to know you can get commercial support for a server if you need it and if somebody is willing to pay for it. On the other hand, lots of companies run successful businesses with applications built on Open Source web containers or application servers without any commercial support, because commercial support is not affordable in their business models. Moreover, commercial support is not a guarantee for getting a hot-fix when you need it, if the vendor's priorities happen to differ from your own.

Like many others, I've turned from GlassFish to JBoss AS/WildFly (after evaluating and dismissing TomEE for lack of stability and documentation). JBoss AS 7 has surpassed GlassFish in terms of usability and reliability, and it's just a shame that RedHat has now converted JBoss AS to a Not-So-Open Source project, hiding branches and tags in a private repository and no longer publishing Community binaries. But that's another story...

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...

23 October 2011

JBoss AS 7: Catching up with Java EE 6



In my Java EE 6 server comparison of June 2011, JBoss AS 6.0.0 was not exactly the shining star, both in terms of performance and usability.

The next major release JBoss AS 7, claiming to be lightning fast, was published in July 2011, followed by two maintenance updates in August and September.

Time to take another look at JBoss and check if it now compares more favourably to other servers.

07 June 2011

Java EE 6 Server Comparison: Conclusion

Lessons Learned


Portability is not just a Java EE marketing promise. My application now runs on three different Java EE 6 servers, using the same WAR file, without any compile-time configuration.

An application is not portable until it has been ported. Of course, this is true for any specification with different implementations, not just for Java EE. Each of the three servers helped me discovering incorrect API usage in my application that just happened to work on another server.

Certification is not reliable. My application hit at least one major specification violation in each of the three Java EE 6 certified servers. Thus, the test coverage in the Java EE TCKs must be insufficient.

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.

Java EE 6 Server Comparison: Introduction

A year and a half after the Java EE 6 specification release, there are now three Open Source servers certified for the Java EE 6 Web Profile:
  • Glassfish 3.x
  • JBoss 6.x
  • Resin 4.0.x
Time to take a look at these three servers in direct comparison and do some experiments, not with a toy or benchmark application developed for this purpose, but with a real-life enterprise application.

06 June 2011

Java EE 6 Integration Testing on Resin and Glassfish

jeeunit, my Java EE 6 Integration Testing project, now supports Caucho Resin 4.0.18 in addition to Glassfish 3.1.

Another new feature is a @Transactional annotation which can be used to wrap test methods in an auto-rollback transaction.

The current release jeeunit 0.8.0 is available from Maven Central and from the jeeunit Project Page on Google Code.

01 June 2011

Using CDI from Spring

Spring and Java EE are converging in many areas, mainly due to CDI. In fact, by confining yourself to a suitable subset of annotations and other configuration mechanisms, you can design your persistence and service layers to run either on Java EE 6 or on Spring 3, simply by selecting the appropriate set of libraries.

The web layer is a different story: if your web framework is tightly coupled to either Java EE 6 or Spring, it will be hard or even impossible to simply change the container, but even in the web layer, there are solutions like Apache Wicket which work well both with Spring and Java EE, all you need is some glue code to access the dependency injection container.

I'm currently migrating a web application from Tomcat/Spring to Glassfish, and since this application is based on Spring MVC, I cannot completely replace Spring in this step. The goal of the migration is to drop all Spring dependencies from all components except the web frontend and to somehow make the service beans (stateless session beans and CDI managed beans) visible to the Spring web application context.

13 March 2011

Transparent Asynchronous Remoting via JMS

The Scenario


A client needs to invoke a service interface with the following restrictions:
  • The service implementation is running on a remote machine.
  • This fact is transparent to the client, i.e. any service method invocation is just like a local method invocation.
  • The service methods are executed asychronously on the server, method invocations on the client return immediately (fire-and-forget).
  • All service methods have void return types.
  • The service invocations shall be transported via JMS.

18 January 2011

reFit: Acceptance Testing for Java EE 6, Spring and OSGi

Even if you don't practice test-driven development, you are certainly familiar with the JUnit family of testing frameworks (including ports to other languages like cppunit, NUnit, or independent but similar approaches like TestNG).

This post is about the Fit framework family, which has a somewhat different focus and is not just another JUnit clone. In a nutshell, Fit represents expected and actual test results in tables, and you do not have to be a programmer to read or write them.

The following table has one column of inputs and two columns of outputs:

Each row of this table can be regarded as an acceptance test case. You can feed this table to a given system and compare the outputs:

It's only a couple of weeks ago I was introduced to Fit in my current project, and I must admit my first thought was "Why don't you just write a @Parameterized JUnit test?"

The answer is, JUnit is for developers, and developers only; Fit is for customers and developers.

You still need a developer to implement the skeleton logic of a test (called fixture in Fit), but anyone can write new test cases by adding rows or columns to a given Fit table.

The Fit method and the original Java implementation were created by Ward Cunningham in or around 2002, the project is hosted on Sourceforge and has been inactive since 2008.

The Fitnesse project integrates Fit with a Wiki, it includes a modified version of the original Fit implementation and is under active development. However, Fit and Fitnesse are incompatible, Fit lets you write your test tables in plain old HTML, whereas Fitnesse supports its own Wiki syntax only.

Our project has a fair amount of plain old HTML Fit tests, and our production code uses Spring, so it was a fairly natural idea to inject Spring beans from the system under test into our Fit test code.

Spring is just one (and not really my favourite) framework for dependency injection (and lots of others things). so I inevitably started thinking about how to use Fit together with Java EE or OSGi.

Thinking was followed by coding (yeah, it can be the other way round sometimes...), and this led to a project called reFit hosted on Google Code.

reFit is based on the latest Fit sources from SourceForge, it provides up-to-date Maven artifacts on Maven Central and integrations with Java EE 6, Spring and OSGi Declarative Services. The Java EE integration reuses parts of my jeeunit project.

In addition, reFit lets you run Fit tests under a JUnit wrapper or from a Maven plugin, both with or without Spring integration. reFit includes ready-to-run example code for Glassfish 3.1, Spring 3, Equinox and Weld SE.

There's more to come, I'm currently experimenting with a Web frontend and a WYSIWYG HTML editor.

For more details, check out the reFit Wiki.

28 December 2010

Java EE 6 Integration Testing Easier Than Ever

With jeeunit 0.6.0, you can write and run JUnit integration tests for Java EE 6 components as easy as this:

@RunWith(JeeunitRunner.class)
class MySessionBeanTest {
    
    @Inject
    private MySessionBean mySessionBean;

    @Test
    public void aSimpleTest() {
        boolean result = mySessionBean.doSomething();
        assertTrue(result);
    }
}

The JeeunitRunner builds a WAR on the fly, launches an embedded container, deploys the WAR and delegates all test methods to a proxy runner within the container.

With this approach, you can run your test class (or even a package with multiple test classes) from Eclipse via the context menu. The container is only launched once for all classes.

jeeunit currently supports Glassfish 3.1-b33 or higher. It uses the new Embedded Glassfish API introduced in b33.

Compared to earlier jeeunit versions, it is no longer required to build a test WAR manually or to provide a test suite for running multiple test classes.

Thanks to the excellent service provided by Sonatype OSS Repository Hosting, jeeunit is now available from Maven Central.

18 December 2010

Glassfish Logging with slf4j (Part 2)

My previous post on the same subject is one of the most popular articles in this blog, and since Glassfish still does not officially support slf4j, this update may be helpful to anyone hitting my blog via Google trying to improve their logging experience with Glassfish.

To redirect (almost) all log messages from Glassfish and your applications to the same log file and/or console, follow this recipe:
  • Copy these JARs to [install-root]/lib/endorsed:
    • jul-to-slf4j.jar
    • slf4j-api.jar
    • logback-classic.jar
    • logback-core.jar
  • Build a JAR containing your logback.xml configuration at root level and put it in the same place. [Update 26 Jul 2011: Actually, this is no longer required: Simply create a logback configuration file somewhere in your local file system and add the system property -Dlogback.configurationFile=file:/path/to/my/logback.xml to your Glassfish configuration.]
  • Define a new system property in the jvm-options section of your domain.xml:
    -Djava.util.logging.config.file=${com.sun.aas.instanceRoot}/config/my_logging.properties
  • Create the corresponding file my_logging.properties with the following contents:
  • handlers = org.slf4j.bridge.SLF4JBridgeHandler
    com.sun.enterprise.server.logging.GFFileHandler.flushFrequency=1
    com.sun.enterprise.server.logging.GFFileHandler.file=${com.sun.aas.instanceRoot}/logs/server.log
    com.sun.enterprise.server.logging.GFFileHandler.rotationTimelimitInMinutes=0
    com.sun.enterprise.server.logging.GFFileHandler.logtoConsole=false
    com.sun.enterprise.server.logging.GFFileHandler.rotationLimitInBytes=2000000
    com.sun.enterprise.server.logging.GFFileHandler.alarms=false
    com.sun.enterprise.server.logging.GFFileHandler.formatter=com.sun.enterprise.server.logging.UniformLogFormatter
    com.sun.enterprise.server.logging.GFFileHandler.retainErrorsStasticsForHours=0
    
When you restart Glassfish, you should only see two log messages in the old java.util.logging format, all the rest goes via slf4j and logback to the appenders configured in your logback.xml. The two remaining log messages are issued before Glassfish reads the domain.xml configuration with the adapted configuration, so there is no easy way of avoiding them.

I have been using this approach on various Glassfish versions from 3.0.1 to 3.1-b33. It is rather ugly, but nonetheless effective.

All this may sound rather mysterious, so I'd better add some explanations:

jul-to-slf4j.jar is a bridge for redirecting java.util.logging via the slf4j API to any logging backend of your choice (logback in this case). To make the redirection work, the bridge has to be visible to the classloader evaluating the logging configuration. Since Glassfish starts logging very early in its bootstrapping phase, the lib/endorsed folder is the only place where the bridge has the desired effect.

Unfortunately, class file folders seem to be unsupported for endorsed libraries. Of course, it would be easier to simply put the logback.xml file in lib/endorsed/classes where you can directly edit it. But for a quick change to your logging configuration, you can always use an editor which supports editing ZIP/JAR file contents in place.

I created the contents of my_logging.properties by trial and error, starting with a one-liner containing only the handler. This caused a couple of exceptions as Glassfish seemed to be missing the GFFileHandler settings, so I copied them over from the original logging.properties.

The same procedure should also work for other slf4j backends, so you could replace the logback JARs by a log4j.jar.

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.

27 July 2010

A Fish in the Clouds

How long does it take to find a hosting company and get an enterprise web application up and running from scratch? Could be weeks if there are enough lawyers and pointy-haired bosses involved. And even if you can directly talk to the providers, it usually takes a couple of days to request quotes and compare them.

That's the way we started for our current project, but now we've decided to have a go at cloud computing. (So at last this adds another buzzword to my CV...)

I vaguely remembered Arun Gupta's blog about Glassfish on Amazon EC2, and using that together with the Ubuntu EC2 Starter's Guide, it just took me about half an hour to set up a virtual machine in the Amazon Cloud with Ubuntu Server 10.04, JDK 1.6.0_20 and Glassfish 3.0.1, start the Glassfish domain and access the admin console from my local web browser.

And downloading the 78 M Glassfish zip file on the EC2 instance from Oracle's server took less than 2 seconds...

Not bad for a start. I would have expected to spend about a day to get as far as that.

I was also using Ubuntu 10.04 on my local machine, working with the command line interface from the
ec2-api-tools Ubuntu package most of the time.

Of course it will take some more time to set up the database server, deploy our web app and to secure the system. And it's too early to tell if we really require all the elasticity of EC2, which is likely to be more expensive in the long run than a conventional dedicated server cluster.

At any rate, installing a site in virtually no time and running it for less than 10 cents per hour is rather impressive. Thumbs up for Amazon Web Services!

26 July 2010

Building a Java EE 6 Web Application with Eclipse Helios, Maven and Glassfish

This is a short tutorial showing how to use Eclipse 3.6 (Helios) with Glassfish and Maven for building and running a Java EE 6 web application from a multi-module source tree.

We are going to import and run the Wicket gmap2-examples, demonstrating the use of Google Maps via Apache Wicket, but this is purely incidental - even if you prefer mainstream JSF or another web framework to Wicket, you may find this tutorial useful. There are absolutely no Wicket specifics involved; gmap2 was just a handy small but non-trivial example.

If you haven't worked with Maven before, you will get an idea how Maven can save you a lot of work managing the third-party dependencies of your project automatically.

This is what you'll see in the end:


There's quite a few things on your shopping list before you can start. If you are reading this, you probably already have the following on your disk:
You'll need to install these features into Eclipse:
  • Maven Integration for Eclipse (also known as m2eclipse)
  • Maven Integration for Eclipse (Extras)
  • Glassfish Java EE Application Server Plugin for Eclipse
Eclipse 3.6 has a new way of installing plugins via Help | Eclipse Marketplace. This is an integrated web client which lets you search for plugins by free text, so you no longer have to copy and paste update site URLs into the Update Manager - but you can still do so if you prefer.

The m2eclipse book has step-by-step instructions and screenshots explaining the installation process: start here with the m2eclipse installation. When you get to the Extras, the only ones required for the rest of this tutorial are Maven Integration for WTP and Maven SCM Integration. The WTP integration will let Eclipse recognize your Maven projects with war packaging as Dynamic Web Projects.

The Maven SCM Integration lets you fetch Maven projects directly from source code repositories like Subversion, Mercurial or others. Note that this integration simply invokes the corresponding command line clients like /usr/bin/svn.

Having installed m2clipse via the Eclipse Marketplace, use the same procedure to install the Glassfish Plugin.

After restarting Eclipse, set your Glassfish preferences via Window | Preferences | Glassfish Preferences. For this tutorial, you should check Start the Glassfish Enterprise Server in verbose mode and uncheck the other items.

Next, define a server runtime environment via Window | Preferences | Server | Runtime Environment | Add... Select the server type Glassfish | Glassfish Server Open Source Edition 3 (Java EE 6), check Create a new local server and click Next. Select your Glassfish installation directory - this is required to be the parent of the modules and domains directories, e.g. /home/hwellmann/glassfish-3.0.1/glassfishv3/glassfish. Click Next and fill in the domain name and the administrator credentials. If you did not change the Glassfish defaults, you can probably just click on Finish.

The Servers view has opened automatically. You can select your server and click on the Run button to  launch Glassfish from Eclipse. The Eclipse plugin launches Glassfish indirectly via an asadmin subprocess.

You will see some Glassfish log messages in the console. To stop Glassfish, do not hit the stop button in the Console view. This will just kill the asadmin process, but not Glassfish itself, and Eclipse and Glassfish will get terribly out of sync. Make sure to select the Servers view and hit the stop button there to avoid trouble.

Now for the interesting part: Let us import and build the gmap2 example project.

This project has a parent project with two subprojects, or modules in Maven terms. Maven requires you to store the module subprojects of a parent project in subdirectories of the parent directory. Eclipse normally cannot handle overlapping or nested directory structures for projects in the same workspace. Fortunately, m2eclipse works some magic to flatten the project structure, making Eclipse happy.

To import the example sources directly from the Subversion repository, select File | Import... | Maven | Check out Maven Projects from SCM and click Next. Fill in the SCM URL

https://wicket-stuff.svn.sourceforge.net/svnroot/wicket-stuff/tags/wicketstuff-core-1.4.9.2/gmap2-parent

and select the SCM provider svn, then click Next and Finish.

After a while, you will see three projects in your workspace:
  • gmap2
  • gmap2-examples
  • gmap2-parent

The parent project gmap2-parent has two subfolders gmap2 and gmap2-examples which are also represented as top-level Eclipse projects - this is a special feature of the m2eclipse integration.

The gmap2-examples subproject is a web application, as indicated by the Maven packaging type war. Using this and other information specified in the Maven POM, m2eclipse was able to turn this Eclipse project into a Dynamic Web Modules project - have a look at the Project Facets in the project properties to convince yourself.

Opening the project, you will notice two classpath containers Maven Dependencies and Web App Libraries. The latter contains just one item gmap2 with an open folder icon, indicating a reference to another subproject in our workspace that will go into WEB-INF/lib. The Maven Dependencies container displays all JARs required by our project, e.g. wicket-1.4.9.jar and slf4j-api-1.5.8.jar. All these were downloaded automatically by Maven into your local Maven repository on your hard drive, and m2eclipse makes Eclipse reference them from that location.

We are now ready to launch the web app: Select the gmap2-examples project folder and then Run As... | Run on Server from the context menu. Select the existing Glassfish server you created before and click Finish. After a while, you see the gmap2-examples welcome page in a web browser window.

Click on one of the links, e.g. marker listener, to see Google Maps in Firefox in Eclipse via Wicket on Glassfish on Java on Linux. (OK, maybe it's not Firefox or Linux on your machine...)

Note that the Java compilation and the WAR assembly and deployment were done by Eclipse, not by Maven.

However, you can also run a Maven build from Eclipse. To build our entire project hierarchy, select gmap2-parent and open Run As | Maven build... from the context menu. Enter the goals clean install and click Run. You will see the Maven messages in the console window. When Maven has finished, click Refresh (F5) on gmap2-parent, and open gmap2-examples/target to see the WAR file compiled by Maven.

13 May 2010

Glassfish Logging with slf4j

Update 18 Dec 2010: There is an extended version of this article.

It can be annoying to have each third-party library or framework in your application logging to a different logfile. slf4j with its various adapters enables you to collect logging events from various APIs (org.slf4j.api, java.util.logging, org.apache.commons.logging) and redirect them to a logging backend of your choice.

I've always preferred log4j or, more recently, logback over java.util.logging, so after working with Glassfish v3 for a while, I tried to tweak it to use logback over slf4j and the jul-to-slf4j bridge.

To redirect java.util.logging used by Glassfish v3, you put the following libs on your classpath:
  • jul-to-slf4j.jar
  • slf4j-api.jar
  • logback-classic.jar
  • logback-core.jar
(You can replace the logback libs by any other supported backend like log4j, see the slf4j docs for more details.)
The problem with Glassfish is:
  • You need to take care of its class loader hierarchy and make sure that the logging jars get picked up early enough.
  • Glassfish does some all-too-clever logger manipulation in its LogManagerService which will get in your way if you don't like the Glassfish defaults: It redirects all System.out messages to a logger.
I did not manage to fully supersede Glassfish logging by slf4j and logback, but at least I can copy all Glassfish log events to my logback application log like this:
  • Put the logging libs in [install-root]/lib/endorsed.
  • Build a JAR containing your logback.xml configuration and put it in the same place.
  • Edit an entry in [instance-root]/config/logging.properties, setting
    handlers = org.slf4j.bridge.SLF4JBridgeHandler
Now if you omit a ConsoleAppender from your logging configuration, the Glassfish server.log will no longer contain any log output from your application. It will still contain the log messages from Glassfish itself, but they will also be included in your own logback logfile.