couldhavebeenguicelogo.pngAs you all know, I am a regular springframework user. Especially now that I am working for JTeam, all my projects deal with the springframework. At JTeam we are innovators, so we do check out some other frameworks as well. Therefore I am looking at an alternative for Dependency Injection. Since google is doing a good job with there Guice framework, I thought I’d give it a go. Time for a spring break. Beforehand I do want to stress that this is not going to be a post telling that spring is so bad for some reason and that Guice is much better. If you are looking for that, than there are better posts. I need more time to make a good judgement in that area. Of course where appropriate (or not) I might do some comparison. I do am a persons with an opinion, and I do not mind sharing it :-).

So what can you expect from this post? First of all a very short description of my first steps with google Guice. Second, I’ll explain more about the MVC framework called Stripes. I’ll focus on the integration between stripes and Guice. Third a very brief introduction into a back end using the wideplay jpa implementation. Fourth and finally some very careful conclusions.

Read on for the good stuff

What is all this Guice about? Guice in itself focusses on Dependency Injection. If you need more than that, you need extensions. If you want a full tutorial about Guice, I recommend the following book and of course a lot of online resources.

[amtap book:isbn=1590599977]

Next I discuss the most important things I found in this book and in online resource as a springframework user.

The things I discuss are:

  • Module – Configures the binding of the Interfaces to their implementations.
  • @Inject – Annotation used to tell Guice that we need an instance of one of its controlled objects.
  • Injector – Object that gives access to all objects under control of Guice.
  • @ImplementedBy – annotation on the interface with the default implementation of that interface. This way you do not need it to be configured in a Module. You can overrule this implementation by specifying it in a module.
  • .asEagerSingleton() – A singleton object will be instantiated eagerly, meaning during initialization.
  • Provider – When you have no control over the classes since they are library classes and/or legacy code.
  • AOP – How to use MethodInterceptors using Guice
  • Persistence using warp persist – wideplay has created a nice abstraction of JPA for Guice.
  • Web exposure using Stripes – Stripes is a framework that takes very little configuration. You can integrate Guice easily with Stripes.

Module

The binding is configured using an internal DSL. I still like the concept which I talked about before in my report from JAOO.

bind(Service.class).to(ServiceImpl.class).in(Scopes.SINGLETON);

After reading this line of code you can easily understand that we are binding all requests for a service to the ServiceImpl class and make it a singleton. A bit more advanced example.

PersistenceService.usingJpa().across(UnitOfWork.TRANSACTION).transactedWith(TransactionStrategy.LOCAL)

Here we configure the PersistenceService, it uses JPA to persist, creates sessions across each transaction. The transactions are coming from a local resource (no JTA). There are other configuration options for using AOP method interceptors and for wiring the different Modules. You can easily create a module for all your architectural layers and make them call each other using the install command.

The last thing I want to mention with respect to the Module is the abstract implementation AbstractModule. When you use this as a parent class, you can use the nice DSL for configuration.

Injector

As mentioned in the sum up of features, the Injector gives access to all objects that are under control of Guice. There are two different modes in which the Injector can run: Production and Development. By default, the development mode is on. Before going into production, you need to change the creation of the Injector into:

Guice.createInjector(Stage.Production, new MyModule())

I do not really like this, using an environment variable for configuration is better. I also believe that a production stage would be better as a default.

The injector stores all bindings using a Key object. Therefore, obtaining a configured binding is done using this key. There are shortcuts however. The following two lines are the exact same thing

injector.getInstance(Service.class);
injector.getInstance(Key.get(Service.class));

Why this is important? This is what you must use if you have multiple implementations of the same interface. Imagine you have an interface Service with two implementations: NormalService and SuperService. When requesting an implementation of Service, you need to decide which one to inject. Annotations to the rescue. Annotate the requesting class with you custom annotation that enables Guice to decide which implementation to inject. In our example we could say that detailed objects need to the super service. The following block of code shows the object that gets a dependency injected and the binding configuration. Look for the annotatedWith part.

@Inject
public void setService(@Detailed Service service) {...}

bind(Service.class).to(NormalService.class);
bind(Service.class).annotatedWith(Detailed.class).to(SuperService.class);

Provider

There are occasions where you cannot use the @Inject tag. One of the main reasons is using library classes. To make sure you can use library classes, Guice makes use of the Providers. It is a very easy interface that you need to implement.

public interface Provider <T> {
  T get();
}

Now instead of injecting the needed object, you inject the provider.

AOP

Guice has implemented a very basic AOP model. You can only use the MethodInterceptor interface. This enables you to influence the input arguments as well as results of the actual method. You can even prevent the method from executing, just like you can throw new exceptions. I am not going to explain why AOP is interesting. The following line of code shows an example of wiring a MethodInterceptor to all the methods of implementations of the Service interface.

bindInterceptor(subclassesOf(Service.class),any(),new ServiceLogger());

The bindInterceptor has three arguments, the first matches the classes to wire the aspects around. The second argument matches the methods and the third gives the implementation. The most important part are the matchers. Out of the box Guice comes with a number of standard matchers like: any(), not(), annotatedWith(), subclassesOf, only(), identicalTo(), inPackage(), returns(). You can combine the matchers to come up with the right pointcuts for the aspect.

Persistence using warp persist

Guice is a very light weight framework in itself. You need extensions to do some real work. One of the needed extensions is for persisting your objects. Wideplay has created a nice extension to Guice for using JPA. I am not going to reproduce their documentation here. Read the documentation on their website. I do give you the code for a project I am doing together with Frank at JTeam. Frank created the following class and persistence config

@JpaUnit
public class DaoModule extends AbstractModule {
    @Override
    protected void configure() {
        initializePersistenceUnit();
        startPersistenceService();
        bindDaos();
    }

    private void initializePersistenceUnit() {
        bindConstant().annotatedWith(JpaUnit.class).to("jpaUnit");
        install(PersistenceService.usingJpa()
                .across(UnitOfWork.TRANSACTION)
                .transactedWith(TransactionStrategy.LOCAL)
                .buildModule());
    }

    private void startPersistenceService() {
        bind(PersistenceServiceInitializer.class).asEagerSingleton();
    }

    private void bindDaos() {
        bind(ParcelDao.class).to(JpaParcelDao.class).asEagerSingleton();
    }
}
public class PersistenceServiceInitializer {
    @Inject
    public PersistenceServiceInitializer(PersistenceService service) {
        service.start();
    }
}

You also need a persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                        http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
             version="1.0">
    <persistence-unit name="solidJpaUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>...entity class 1...</class>
        <class>...entity class 2...</class>
        <class>... etc ...</class>

        <properties>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/demo"/>
            <property name="hibernate.connection.username" value="demo"/>
            <property name="hibernate.connection.password" value="emo"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
            <property name="hibernate.connection.autocommit" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

In your dao implementation you inject the EntityManager and you can execute your finders and other data access calls. The following code block gives you a very easy example

public class JpaExampleDao implements ExampeDao {
    private final Provider<EntityManager> manager;

    @Inject
    public JpaExampleDao(Provider<EntityManager> manager) {
        this.manager = manager;
    }

    public List<Example> findExamples() {
        return manager.get()
                .createQuery("SELECT e FROM example e")
                .getResultList();
    }
}

Final thing to mention here is the @Transactional annotation. Using the warp persistence library, you can use this annotation to demarcate your transactions. At the moment there are just READ_ONLY and READ_WRITE configurations.

Web presence using stripes

The web front end is the last step for this blog post. I am not going to explain stripes. I use a very small part of it for our project. The only thing that was important to me is the integration of stripes and Guice. There is a project that does the integration called stripes-guicer. I had some problems to get this to work. Than I found a blog post that did most of the work I needed. Before I go and describe this solution let me explain the problem first.

The problem with a lot of frameworks for the web, is that they control the objects that are created. The ActionBeans or controllers are created by the web framework. You cannot inject Guice controlled beans at construction of these obejcts.

There are two possible solution directions. The first is to get Guice between the actual construction of the framework. Then you can use the normal Guice configuration. Another solution is to let Guice know of these objects right after they are created. Almost all frameworks give you a mechanism to get notified of this phase. The influence Guice can have on these objects is limited. Since they have been constructed already you cannot use constructor injection and you cannot use AOP as provided by Guice. Of course you the scope of these objects is also not controlled by Guice.

Looking at the mentioned framework: stipes-guicer, they got Guice between object creation by Stripes. TO bad this did not work for me. The mentioned blog took the other path and injects the bean into Guice. The following pieces of code show this path as mentioned by Stephen Starkey

We start off with a ServletContextListener implementation that initializes Guice and puts in on the ServletContext. Than we create a Stripes interceptor that intercepts the LifecycleStage.ActionBeanResolution phase. During this phase we obtain the Guice injector from the ServletContext and inject the current ActionBean using the injectMembers method. To make this all happen, we need to add some items to the web.xml.

public class GuiceServletContextListener implements ServletContextListener {
    private static final Logger logger = LoggerFactory.getLogger(GuiceServletContextListener.class);

    public static final String KEY = Injector.class.getName();

    public void contextInitialized(ServletContextEvent sce) {
        sce.getServletContext().setAttribute(KEY, getInjector(sce.getServletContext()));
    }

    public void contextDestroyed(ServletContextEvent sce) {
        sce.getServletContext().removeAttribute(KEY);
    }

    private Injector getInjector(ServletContext ctx) {
        try {
            return Guice.createInjector(new WebModule());
        } catch (Exception e) {
            logger.error("Problem while initializing the guice injector",e);
            throw new RuntimeException(e);
        }
    }
}
@Intercepts(LifecycleStage.ActionBeanResolution)
public class GuiceInterceptor implements Interceptor {
    private final static Logger logger = LoggerFactory.getLogger(GuiceInterceptor.class);
    
    public Resolution intercept(ExecutionContext context) throws Exception {
        Resolution resolution = context.proceed();
        logger.debug("Running Guice dependency injection for instance of {}",
                context.getActionBean().getClass().getSimpleName());
        ServletContext ctx = context.getActionBeanContext().getServletContext();
        Injector injector = (Injector) ctx.getAttribute(GuiceServletContextListener.KEY);
        injector.injectMembers(context.getActionBean());
        
        return resolution;
    }
}
    <filter>
        <display-name>Stripes Filter</display-name>
        <filter-name>StripesFilter</filter-name>
        <filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
        <init-param>
            <param-name>ActionResolver.Packages</param-name>
            <param-value>nl.jteam.stadgenoot.web.action</param-value>
        </init>
        <init-param>
            <param-name>Interceptor.Classes</param-name>
            <param-value>
                nl.jteam.stadgenoot.web.integration.guice.GuiceInterceptor
            </param-value>
        </init-param>
    </filter>
...
    <listener>
        <display-name>GuiceContextListener</display-name>
        <listener-class>nl.jteam.stadgenoot.web.integration.guice.GuiceServletContextListener</listener-class>
    </listener>

Conclusions

After a week of playing around I can now say, I like Guice. It is the mixing activity that can improve here and there. I am sure people will jump on the wagon there. It does come with a lot of challenges as a springframework veteran. Now I know both, it seems like a good additional tool in my Toolbox. The usage of pure Java is very nice. Simplicity as a goal is very important to a framework lice Guice.

As for the other two frameworks, I like warp persistence. Some additional transaction stuff like specifying that an existing transaction is required would be nice. Stripes is to hard for me to tell, maybe I’ll spend another post on that in the future.

Hope you liked it, stay tuned for new topics. I understood that a very nice article is coming about a Circuit Breaker implementation.

Ps. a tip for all wordpress users out there, if you post java code with generics or incomplete xml, do not use the option to make wordpress correct xhtml errors. It does not do nice things with your code.

One liter of Guice during Spring break
Tagged on: