Extreme Java When vanilla Java is not enough

22May/090

Using Spring with Mojarra InjectionProvider

Are you using SpringBeanFacesELResolver to handle dependency injection on managed beans? It works nice, but your faces-config grows fast with this approach.

Two months ago, I posted about using Spring injection outside application context. I forgot to mention that the same trick can be used to replace ELResolver solution if you are using Mojarra as your JSF provider.

You only need to add a servlet context parameter:

<context-param>
  <param-name>
    com.sun.faces.injectionProvider
  </param-name>
  <param-value>
    mypkg.SpringJSFInjectionProvider
  </param-value>
</context-param>

And the implementation of SpringJSFInjectionProvider is as simple as:

public class SpringJSFInjectionProvider
       implements InjectionProvider {
  private WebContainerInjectionProvider wcip =
      new WebContainerInjectionProvider();
 
  @Override
  public void inject(Object bean)
         throws InjectionProviderException {
    FacesContextUtils
      .getWebApplicationContext(
         FacesContext.getCurrentInstance())
      .getAutowireCapableBeanFactory()
      .autowireBeanProperties(bean,
         AutowireCapableBeanFactory.AUTOWIRE_NO,
         false);
    wcip.inject(bean);
  }
  @Override
  public void invokePreDestroy(Object bean)
         throws InjectionProviderException {
    wcip.invokePreDestroy(bean);
  }
  @Override
  public void invokePostConstruct(Object bean)
         throws InjectionProviderException {
    wcip.invokePostConstruct(bean);
  }
}

Adding this, you can shrink your faces-context, removing all "managed-property" tags. Your managed beans can look more JavaEE 5 after you change this:

private BO bo;
 
public void setBo(BO bo) {
  this.bo = bo;
}

To this:

@Resource(name="bean-on-appctx")
private BO bo;

No setter, no ELResolver. This means less code to maintain! If you plan to migrate from Spring to EJB, this means you will only need to promote the BO to an stateless bean and change @Resource to @EJB!

7May/090

Executable WAR files using Winstone and Maven

After a couple of years developing webapps, I'm starting to get problems to design a non-web UI. Not a big deal, since I only use Swing on personal projects. The biggest problem with web projects is the need of at least a servlet container. If you host a lot of projects, Tomcat, JBoss, Glassfish and Geronimo are good choices. But, if you need to host only one "web-container-only" project, Jetty or Winstone are way better.

I'm planning to use maven instead of ant for all of my projects, both personal and professional. It is easier to maintain and more IDE-portable. When I'm developing, I can use "maven jetty:run" to automatically compile and start Jetty (ctrl-c ends the server). The whole process is faster than a "ant dist / deploy / OOM / kill -9" when using Tomcat. You only need to add jetty plugin to your POM (inside "project > build > plugins"):

<plugin>
  <groupId>org.mortbay.jetty</groupId>
  <artifactId>maven-jetty-plugin</artifactId>
  <configuration>
    <contextPath>/</contextPath>
  </configuration>
</plugin>

This is useful to develop, but, when I want to create the "executable WAR", I prefer using Winstone - it's even lighter than Jetty. This means I need another plugin:

<plugin>
  <groupId>net.sf.alchim</groupId>
  <artifactId>winstone-maven-plugin</artifactId>
</plugin>

Running "winstone:embed" will create a "xxx-standalone.jar" on "target" folder. This JAR can be run with "java -jar" and your application becames avaliable on "http://localhost:8080/". This plugin has a lot of configurations, and, using maven, you can configure it to run this goal on package phase. Read its manual for more information.