Java
Maven and skinny wars
by ron on Sep.20, 2009, under Java, Tools
Maven is a great build system, but sometimes limitations come up that can drive you crazy. One such limitation is support for building “skinny war” files. Granted, I don’t think it’s the most common configuration, but for certain types of applications, it’s the preferred way to package your application.
By default, war files are packaged with all of the libraries they use embedded within them. This is fine, unless your application uses a large number of libraries, and you have more than one war file within your enterprise application archive (ear file). In that case, you’re causing the JVM to load the same set of classes multiple times, once for each war, which can use up a significant amount of memory, and bloating the size of your ear file.
In a skinny war configuration, the libraries are packaged at a higher level, within the ear file itself, and the war files are made to reference the libraries packaged within the ear file within their MANIFEST.MF file. The classes are loaded once, and can be used in multiple web applications bundled in the ear.
Unfortunately, this isn’t directly supported in Maven, although there are workarounds. As this page states, “The Maven WAR and EAR Plugins do not directly support this mode of operation but we can fake it through some POM and configuration magic”. The workaround is to list the jars in each war, but tell Maven to exclude it from the WEB-INF/lib and to add references to the jar in the MANIFEST.MF file.
The ear file Maven project then needs to list every library it will package as a dependency. This means that common libraries will be listed in the ear project, and each war project that uses them, causing quite a bit of bloat in the Maven project files.
This wiki page has a good description of the situation, some alternate solutions, and requirements for a long term solution.
Ideally, I’d like to be able to take the same Maven war project file, and build for standalone deployment (fat war), or deployment within an ear project where the common libraries are included once in the ear file (skinny war), without having to change the Maven war project file.
For this to work, I think the ear project would have to control whether and which war project libraries are pushed up to the ear project. The ear project file could explicitly list those libraries that should be bundled in the ear, or it could have an option where it calculates the common libraries across the contained war files, and automatically bundles them in the ear file. As the link above indicates, the ear project would have to have the ability to rewrite the manifest entries of the contained war projects.
Technorati Tags: maven java j2ee

JSR 303 & Hibernate validation framework
by ron on Jul.14, 2009, under Java
I was recently looking for a validation framework, and came across the work that has been done lately for JSR 303 (latest version of the spec here). JSR 303 defines a standard meta-data model and API for validation of JavaBeans/POJOs. Basically, it’s a standard way to describe constraints for Java POJOs, and an API to access those constraints.
From the JSR:
“Validating data is a common task that is copied in many different layers of an application, from the presentation tier to the persistentce layer. Many times the exact same validations will have to be implemented in each separate validation framework, proving time consuming and error-prone. To prevent having to re-implement these validations at each layer, many developers will bundle validations directly into their classes, cluttering them with copied validation code that is, in fact, meta-data about the class itself.”
I definetely agree – the validation metadata belongs to the domain class. This has been a hole in the Java space for quite a while. We’ve had validation frameworks such as Commons Validator (previously part of Struts) for many years, but we haven’t had something that could be used across layers in a widespread manner. If you look at typical web applications with XML schemas , a persistence framework, and Web UI, you can easily see where you can end up re-implementing the same constraints multiple times.
public class Address {
@NotNull private String line1;
private String line2;
private String zip;
private String state;
@Length(max = 20)
@NotNull
private String country;
@Range(min = -2, max = 50, message = "Floor out of range")
public int floor;
...
}
As can be seen from the Hibernate Validator example above, the JSR allows you to specify the validation message as a part of the metadata. I think it’s good to have the option, but I prefer to define the validation messages externally. I don’t want to have to change my domain classes every time someone wants different wording on a validation message, and for those that need to support internationalization, you pretty much have no option but to define them externally. From looking at the JSR, it looks like defining messages externally is also supported.
Like recent JSRs, I like that it supports annotations, but still supports overriding/extension via XML. I’m also glad this JSR works on Java SE. In the past too many JSRs were restricted to JEE.
Hibernate Validator 4 (currently beta 1) is the reference implementation. It being a Hibernate project, you can guess that Hibernate core would be able to use the constraints to generate table definitions, etc.. But what about other layers – I’d really like to see UI frameworks taking advantage of this, and generating browser-side validation JavaScript as well as enforcing the constraints server side.
Here’s what I was able to find in the JSF world:
- MyFaces Extensions Validator
Planned support for JSR 303, but not currently supported. See this page. - RichFaces BeanValidator
RichFaces 3.2.2 supports constraints defined in Hibernate Validator. Presumably they’ll switch to JSR 303 in the future. Since Hibernate Validator 4 is the reference implementation, hopefully switching from Hibernate Validator 3.X to JSR 303 is little/no work.
MyFaces and JBoss built-in implementation
by ron on Oct.28, 2008, under Java, Web
I’m working on a WebSphere-based application, and need to get it running on my Mac. RAD isn’t available for the Mac, and even if it was, it’s so far behind in Eclipse revisions that I can’t use most of the Eclipse plugins I find useful.
So there’s a couple options for developing WebSphere-based applications on Eclipse/Mac:
- MyEclipse Blue Edition : An Eclipse distribution with WebSphere connectors. Bring your own WebSphere (e.g. WebSphere Express)
- Make your application portable and develop on another app server : Develop on JBoss & Eclipse, but deploy on WebSphere
Right now I’m going with the second option, since a colleague already did most of the work of getting the application running under JBoss. I took the changes he had to make to get it to run under JBoss, and made them into a patch I could apply on top of the latest code from source control.
So far it’s working great. I just have to be careful to do a regression test in a RAD/WebSphere environment before any changes can be handed over to QA.
I did run into a problem with clashing JSF libraries in JBoss:
09:25:40,120 WARN [JBossJSFConfigureListener] MyFaces JSF implementation found! This version of JBoss AS ships with the java.net implementation of JSF. There are known issues when mixing JSF implementations. This warning does not apply to MyFaces component libraries such as Tomahawk. However, myfaces-impl.jar and myfaces-api.jar should not be used without disabling the built-in JSF implementation. See the JBoss wiki for more details.
09:25:40,126 WARN [config] Unable to process deployment descriptor for context ‘null’
09:25:40,443 ERROR [STDERR] java.lang.UnsupportedOperationException
09:25:40,444 ERROR [STDERR] at com.sun.faces.config.ConfigureListener$InitFacesContext.getViewRoot(ConfigureListener.java:1690)
09:25:40,444 ERROR [STDERR] at com.sun.faces.util.MessageFactory.getMessage(MessageFactory.java:113)
09:25:40,444 ERROR [STDERR] at com.sun.faces.util.MessageUtils.getExceptionMessageString(MessageUtils.java:277)
09:25:40,444 ERROR [STDERR] at com.sun.faces.config.ConfigureListener.configure(ConfigureListener.java:855)
09:25:40,444 ERROR [STDERR] at com.sun.faces.config.ConfigureListener.configure(ConfigureListener.java:502)
09:25:40,444 ERROR [STDERR] at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:402)
09:25:40,444 ERROR [STDERR] at org.jboss.web.jsf.integration.config.JBossJSFConfigureListener.contextInitialized(JBossJSFConfigureListener.java:69)
The MyFaces Tomahawk components are an implementation of, and extension of the standard JSF components. This complicates things because when you use application servers that bring their own implementations, such as JBoss and WebSphere, you have to somehow get the application server to not load its implementation ahead of MyFaces. I wish MyFaces had just made their extended components use a separate namespace and we could then use their components while still keeping the application server JSF implementation.
For JBoss, the solution is to set a parameter that instructs JBoss to ignore its own JSF implementation in favor of yours. The following article describes the solution:
http://www.jboss.org/community/docs/DOC-10182
Handy Java utility: jarexplorer
by ron on Dec.16, 2007, under Java, Tools
Wanted to give kudos to a handy little Java utility I started using: jarexplorer. It’s a Swing-based app that indexes the contents of jar files found in an entire directory structure, and lets you search for classes and files within those jar files. It’s blazingly fast and also provides viewers to look into classes, text files, and images. Double click on the search results and the viewer comes up. Nice to see tools that do one thing and do it well.