Kohei Nozaki's blog 

Entries tagged [guice]

Jukito integration with JPA and guice-persist


Posted on Sunday Jul 31, 2016 at 11:28AM in Technology


A DI container such as Guice helps you to assemble loosely-coupled classes that easy to write unit tests.

But integration tests, that are necessary thing as well as unit tests, it’s a different story from writing unit tests. writing integration tests involve many cumbersome initialization code of frameworks such as DI container, JPA provider or an application server. they tend to spread across testcases and make testcases messy.

If you use Guice as DI container, Jukito helps you to write integration tests. its official documentation covers some simple usecases, but not mentioned about integration with guice-persist. so in this entry I’ll introduce you how to integrate and begin writing clean testcases without messy boilarplate code with them.

Create an application to be tested

Consider we have a simple JPA entity and a service class which uses it.

An entity class named Employee:

@Entity
public class Employee implements Serializable {
    @Id
    @GeneratedValue
    private Long id;
    private String name;

    public Employee(final String name) {
        this.name = name;
    }
...

The service class to be tested named EmployeeService:

public class EmployeeService {

    @Inject
    private EntityManager em;

    @Transactional
    public Long save(final String name) {
        final Employee employee = new Employee(name);
        em.persist(employee);
        em.flush();
        return employee.getId();
    }

    public List<String> findAllNames() {
        return em.createQuery("SELECT e.name FROM Employee e ORDER BY e.name", String.class).getResultList();
    }
}

Create a module for testing

Next, we will create a module for testing (BTW I recommend you to use Module overriding for creating one for testing, based on production one). this would be something like:

// Taken from https://gist.github.com/JWGmeligMeyling/785e459c4cbaab606ed8 , thanks!
public class DatabaseModule extends AbstractModule {

    @Override
    protected void configure() {
        install(new JpaPersistModule("myPU"));
        bind(JPAInitializer.class).asEagerSingleton();
    }

    @Singleton
    private static class JPAInitializer {
        @Inject
        public JPAInitializer(final PersistService service) {
            service.start();
        }
    }
}

Create JpaJukitoRunner

Then, create a special TestRunner which extends JukitoRunner as follows:

public class JpaJukitoRunner extends JukitoRunner {

    public JpaJukitoRunner(final Class<?> klass) throws InitializationError, InvocationTargetException, InstantiationException, IllegalAccessException {
        super(klass);
    }

    public JpaJukitoRunner(final Class<?> klass, final Injector injector) throws InitializationError, InvocationTargetException, InstantiationException, IllegalAccessException {
        super(klass, injector);
    }

    private UnitOfWork unitOfWork;

    @Override
    protected Object createTest() throws Exception {
        this.unitOfWork = getInjector().getInstance(UnitOfWork.class);
        this.unitOfWork.begin();
        return super.createTest();
    }

    @Override
    public void run(final RunNotifier notifier) {
        notifier.addListener(new RunListener() {

            @Override
            public void testFinished(final Description description) throws Exception {
                // this ensures every tests use distinct entity manager instances
                unitOfWork.end();
            }
        });
        super.run(notifier);
    }
}

This ensures every tests use distinct EntityManager instances for each execution. without this, only one EntityManager instance will be used for all of executions of test cases because it is stored in a ThreadLocal and JUnit uses only one Thread by default for all test executions.

That means that many entities will be kept managed during an execution. consider if you have thousands of test classes in your project - entities will be shared across all of test execution. it will make your EntityManager fat, also your tests may get affected by 1st level cache which got dirty by other test executions.

Create a testcase

Finally, you can write a testcase as follows:

@RunWith(JpaJukitoRunner.class)
@UseModules(DatabaseModule.class)
public class EmployeeServiceTest {

    @Inject
    private EmployeeService sut;
    @Inject
    private EntityManager em;

    @Before
    @Transactional
    public void setUp() throws Exception {
        em.createQuery("DELETE FROM Employee").executeUpdate();
    }

    @Test
    public void saveShouldPersistJohnDoe() throws Exception {
        final String name = "John Doe";

        final long id = sut.save(name);

        final Employee employee = em.find(Employee.class, id);
        assertThat(employee.getName(), is(name));
    }

    @Test
    public void findAllNamesShouldReturnExpectedResult() throws Exception {
        sut.save("Jane Doe");
        sut.save("John Doe");

        final List<String> result = sut.findAllNames();

        assertThat(result.size(), is(2));
    }
}

You can see that there are no any cumbersome initialization code of JPA or database stuff. and note that you can use declarative transaction management by @Transactional, for both the sut class and populating test data into your database.

Cleaning 1st level cache

I have mentioned about bad effect of 1st level cache of EntityManager earlier in this entry, so you may consider that you want to clean 1st level cache. you can do it with em.clear(), or also something like following:

@RunWith(JpaJukitoRunner.class)
@UseModules(DatabaseModule.class)
public class EmployeeServiceTestManagesUOW {

    @Inject
    private Provider<EmployeeService> sut;
    @Inject
    private Provider<EntityManager> em;
    @Inject
    private UnitOfWork unitOfWork;

    @Before
    @Transactional
    public void setUp() throws Exception {
        em.get().createQuery("DELETE FROM Employee").executeUpdate();
    }

    @Test
    public void saveShouldPersistJohnDoe() throws Exception {
        final String name = "John Doe";
        newEntityManager();

        final long id = sut.get().save(name);

        newEntityManager();
        final Employee employee = em.get().find(Employee.class, id);
        assertThat(employee.getName(), is(name));
    }

    private void newEntityManager() {
        unitOfWork.end();
        unitOfWork.begin();
    }
}

In this test, there are three distinct EntityManagers involved in a test execution. the one in setUp(), another one in invocation of sut#save() and finally one for em#find() which is used for assertion.

But in my opinion, this is an overkill and using one shared EntityManager for one test execution would be sufficient. if it didn’t work well, something may wrong with your usage of JPA.

Conclusion

We have seen how testcases which involve JPA and guice-persist could be written cleanly with Jukito. it enables us to eliminate cumbersome boilarplate code for managing and invoking Injector, JPA initialization and manual transaction management. now our testcases look pretty clean.

Executable testcases and the example project can be obtained from my GitHub repository.

References


Managing multiple JPA persistence units with guice-persist


Posted on Sunday Jun 19, 2016 at 06:15PM in Technology


Guice has an extension named guice-persist which aim for providing integration between Guice and a data persistence mechanism. it gives declarative transaction management functionality with the annotation @com.google.inject.persist.Transactional which works with a standalone environment or plain servlet containers such as Tomcat or Jetty.

guice-persist supports JPA and it’s simple to use with only one persistence unit, but to use it with multiple persistence units, it requires some tricks.

The official Guice wiki has only some brief description and I can’t find any complete example to implement it in an actual application. so, in this entry I’ll give you a complete example about how to write a module which manages multiple persistence units.

Module hierarchy

To manage multiple PUs in a module, you should create PrivateModule subclasses of the same number of your persistence units.

Let’s say we have two persistence units that one is named masterPU and another one named slavePU. For example, we have the following persistence.xml in an application:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="masterPU" transaction-type="RESOURCE_LOCAL">
...
    </persistence-unit>
    <persistence-unit name="slavePU" transaction-type="RESOURCE_LOCAL">
...
    </persistence-unit>
</persistence>

In this case, we are going to create and assemble classes as the following diagram:

1788876a 6b06 4be0 a5d1 4cc3c2897b23

MasterPu and SlavePu are qualifier annotations that used for distinguish multiple bindings of JPA classes.

Writing modules

So, how do you write those modules? I’ll show you some important parts of them.

Qualifier annotations

First you need to create the two qualifier annotations something like this:

import static java.lang.annotation.ElementType.*;

@javax.inject.Qualifier
@java.lang.annotation.Target({FIELD, PARAMETER, METHOD})
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
public @interface MasterPu {
}

Don’t forget about SlavePu as well.

JpaPersistPrivateModule

Now here’s the most important part - this class installs JpaPersistModule and rebinds and exposes JPA class bindings:

public class JpaPersistPrivateModule extends PrivateModule {
    protected final String persistenceUnitName;
    protected final Properties props;
    protected final Class<? extends Annotation> qualifier;

    public JpaPersistPrivateModule(final String persistenceUnitName, final Properties props, final Class<? extends Annotation> qualifier) {
        this.persistenceUnitName = persistenceUnitName;
        this.props = props;
        this.qualifier = qualifier;
    }

    public JpaPersistPrivateModule(final String persistenceUnitName, final Class<? extends Annotation> qualifier) {
        this(persistenceUnitName, new Properties(), qualifier);
    }

    @Override
    protected void configure() {
        install(new JpaPersistModule(persistenceUnitName).properties(props));
        rebind(qualifier, EntityManagerFactory.class, EntityManager.class, PersistService.class, UnitOfWork.class);
        doConfigure();
    }

    private void rebind(Class<? extends Annotation> qualifier, Class<?>... classes) {
        for (Class<?> clazz : classes) {
            rebind(qualifier, clazz);
        }
    }

    private <T> void rebind(Class<? extends Annotation> qualifier, Class<T> clazz) {
        bind(clazz).annotatedWith(qualifier).toProvider(binder().getProvider(clazz));
        expose(clazz).annotatedWith(qualifier);
    }

    /**
     * bind your interfaces and classes as well as concrete ones that use JPA classes explicitly
     */
    protected void doConfigure() {
        // write your bindings in your subclasses
        // bindConcreteClassWithQualifier(MyTableService.class);
        // ...
    }

    /**
     * binds and exposes a concrete class with an annotation
     */
    protected <T> void bindConcreteClassWithQualifier(Class<T> clazz) {
        bind(clazz).annotatedWith(qualifier).to(clazz);
        expose(clazz).annotatedWith(qualifier);
    }

    /**
     * binds and exposes a concrete class without any annotation
     */
    protected void bindConcreteClass(Class<?> clazz) {
        bind(clazz);
        expose(clazz);
    }
}

First, this class installs JpaPersistModule and it creates bindings of JPA classes without any annotation but those bindings will not be exposed globally because we are in a PrivateModule. then, this class rebinds them with a qualifier annotation and exposes them with qualifier annotation. eventually, bindings of the four JPA classes will be created with a qualifier annotation.

MyModule, MasterPuModule and SlavePuModule

public class MyModule extends AbstractModule {
    @Override
    protected void configure() {
        install(new MasterPuModule());
        install(new SlavePuModule());
    }

    private static class MasterPuModule extends JpaPersistPrivateModule {
        public MasterPuModule() {
            super("masterPU", MasterPu.class);
        }

        @Override
        protected void doConfigure() {
            bindConcreteClassWithQualifier(MyTableService.class);
        }
    }

    private static class SlavePuModule extends JpaPersistPrivateModule {
        public SlavePuModule() {
            super("slavePU", SlavePu.class);
        }

        @Override
        protected void doConfigure() {
            bindConcreteClassWithQualifier(MyTableService.class);
        }
    }
}

This class installs two JpaPersistPrivateModule subclasses for persistence units and binds a service class named MyTableService which requires injection of EntityManager. this module creates two distinct annotated bindings for the class.

Note that if you need declarative transaction management by @Transactional for your service classes, you should create bindings of them inside doConfigure(). for example, if you creates such bindings in MyModule#configure(), declarative transactions won’t work.

How about PersistFilter?

If you need PersistFilter for those two modules, you need to create a binding for each modules inside doConfigure() as follows:

Key<PersistFilter> key = Key.get(PersistFilter.class, qualifier);
bind(key).to(PersistFilter.class);
expose(key);

Then, install all of modules inside your subclass of ServletModule. after that, create filter mappings inside configureServlets() as follows:

filter("/*").through(Key.get(PersistFilter.class, MasterPu.class));
filter("/*").through(Key.get(PersistFilter.class, SlavePu.class));

Conclusion

We have seen an example of a Guice module that manages two persistence units with guice-persist. check my GitHub repository for the complete example project and testcases.


PrivateModule, TypeLiteral and AssistedInject - Google Guice techniques for complex scenarios


Posted on Sunday Feb 07, 2016 at 11:44AM in Technology


In this entry I’ll introduce you some Google Guice techniques that can be used for some complex class designing scenarios, I’ve learned recently and found very helpful.

I’ve tested techniques that used in this entry works with Google Guice 3.0 and 4.0. example implementations and test cases can be obtained from my GitHub repository.

PrivateModule

Consider you have classes that something like following diagram:

237fbbbb c5d0 4315 aeef ccc9e8b2605e

You have a service class named MyService which depends on the interface named MyStrategy (DOC, Depended On Component). the DOC has two implementations, the one EnglishStrategy says "Hello", when the method of it named sayHello() is being called, and another one JapaneseStrategy says "Konnichiwa".

There are annotation classes English and Japanese to distinguish two strategy MyService depends on. these two annotations are written as follows:

import static java.lang.annotation.ElementType.*;

@javax.inject.Qualifier
@java.lang.annotation.Target({FIELD, PARAMETER, METHOD})
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
public @interface English {
}

On that situation, you want Guice to produce and inject two MyService instances for your client class. you would declare injection points as follows:

// (1) call for injection of MyService annotated as @English
@Inject
@English
MyService englishService;

// (2) call for injection of MyService annotated as @Japanese
@Inject
@Japanese
MyService japaneseService;

But it doesn’t work due to Guice failed to look MyService binding annotated as @English and @Japanese up.

In such case, you can create two PrivateModule and install them in your Module implementation as follows:

@Override
protected void configure() {
    install(new PrivateModule() {
        @Override
        protected void configure() {
            // bind MyService annotated as English to MyService PRIVATELY
            bind(MyService.class).annotatedWith(English.class).to(MyService.class);

            // expose MyService annotated as English GLOBALLY. this fulfills injection point (1)
            expose(MyService.class).annotatedWith(English.class);

            // bind MyStrategy to EnglishStrategy PRIVATELY
            bind(MyStrategy.class).to(EnglishStrategy.class);
        }
    });
    install(new PrivateModule() {
        @Override
        protected void configure() {
            // bind MyService annotated as Japanese to MyService PRIVATELY
            bind(MyService.class).annotatedWith(Japanese.class).to(MyService.class);

            // expose MyService annotated as Japanese GLOBALLY. this fulfills injection point (2)
            expose(MyService.class).annotatedWith(Japanese.class);

            // bind MyStrategy to JapaneseStrategy PRIVATELY
            bind(MyStrategy.class).to(JapaneseStrategy.class);
        }
    });
}

These PrivateModule create two bindings:

  1. MyService annotated with English or Japanese.

  2. MyStrategy without any annotation for EnglishStrategy or JapaneseStrategy privately

And, it exposes only the binding 1. If the binding 2 exposes as well or created in global scope, Guice will complain that there are two bindings for MyStrategy without any annotation. that’s point what PrivateModule helps.

TypeLiteral

Consider you have following injection points that with generics type parameter:

@Inject
List<String> stringList;
@Inject
List<Integer> integerList;

To bind instances to these injection points, you need to use TypeLiteral in your Module implementation as follows:

@Override
protected void configure() {
    bind(new TypeLiteral<List<String>>() {
    }).toInstance(new ArrayList<String>() {{
        add("hello");
    }});

    bind(new TypeLiteral<List<Integer>>() {
    }).toInstance(new ArrayList<Integer>() {{
        add(123);
    }});
}

With this module, Guice resolves correct the two injection points with use of generics type parameter.

Also you can leave constructing an instance to Guice if you have an implementation class. for example, consider you have a generic interface as follows:

public interface MyGenericService<T extends Number> {
    T get();
}

Injection points:

@Inject
MyGenericService<Integer> integerService;
@Inject
MyGenericService<Double> doubleService;

Two implementations:

public class MyIntegerService implements MyGenericService<Integer> {
    @Override
    public Integer get() {
        return 123;
    }
}
public class MyDoubleService implements MyGenericService<Double> {
    @Override
    public Double get() {
        return 0.5;
    }
}

To create bindings to these injection points without creating instances in the module, you can write as follows in your module implementation:

bind(new TypeLiteral<MyGenericService<Integer>>(){}).to(MyIntegerService.class);
bind(new TypeLiteral<MyGenericService<Double>>(){}).to(MyDoubleService.class);

AssistedInject

Consider you have classes that something like following diagram:

703fa153 c547 4dd9 9145 70f36d55988e

You have a service class named MyProduct, which requires a parameter name for its constructor. the parameter name varies in each injection, so we create the factory interface MyFactory for it. also, MyProduct depends on MyCollaborator.

You would create MyProduct instance in your client as follows:

@Inject
MyFactory factory;
...
public void someMethodInClient() {
    final MyProduct product = factory.create("foo");
    ...
}

So, anyway, an implementation of MyFactory is needed. it must be simple in this case but it brings another boilarplate code that should be avoided as possible. and imagine that if MyProduct has a hundreds of DOCs? it will be longer as numbers of DOCs grows. manual construction procedure will be something like new MyProduct(new MyCollaborator1(), new MyCollaborator2(), …​) . obviously, it should be avoided.

With AssistedInject , Guice will do it instead of you.

First, create MyFactory as follows:

public interface MyFactory {
    MyProduct create(String name);
}

Note that you don’t need to create an implementation class yourself, just forget about it. next, put an additional dependency to your pom.xml:

<dependency>
    <groupId>com.google.inject.extensions</groupId>
    <artifactId>guice-assistedinject</artifactId>
    <version>4.0</version>
</dependency>

Put following procedure to your Module implementation:

@Override
protected void configure() {
    install(new FactoryModuleBuilder().build(MyFactory.class));
}

Finally, declare an injection point in the MyProduct class as follows. note that a constructor parameter name is annotated as @Assisted:

@Inject
MyProduct(@Assisted final String name, final MyCollaborator collaborator) {
    this.name = name;
    this.collaborator = collaborator;
}

With that, Guice automatically creates MyFactory implementation for you, and handles parameter name nicely.


Testing guice-persist nested @Transactional behavior


Posted on Wednesday Dec 23, 2015 at 01:41PM in Technology


There is no mention of nested use of @Transactional in the Transactions page of official Guice Wiki so I’ve done some testing about how transactions will be treated in nested use.

As it turns out, Guice seems ignore any of nested @Transactional and any of its rollbackOn attributes. It’s all up to the parent invoker.

For testing, I created two classes as following UML diagram:

b03b90cb 0b01 4601 9dac 755d79f2347e

EnclosingService holds a reference to EnclosedService and invokes a method of it from every method of EnclosingService. Each name of methods state that what exception will be thrown from the method. For example, EnclosedService#runtimeException() throws RuntimeException while EnclosedService#noException() won’t throw any of Exception. EnclosedService#ioExceptionWithRollbackOn() throws IOException and annotated as @Transactional(rollbackOn = IOException.class). And names of methods of EnclosingService states same but the part of after _ means that what method of EnclosedService will be invoked.

All of methods in both services save a Entity with em.persist() then invoke em.flush() so that every changes will be flushed immediately. i.e. EnclosingService#noException_noException() saves two entities that one in the method itself and another one in the enclosing invocation of EnclosedService#noException().

Then I created a test case which has 16 test methods that covers all of methods defined in EnclosingService and found that any of @Transactional annotation or rollbackOn attribute in EnclosedService are being ignored. I summarized the result in a table:

0f595e00 fad6 4df1 b0d6 442024eca778

I can see all of operations are atomic and any Exception thrown in methods of EnclosedService doesn’t affect the result if the transaction will be committed or rolled back. When Guice detects that it’s a RuntimeException or a checked exception that defined as rollbackOn in the first method which annotated as @Transactional then rollback happen.

All resources that used in this test can be obtained from my GitHub repository. It used in-memory database of Apache Derby so that everyone can execute the testcase without any annoying preparation. Also EclipseLink 2.5.1, Guice 3.0 and log4jdbc are used so that I can see how transaction is going such as commit / rollback.


Lean example of Tomcat 8 + Guice 4 + Jersey 2.19


Posted on Wednesday Aug 05, 2015 at 02:36PM in Technology


Jersey is the RI of JAX-RS. in this entry, I introduce you how to use Jersey 2.19 with Guice 4 on Tomcat 8. it looks like there are some issues exist as follows but thanks to https://github.com/Squarespace/jersey2-guice , I’ve succeeded to use them anyway.

The entire project which based on Maven can be obtained from My GitHub repository.

Dependencies

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey</groupId>
            <artifactId>jersey-bom</artifactId>
            <version>2.19</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
    </dependency>
    <dependency>
        <groupId>com.google.inject</groupId>
        <artifactId>guice</artifactId>
        <version>4.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.inject.extensions</groupId>
        <artifactId>guice-servlet</artifactId>
        <version>4.0</version>
    </dependency>
    <dependency>
        <groupId>com.squarespace.jersey2-guice</groupId>
        <artifactId>jersey2-guice</artifactId>
        <version>0.10</version>
    </dependency>
</dependencies>

web.xml

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>guice.tomcat.jersey</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/webapi/*</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>guice.tomcat.MyJerseyGuiceServletContextListener</listener-class>
    </listener>

    <filter>
        <filter-name>guiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

MyJerseyGuiceServletContextListener.java

In this example, we use the servlet context listener named JerseyGuiceServletContextListener which comes from jersey2-guice artifact as parent class.

public class MyJerseyGuiceServletContextListener extends JerseyGuiceServletContextListener {
    @Override
    protected List<? extends Module> modules() {
        return Collections.singletonList(new ServletModule() {
            @Override
            protected void configureServlets() {
                bind(MyService.class).to(MyServiceImpl.class);
            }
        });
    }
}

Service class

We use very simple pair of an interface and implementation that creates a simple greeting message, which used in a past entry so omitted for simplicity.

MyResource.java

This is an simple implementation of JAX-RS resource class. placed under guice.tomcat.jersey package. the preceding service class named MyService will be injected by @javax.inject.Inject annotation.

@Path("myresource")
public class MyResource {

    @Inject
    private MyService myService;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getIt() {
        return myService.hello("Jersey");
    }
}

Test run

$ curl http://localhost:8080/webapi/myresource
Hello, Jersey