Category Archives: Java

JUnit tests made easy with Guice

Guice is an open source tool by Google that aims at simplifying the construction of software components especially when complex relationships exist between its parts.

Until I came across Guice (and Spring, to be honest), I was used to honor two main design patterns: factory methods and builder. The intent of these two patterns is to separate the construction of objects from their representation and from their usage. For instance, if you delegate the construction of instances of an interface to a factory method, which concrete class will be used to create the instances will depend on the particular implementation of the factory method which, in turn, will vary from application to application. On the other hand, using a builder you centralize the construction of complex objects so that the way these objects are built (and their dependencies in particular) is defined once for all in the code. Of course, if you follow these two patterns in Java you’ll have to abandon the new operator.

Guice is an easy way to blend these two patterns together into a single framework and much more. Thanks to the dependcy injection design pattern, Guice helps you decouple components and configure dependencies. All you have to do is define which interfaces are implemented by which concrete classes and which objects are to be injected in your components.

If you’re unit testing components with JUnit you surely face where to put the initialization code that reads the Guice configuration modules and creates the injector(s). As a trivial solution you could make every test class to extend a common class with a static method that is annotated with @BeforeClass; this method has to be used once per test to setup the Guice injector. While this is an acceptable solution, it doesn’t take full advantage of the Guice capabilities. When I faced this problem for the first time I asked myself what the best way to inject the components I needed in my tests was. I wanted to obtain something like this:

public class ServiceTest {
    private IService service;

    @Inject
    public void setService(IService service) {
        this.service = service;
    }

    @Test
    public void testApp() {
        Assert.assertEquals("Hello World!", service.doSomething());
    }
}

I then found a post about integrating Guice and JUnit that solved almost all my doubts. The author suggested to create a custom JUnit class runner that overrides the default behaviour and, in addition to instancing the test class, it configures Guice and injects the dependencies in the test class instance. The custom class runner must be passed to the JUnit @RunWith annotation. This is a more elegant solution with respect to the before mentioned trivial one. But still it had something I didn’t like: the fact that the Guice modules have to be passed to the constructor of the custom class runner. Wouldn’t it be better if the list of Guice modules was declared within the unit test as a parameter of an annotation?

I got inspired by how JUnit test suite works and I wrote my own class runner:

public class GuiceJUnitRunner extends BlockJUnit4ClassRunner {
    private Injector injector;

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    public @interface GuiceModules {
        Class<?>[] value();
    }

    @Override
    public Object createTest() throws Exception {
        Object obj = super.createTest();
        injector.injectMembers(obj);
        return obj;
    }

    public GuiceJUnitRunner(Class<?> klass) throws InitializationError {
        super(klass);
        Class<?>[] classes = getModulesFor(klass);
        injector = createInjectorFor(classes);
    }

    private Injector createInjectorFor(Class<?>[] classes) throws InitializationError {
        Module[] modules = new Module[classes.length];
        for (int i = 0; i < classes.length; i++) {
            try {
                modules[i] = (Module) (classes[i]).newInstance();
            } catch (InstantiationException e) {
                throw new InitializationError(e);
            } catch (IllegalAccessException e) {
                throw new InitializationError(e);
            }
        }
        return Guice.createInjector(modules);
    }

    private Class<?>[] getModulesFor(Class<?> klass) throws InitializationError {
        GuiceModules annotation = klass.getAnnotation(GuiceModules.class);
        if (annotation == null)
            throw new InitializationError(
                    "Missing @GuiceModules annotation for unit test '" + klass.getName()
                            + "'");
        return annotation.value();
    }
}

Basically, if you use this runner your test will be :

@RunWith(GuiceJUnitRunner.class)
@GuiceModules({ ComponentsTestModule.class, ServicesTestModule.class })
public class ServiceTest {
    private IService service;

    @Inject
    public void setService(IService service) {
        this.service = service;
    }

    @Test
    public void testApp() {
        Assert.assertEquals("Hello World!", service.doSomething());
    }
}

I think this is a cleaner approach and, in fact, it is very similar to how unit tests are configured with Spring. The advantage is that every needed module is declared clearly in the unit test and could be easily added or removed.
I uploaded the code on GitHub, feel free to check it out from my account and leave a feedback: GuiceJUnitRunner.

Project is based on Maven2 and Eclipse. These are some easy steps to download and test it:

% git clone git://github.com/sfragis/GuiceJUnitRunner.git
% cd GuiceJUnitRunner
GuiceJUnitRunner% mvn test

Sudo like tool for Alfresco – security aspects

In my first post in this blog I proposed a way to execute some javascript code with the admin privileges within the Alfresco (web)scripts.
As Peter Monks pointed out in his comment, there’re some risks concerning security you’d better be aware of if you intend to use this extension in your projects.
As Peter suggested, if users can author their own scripts then they can potentially submit code that runs with administrator privileges, which is an obvious security flow.
Also, attention must be paid in case the eval statement is used within the sudo argument function: avoid this kind of practice if the eval argument itself depends on some webscript input parameter since this could potentially lead to code injection. So how to cope with these problems?
My solution is to create a “sudoers” group (as in the Unix OSs) so that only users that belong to this group can execute the sudo function. Here is how I would change the Sudo bean:

public class Sudo extends BaseScopableProcessorExtension {
    private AuthorityService authorityService;

    public void sudo(final Function func) throws Exception  {
        final Context cx = Context.getCurrentContext();
        final Scriptable scope = getScope();
        String user = AuthenticationUtil.getRunAsUser();

        Set<String> groups = authorityService.getContainingAuthorities(AuthorityType.GROUP, user, false);
        if (!groups.contains("GROUP_SUDOERS"))
            throw new Exception("User '" + user + "' cannot use sudo");

        RunAsWork<Object> raw = new RunAsWork<Object>() {
            public Object doWork() throws Exception {
                func.call(cx, scope, scope, new Object[] {});
                return null;
            }
        };

        AuthenticationUtil.runAs(raw, AuthenticationUtil.getAdminUserName());
    }
}

We used the authorityService service to get the set of groups the current user belongs to and then we checked that the SUDOERS group is one of those. If you use this version of the Sudo bean, remember to update the Spring bean definition (file sudo-script-services-context.xml):

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
    <bean id="Sudo" parent="baseJavaScriptExtension" class="eu.fabiostrozzi.sudo.ws.js.Sudo">
        <property name="extensionName">
            <value>sudoUtils</value>
        </property>
       <property name="authorityService">
             <ref bean="AuthorityService" />
       </property>
    </bean>
</beans>

This is by no means a fully fledged solution but surely reduces risks if, for instance, users that can author scripts are not added to the SUDOERS group.

Sudo like tool for Alfresco webscripts

This year we at GetConnected worked a lot on integration solutions based on Alfresco. Integrating customers’ softwares with Alfresco means, first of all, facingĀ  with different permissions models: the Alfresco’s one and that of the external software. Most of the times they differ and it couldn’t be otherwise: althought Alfresco is an extendable, general purpose product, external softwares target specific problem and have ad-hoc solutions. Continue reading “Sudo like tool for Alfresco webscripts” »