Integrating guice and junit4

A JUnit4 Method rule to perform injection on your test fixture before each test case:

import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
 
import org.junit.rules.MethodRule;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
 
public class PerTestGuiceRule implements MethodRule
{
   private final Module module;
 
   public PerTestGuiceRule(final Module module)
   {
      this.module = module;
   }
 
   @Override
   public Statement apply(
            final Statement base,
            @SuppressWarnings("unused") final FrameworkMethod method,
            final Object target)
   {
      return new Statement()
      {
         @Override
         public void evaluate() throws Throwable
         {
            final Injector injector = Guice.createInjector(module);
 
            injector.injectMembers(target);
 
            base.evaluate();
         }
      };
   }
}

Use it by putting this code in you test fixture:

@Rule public PerTestGuiceRule guiceRule = 
                   new PerTestGuiceRule(new MyModule());
 
@Inject MyInjectableType myInjectableType;

You might want to check out GuiceBerry. I tried to use it, but for my case it seems very complex, or maybe impossible, to create your module per-test due to the static map of module class -> module instance used internally by guiceberry. There is a test scope included, but I don’t see a really clean way to use that if you want to test your production guice modules.

Marshalling Immutable Types in Jaxb

Unfortunately Jaxb requires any classes it creates during unmarshalling to have a default no-arguments constructor, and some way of mutating the fields. This prevents the use of types which enforce immutability using final fields.

A way to get around this is to use the @XmlJavaTypeAdapter annotation and implement custom marshalling and unmarshalling.

For example, create a class like this:

@XmlJavaTypeAdapter(value = MyValueXmlAdapter.class)
public class MyValue
{
   private final String value;
 
   private MyValue(final String value)
   {
      this.value = value;
   }
 
   @Override
   public String toString()
   {
      return value;
   }
 
   public static MyValue valueOf(final String value)
   {
      return new MyValue(value);
   }
}

and another like this:

public class MyValueXmlAdapter extends XmlAdapter<String, MyValue>
{
   @Override
   public String marshal(final MyValue value) throws Exception
   {
      return value.toString();
   }
 
   @Override
   public MyValue unmarshal(final String value) throws Exception
   {
      return MyValue.valueOf(value);
   }
}

Update Glassfish 3.0 to use Jersey 1.3

In order to update Glassfish 3.0 to use Jersey 1.3 we had to write over the Jersey files in the “modules” subfolder of the glassfish installation.

Here are some maven dependencies for the required files:

   <properties>
      <jersey.version>1.3</jersey.version>
      <jackson.version>1.5.6</jackson.version>
   </properties>
   <dependencies>
      <dependency>
         <groupId>com.sun.jersey</groupId>
         <artifactId>jersey-server</artifactId>
         <version>${jersey.version}</version>
      </dependency>
      <dependency>
         <groupId>com.sun.jersey</groupId>
         <artifactId>jersey-client</artifactId>
         <version>${jersey.version}</version>
      </dependency>
      <dependency>
         <groupId>com.sun.jersey</groupId>
         <artifactId>jersey-json</artifactId>
         <version>${jersey.version}</version>
      </dependency>
      <dependency>
         <groupId>com.sun.jersey.glassfish.v3.osgi</groupId>
         <artifactId>jersey-gf-server</artifactId>
         <version>${jersey.version}</version>
      </dependency>
     <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-xc</artifactId>
        <version>${jackson.version}</version>
     </dependency>
     <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-jaxrs</artifactId>
        <version>${jackson.version}</version>
     </dependency>
     <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>${jackson.version}</version>
     </dependency>
     <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>${jackson.version}</version>
     </dependency> 
   </dependencies>

And here is a assembly plugin snippet which will rename the dependencies the way glassfish expects them to be named

   <dependencySets>
      <dependencySet>
         <outputFileNameMapping>${artifact.artifactId}.${artifact.extension}</outputFileNameMapping>
         <outputDirectory>modules</outputDirectory>
      </dependencySet>
   </dependencySets>

Serving static content and Jersey

If you want to serve static content from the same WAR as Jersey resources, it is possible to configure Jersey to run as a filter rather than a Servlet.

You can then define the property com.sun.jersey.config.property.WebPageContentRegex to exclude URLs matching the regular expression from being handled by Jersey. Instead request matching the pattern will fall through to the next filter and eventually the default Servlet, which can respond with your static content in the normal way.

   <filter>
      <filter-name>jerseyFilter</filter-name>
      <filter-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</filter-class>
      <init-param>
         <param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
         <param-value>/static/.*</param-value>
      </init-param>
   </filter>
   <filter-mapping>
      <filter-name>jerseyFilter</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>

Testing using FEST Swing in CruiseControl

I have a CruiseControl CI build running as a windows service. Unfortunately when unit tests involving FEST Swing are run they fail as they need to actually render the UI components to a logged in user’s desktop.

My CruiseControl machines are virtual windows server 2003 machines running on vmware. So each build has its own dedicated virtual machine.

I followed the instructions for hudson builds on windows from the FEST Swing site.

Configure the server to auto login your build user:

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon=1
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName=testuser
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultPassword=secret

Start CruiseControl on login by creating a batch file in the users “Start Up” start menu folder containing:

"C:\Program Files\CruiseControl\Wrapper.exe" -c "C:\Program Files\CruiseControl\wrapper.conf"

Make sure that the screen saver is disabled.

ActiveMq 5.3.0 and JBoss JMX

It seems that in ActiveMq 5.3.0 someone has change the way that the JMX Management Context is discovered.

If you simply upgrade from version 5.2.0 to 5.3.0 you will need to define the system property jboss.platform.mbeanserver

I think this tells JBoss to use the platform MBean server instead of starting it own; and it is the platform MBean server that ActiveMQ uses for its org.apache.activemq:BrokerName=localhost,* MBeans.

Glassfish Answer File

I’ve managed to get the glassfish v3 silent install working.

Maybe I should have just used the zip file distribution… anyway….

Here is the answer file I used. all the ${variables} need to be filled in with the values relevant to your situation. You have to pass the -s option as well as the -a option to the glassfish installer exe.

RegistrationOptions.regoptions.CREATE_NEWACCT=CREATE_NEWACCT
glassfish.Administration.HTTP_PORT=${glassfish.http.port}
updatetool.Configuration.PROXY_PORT=
glassfish.Administration.ADMIN_PASSWORD=${glassfish.admin.password}
JDKSelection.directory.JDK_FROM_LIST_CHOICE=false
RegistrationOptions.regoptions.SKIP_REGISTRATION=SKIP_REGISTRATION
updatetool.Configuration.PROXY_HOST=
SOAccountCreation.accountinfo.COUNTRY=
InstallHome.directory.INSTALL_HOME=${INSTALL_PATH}
RegistrationOptions.regoptions.USE_EXISTINGACCT=USE_EXISTINGACCT
SOAccountCreation.accountinfo.FIRSTNAME=
updatetool.Configuration.ALLOW_UPDATE_CHECK=false
glassfish.Administration.ADMIN_USER=${glassfish.admin.user}
JDKSelection.directory.JDK_LIST=
SOAccountCreation.accountinfo.PASSWORD=
SOAccountCreation.accountinfo.COMPANYNAME=
JDKSelection.directory.HIDDEN_JDK=
SOAccountCreation.accountinfo.COUNTRY_DROP_DOWN=
SOAccountCreation.accountinfo.REENTERPASSWORD=
License.license.ACCEPT_LICENSE=0
RegistrationOptions.regoptions.USERNAME=
updatetool.Configuration.BOOTSTRAP_UPDATETOOL=false
SOAccountCreation.accountinfo.LASTNAME=
glassfish.Administration.ADMIN_PORT=${glassfish.admin.port}
RegistrationOptions.regoptions.USERPASSWORD=
JDKSelection.directory.JDK_TYPED_IN_CHOICE=true
SOAccountCreation.accountinfo.EMAIL=
JDKSelection.directory.JDK_TYPE_IN=${JDKPath}
RegistrationOptions.regoptions.DUMMY_PROP=

Glassfish Automated Installation

I’m struggling with the Glassfish v3 automated installation. I’m trying to follow the instructions in the glassfish install documentation. But the variables they mention as configurable don’t correspond with the variables that are in the generated answer file.

Things I know so far are:

  • you can generate an answer file using the -n option
  • you can read the answer file in using the -a option
  • you have to specify -s if you want the installer to run silently
  • you can create a windows service using asadmin create-service which seems to be new to version 3