Using Guice without a main method - java

I'm creating a library that will be included as a jar, so it won't contain a main method. I'm wondering what is the best practice for bootstrapping Guice in this case. I have one top level singleton.
public class TestManager
{
private TestManager()
{
}
public static TestManager getInstance()
{
// construct and return singleton
}
public void createSomeObjects()
{
}
}
Where should I bootstrap Guice? I was thinking that in the constructor that I could call Guice.createInjector(new Module()); but it wouldn't inject any of the objects created in createSomeObjects().
Is there a common way to do this when you don't have a main method()?
Cheers.

Much like logging configurations, if this is a true library then your options are pretty much this:
Tell the library user that they are responsible for bootstrapping Guice themselves.
Provide a library initialization method that takes care of bootstrapping Guice if they want to use your library
Trying to make the library super-smart to do self-configuration often ends up with somewhat inflexible, hard to test class hierarchies.

If you're just using Guice in the scope of your library and not for the whole application then you could use a static block in the TestManager class.
This strategy assumes that the application is going to call TestManager.getInstance() at some point and that it is the only entry point into your API.
#Singleton
class TestManager {
private static final TestManager INSTANCE;
static {
INSTANCE = Guice.createInjector(new Module()).getInstance(TestManager.class);
}
private TestManager() {
}
public static TestManager getInstance() {
return INSTANCE;
}
#Inject
public void createSomeObjects(YourDependencies ...) {
// Do something with dependencies
}
}

This is not what you should do, but what you could do:
Let key classes in your library extend or otherwise reference a class that initializes everything in a static block. This is a very dirty hack, but if you make sure your api can't be accessed without the classloader loading your initializer class you should be on the safe side.
You could make it a bit cleaner if you used AspectJ and injected a private Member of the initializer type into all classes in your library (without touching the java code), but it would still be a hack.

Related

Design pattern to use when you need to initialize your object?

I have a class, which has an Initialize method, which creates a bunch of tables in a database. This class looks like this:
public class MyClass
{
private bool initialized = false;
public void Initialize()
{
if(!initialized)
{
//Install Database tables
initialized = true;
}
}
public void DoSomething()
{
//Some code which depends on the database tables being created
}
public void DoSomethingElse()
{
//Some other code which depends on the database tables being created
}
}
The two methods DoSomething and DoSomethingElse need to make sure that the Initialize method has been called before proceeding because they depend on having the tables in the database. I have two choices:
Call the Initialize method in the constructor of the class - this does not seem like a good idea because constructors should now call methods, which are non-trivial and could cause an exception.
Call the Initialize method in each of the two methods - this does not seem like a great solution either especially if there are more than a handful of methods.
Is there a design pattern which could solve this in a more elegant way?
I would use a static factory method in which Initialize is invoked, and make the constructor private, to force use of the static factory method:
public class MyClass
{
private MyClass() { ... }
public static MyClass createInstance() {
MyClass instance = new MyClass();
instance.Initialize();
return instance;
}
}
Also, I would remove the initialized variable - in part because you don't need it any more - but also because it requires some means of guaranteeing visibility (e.g. synchronization, volatile or AtomicBoolean) for thread safety.
I think that Miško Hevery's blog post on (not) doing work in constructors is an interesting read.
I would separate the installation of the database from the definition of tasks that depends on it:
static factory could be used for the database installation as pointed out by #andy-turner
and the repository pattern to do work on the database
I suggest this solution because if i understand correctly, you are concerned about the high number of tasks that depends on the database.
Using the dependency injection pattern the repository can get a reference to the database, so in your bootstrapping code you can execute the database installation once and then inject the reference to the database in all the repositories that depends on it.
I would recommend using a collaborator that does the initialisation. That way MyClass can easily be tested by substituting a mock for the initialiser collaborator. For example:
public class MyClass {
public MyClass(MyClassInitialiser initialiser) {
initialiser.initialize();
}
public void DoSomething() {
//Some code which depends on the database tables being created
}
public void DoSomethingElse() {
//Some other code which depends on the database tables being created
}
}
Or an alternative solution, the idea here is that you're breaking the single responsibility principle in MyClass. There is non-trivial initialisation behaviour (installing database tables) and behaviour on those tables in the same class. So you should separate those responsibilities into two different classes and pass one in as a collaborator to the other.
public class MyClass {
DatabaseCollaborator collaborator;
public MyClass(DatabaseCollaborator collaborator) {
this.collaborator = collaborator;
}
public void DoSomething() {
//Some code which depends on the database tables being created
collaborator.someMethod();
}
public void DoSomethingElse() {
//Some other code which depends on the database tables being created
collaborator.anotherMethod();
}
}
public class DatabaseCollaborator {
DatabaseConfig config;
public DatabaseCollaborator(DatabaseConfig config) {
this.config = config;
}
public void someMethod() {
}
public void anotherMethod() {
}
}
public class DatabaseConfig {
public DatabaseConfig() {
// initialize
}
}
When I want a class whose instances must be initialized exactly once but I want to defer initialization until right before it's necessary (at which point the caller may fail to call an Initialize function, find it inconvenient to do so, or etc.), I do it similar to how you've started out with your code, but I make the initialization method private and name it something like "EnsureInitialized". It uses a flag to track and early exit if initialization has already been done, and all functions which depend on initialization already having happened just call that function as their first line (after argument-checking).
If I expect the caller to control when this instance's initialization is done, I make the method public, name it "Init", track whether it has been run with a flag, handle idempotence or max-run-once inside the Init method however is appropriate for that class, and all methods which depend on Init having already been run will call a different, private method named "AssertIsInitialized" which will throw an exception with text like "Must call init on {class name} instance before using this function".
My goal with these different patterns is to be unambiguous about each method's expectations and operation regarding initialization within the class instance lifecycle, and provide discoverability (of the design or code bugs using it) and automatic behavior (in the case of the self-initializing class in my first paragraph) wherever I think each is most appropriate to what the rest of the application is doing.

How do I substitute Guice modules with fake test modules for unit tests?

Here's how we are using Guice in a new application:
public class ObjectFactory {
private static final ObjectFactory instance = new ObjectFactory();
private final Injector injector;
private ObjectFactory() throws RuntimeException {
this.injector = Guice.createInjector(new Module1());
}
public static final ObjectFactory getInstance() {
return instance;
}
public TaskExecutor getTaskExecutor() {
return injector.getInstance(TaskExecutor.class);
}
}
Module1 defines how the TaskExecutor needs to be constructed.
In the code we use ObjectFactory.getInstance().getTaskExecutor() to obtain and the instance of TaskExecutor.
In unit tests we want to be able to replace this with a FakeTaskExecutor essentially we want to get an instance of FakeTaskExecutor when ObjectFactory.getInstance().getTaskExecutor() is called.
I was thinking of implementing a FakeModule which would be used by the injector instead of the Module1.
In Spring, we would just use the #Autowired annotation and then define separate beans for Test and Production code and run our tests with the Spring4JunitRunner; we're trying to do something similar with Guice.
Okay, first things first: You don't appear to be using Guice the way it is intended. Generally speaking, you want to use Guice.createInjector() to start up your entire application, and let it create all the constructor arguments for you without ever calling new.
A typical use case might be something like this:
public class Foo {
private final TaskExecutor executor;
#Inject
public Foo(TaskExecutor executor) {
this.executor = executor;
}
}
This works because the instances of Foo are themselves injected, all the way up the Object Graph. See: Getting started
With dependency injection, objects accept dependencies in their constructors. To construct an object, you first build its dependencies. But to build each dependency, you need its dependencies, and so on. So when you build an object, you really need to build an object graph.
Building object graphs by hand is labour intensive, error prone, and makes testing difficult. Instead, Guice can build the object graph for you. But first, Guice needs to be configured to build the graph exactly as you want it.
So, typically, you don't create a Singleton pattern and put the injector into it, because you should rarely call Guice.createInstance outside of your main class; let the injector do all the work for you.
All that being said, to solve the problem you're actually asking about, you want to use Jukito.
The combined power of JUnit, Guice and Mockito. Plus it sounds like a cool martial art.
Let's go back to the use case I've described above. In Jukito, you would write FooTest like this:
#RunWith(JukitoRunner.class)
public class FooTest {
public static class Module extends JukitoModule {
#Override
protected void configureTest() {
bindMock(TaskExecutor.class).in(TestSingleton.class);
}
}
#Test
public void testSomething(Foo foo, TaskExecutor executor) {
foo.doSomething();
verify(executor, times(2)).someMethod(eq("Hello World"));
}
}
This will verify that your Mock object, generated by Mockito via Jukito has had the method someMethod called on it exactly two times with the String "Hello World" both times.
This is why you don't want to be generating objects with ObjectFactory in the way you describe; Jukito creates the Injector for you in its unit tests, and it would be very difficult to inject a Mock instead and you'd have to write a lot of boilerplate.

Java reflection instance with Weld-SE context

I have a problem with creating object via reflection with Weld context.
I'm loading classes and their configuration from external files.
Simplify my code looks like:
final Class<?> moduleClass = Class.forName(properties.getProperty("className"));
then I'm creating instance of this class
final Constructor<?> constructor = moduleClass.getDeclaredConstructor();
module = (Module) constructor.newInstance();
Module class:
#ModuleImpl
public class ExampleModule extends AbstractModule (implements Module interface) {
#Inject
private Test test;
Module is created sucessfully, but it hasn't weld context to inject Test class. And I cannot find the correct way. I tried to make own producer but I'm not much familiar with Weld and CDI in Java SE yet.
My broken producer (I think that its totaly bad)
public class InjectionProvider {
#Produces
public Module getInsrance(Class<?> clazz) throws ReflectiveOperationException {
final Constructor<?> constructor = clazz.getDeclaredConstructor();
return (Module) constructor.newInstance();
}
}
I cannot find something about this problem, so if anyone can help me I will be glad. I really need this way of creating classes because I don't want to change my code everytime when I need change some property in Module classes.
EDITED:
I cannot make it with producers. But I found a workaround. I'm not sure if is it good solution but it works for now.
I created a singleton class with Weld context.
public class TheMightyWeld {
private static Weld weld;
private static WeldContainer weldContainer;
public static WeldContainer getThePowerOfCreation() {
if (weldContainer == null) {
weld = new Weld();
weldContainer = weld.initialize();
}
return weldContainer;
}
public static void shutdown() {
if (weld != null) {
weld.shutdown();
}
}
}
And then I can initialize my app with
TheMightyWeld.getPowerOfCreation().instance().select(FXApplicationStarter.class).get().startApplication(primaryStage, getParameters());
And later in code I can reuse it for reflection
module = (Module) TheMightyWeld.getPowerOfCreation().instance().select(moduleClass).get();
EDITED 2:
I found better a solution. I can inject weld Instance
#Inject
private Instance<Object> creator;
then I can do only this
creator.select(moduleClass).get();
I think that this is a good solution.
I don't know if I understand your question right,
specifically the part related to the class loading
vs. the code used in the producer.
I am wondering if you expect inject to work for
a object that you instanciate for yourself through
Class.forName. As the decoration of objects
through frameworks usually is done
using a modified classloader and returning
the modified or decorated object, I guess your
approach disables this decoration (dependency injection).
You not using a call to new leaving the instanciating
to the classloader rather you are using a instantiation
through reflection.
See edited post. If someone have a better solution I will be glad for it.

How to inject logger using Google Guice

Usually I define logger like this:
private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
But when using #Inject we must use non-static and non-final field, like:
#Inject
private Logger logger;
i.e. logger will be created in each instance of this class, also logger is mutable. May be exist some way to make logger static? Also how I can bind logger to certain class (I use send the class object when creating logger object from factory LoggerFactory.getLogger(MyClass.class);, how to create logger in same way using injecting ? )?
Please check the Custom Injections on Guice wiki, there is a complete Log4J example.
EDIT: You can use either a static field or a final field for your logger, but not a static final one. This is a Java limitation.
Also be wary that:
Injecting final fields is not recommended because the injected value may not be visible to other threads.
Haven't tested that but the code in the article should work fine for static fields, although you could improve it by getting rid of MembersInjector and doing all of it in the TypeListener (since a static field needs to be set only once).
Using requestStaticInjection() will force you to list all your classes in a module file - not a good idea, as you will soon forget to add one.
OTOH if you just want to support JUL you might be better of using the built-in support (as mentioned by Jeff, I assumed you didn't want a general answer, since you didn't mention JUL specifically in your question).
When designing your application for dependency injection, typically the best practice is to avoid static fields and methods as much as possible. This is so that your dependencies are clearer, and so it's easier to replace your real dependencies with other instances during tests and as your application evolves. The ideal behavior, therefore, is to avoid static methods and fields (including loggers) as much as possible.
Guice, however, does allow for marking fields static, and requesting injection of static fields when the Injector is created. The fields will need to remain mutable--final doesn't mean "final except for Guice".
public class YourClass {
#Inject static Logger logger;
/* ... */
}
public class YourModule extends AbstractModule {
#Override public void configure() {
/* YourClass.logger will work once you create your Injector. */
requestStaticInjection(YourClass.class);
}
}
Guice automatically provides java.util.logger.Logger instances for you with the class name embedded into it, but that's only because of a special case coded into Guice. If you want a special logger, as in this SO question, you'll need to investigate the Custom Injections to which Jakub linked--but if the whole goal is to centralize logger creation so you can control it in one place, you can just refactor that into a static factory outside of Guice too.
#LogToFile
public class YourClass {
private static final Logger logger = YourLoggerFactory.create(YourClass.class);
/* ... */
}
public class YourLoggerFactory {
private YourLoggerFactory { /* do not instantiate */ }
public Logger create(Class<?> clazz) {
if (clazz.getAnnotation(LogToFile.class) != null) {
return someImplementation(new File(...));
} else {
return someOtherImplementation();
}
}
}

suppress a singleton constructor in java with powermock

I'm trying to unit-test some classes that make use of a Singleton class whose constructor does some things I can't (and shouldn't) do from the unit-test environment. My ideal scenario would be to end up with the constructor completely suppressed and then stub out the other member methods that my test classes invoke. My problem is that I can't seem to get the constructor suppressed.
My understanding of a way to solve this would be something like the following:
public class MySingleton extends AbstractSingletonParent {
public final static MySingleton Only = new MySingleton();
private MySingleton(){
super(someVar); // I want the super-class constructor to not be called
//
//more code I want to avoid
}
public Object stubbedMethod() {}
}
public class ClassToBeTested {
public void SomeMethod(){
Object o = MySingleton.Only.stubbedMethod();
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest(MySingleton.class)
public class TestClass {
#Test
public void SomeTest() {
suppress(constructor(MySingleton.class));
mockStatic(MySingleton.class);
PowerMock.replay(MySingleton.class);
// invoke ClassToBeTested, etc
PowerMock.verify(MySingleton.class);
//make some assertions
}
}
Unfortunately during the createMock invocation, the MySingleton constructor is hit, and it still calls the super constructor.
Am I doing something silly? I found an example on the web doing almost exactly this, but it was using a deprecated suppressConstructor method. Despite the deprecation I tried that, too, to no avail...
Is what I'm trying to do possible? If so, what am I doing wrong?
*Edited version now works.
You need to annotate TestClass with the #PrepareForTest annotation so it has a chance to manipulate the bytecode of the singletons.
Also, the superclass ctor supression signature should include somevar's class; right now you're just suppressing the default ctor.
See the #PrepareForTest API docs. Here's a blog post with some more details as well.
FWIW, it's working for me:
#RunWith(PowerMockRunner.class)
#PrepareForTest({EvilBase.class, NicerSingleton.class})
public class TestEvil {
#Test
public void testEvil() {
suppress(constructor(EvilBase.class));
assertEquals(69, EvilBase.getInstance().theMethod());
}
#Test
public void testNice() {
suppress(constructor(EvilBase.class));
suppress(constructor(NicerSingleton.class));
assertEquals(42, NicerSingleton.getInstance().theMethod());
}
}
How about you set the instance field ('only' in your code) of your Singleton with an instance instantiated with the constructor you want (you can do all of this with the Reflection API or dp4j).
The motivating example of a dp4j publication discusses that.
I am not sure what is it that you are doing wrong. But on the design side, i can suggest you look into dependency injection i.e. DI.
For making your code testable, make use of DI. With DI you would pass the singleton class as an constructor argument to your test class. And now since you pass an argument, inside your test case you can create a custom implementation of the AbstractSingleton class and your test case should work fine.
With DI, your code will become more testable.

Categories