I am new to Guice and trying to understand the scope of configure() method in your Module class. Currently below is my application structure. It works.
class MainClass {
public static void main(String[] args) {
Injector injector = createInjector(new MainModule(param1, param2, param3));
injector = injector.createChildInjector(injector.getInstance(FuncModule.class));
}
}
FuncModule.java
class FuncModule extends AbstractModule {
#Override
public void configure() {
// Register a AWS SWF Workflow Worker
// Register a AWS SWF Activity Worker
// Instantiate WorkflowFactory class
TempWorkflowClientExternalFactory obj = new TempWorkflowClientExternalFactoryImpl(<param1>, <param2>);
bind(TempWorkflowClientExternalFactory.class).annotatedWith(Names.named("temp1")).toInstance(obj);
}
}
I am trying to understand if my configure method is doing "too much". Is the intention/scope of configure method only limited to binding? If so, where would be best place to register the workers and instantiate the factory object?
You're right to wonder whether your configure method is the right place for this type of initialization; it's a matter of judgment. Guice does have this to say: Modules should be fast and side-effect free.
But the full power of the Java language comes at a cost: it's easy to do too much in a module. It's tempting to connect to a database connection or to start an HTTP server in your Guice module. Don't do this! Doing heavy-lifting in a module poses problems:
Modules start up, but they don't shut down. Should you open a database connection in your module, you won't have any hook to close it.
Modules should be tested. If a module opens a database as a course of execution, it becomes difficult to write unit tests for it.
Modules can be overridden. Guice modules support overrides, allowing a production service to be substituted with a lightweight or test one. When the production service is created as a part of module execution, such overrides are ineffective.
A few other factors to consider:
Your Guice module is still a Java class, and can and should adhere to the Single Responsibility Principle as much as with any other class. If the construction or configuration of your dependencies is more than a screenful or two, or is hard to describe in a sentence or two, it might be time to break up the module (see install) or extract the construction/configuration to its own method or class. You've given us a hint with your commented configure sections: Maybe it's time to extract methods or classes so the code is more self-describing.
Guice is just one dependency injection framework, and is designed to require very little Guice-specific code or patterns. With JSR330-compatible annotations (#Inject) and interfaces (Provider), you should be able to replicate or replace Guice's functionality manually—or with a different framework like Spring or Dagger (2)—without much trouble. Java Module instances, however, are unique to Guice; custom initialization code that lives in a Module will need to be refactored or rewritten if you ever want to use it in a non-Guice context. This may be a good reason to separate reusable initialization code from Guice modules in the first place.
Along similar lines, as the Guice wiki mentions, you should test any nontrivial logic in your classes. Guice Modules and their configure methods are hard to test without Guice; you may find it easier to test your external construction/configuration if it's in a separate class or method.
Any initialization you do in a Module's configure method happens when you call createInjector or createChildInjector, along with all other Modules in an unspecified order. This gives you very little granularity to set up logging, defer to a background thread, catch exceptions gracefully, or otherwise control when and how the initialization happens. By extracting third-party initializer code to a separate class or method, or a Provider or #Provides method, you give yourself more flexibility about when and how it is run.
All that said, Guice definitely allows for instance bindings, and it's very common to see simple and lightweight constructor calls, initializer calls, and other instance-preparing code in Modules. Creating a whole new class for a couple of lines of trivial initialization is probably overkill.
In short, leave in simple/short/safe initialization calls, but as soon as things get complicated/long/dangerous be ready to extract the creation or initialization to give yourself more control.
P.S. Separately, though there's nothing technically wrong with obtaining a Module instance from an Injector, be aware that it is not a common pattern. At best, this violates the rule-of-thumb that you don't have access to a functioning Injector at Module configure time; at worst, you may find it hard to reason about which Injector you're actually calling, and thus which bindings you have available to you. You can keep it, but use with caution, and consider keeping things explicit by passing parent-injector-sourced dependencies as Module constructor parameters.
/** Injected child module. Get this from a parent injector. */
public class BModule extends AbstractModule {
#Inject Injector injector; // You can always inject the Injector...
#Override public void configure() {
bind(B.class).to(BImpl.class);
}
#Provides C provideC(B b) {
return new C(b);
}
#Provides D provideD() {
return new D(injector.getInstance(B.class)); // but this won't work;
// injector is the parent,
// not the one with this module.
}
}
Related
Taking a look at Guice (and Dagger) for a new project. Every Guice tutorial I have seen so far shows an injector being created at the point where the developer needs the DI to create an object instance.
A typical example seen on the web:
public static void main(String[] args) {
Injector injector = Guice.createInjector(new BasicModule());
Communication comms = injector.getInstance(Communication.class);
}
To me this defeats the purpose of the DI - everywhere an instance is required, you tie the instance to the modules which define how to build it.
Is there a way to ask Guice to create an instance of a class who's module (dependency graph) has been previously defined to Guice (eg. at application startup?).
I am using the Dropwizard.io framework so there are situations where I don't have full control over the way a class is constructed but want to be able to mock out the dependencies I reference in that class.
Exactly the same applies to Dagger - I'd appreciate examples for either/both.
Edit:
I've worked with several DI frameworks in .NET over the years, so I'm going to give an example of what I'm trying to do based on one of those.
For example, in the ASP.NET Core DI implementation, at service start-up you define the services you want the DI to be able to create. Typically you'll be asking the DI to give you an instance which is an implementation of an interface. So at start-up:
protected override void ConfigureAdditionalServices(IServiceCollection services)
{
services.AddScoped<ITransactionService, TransactionService>();
}
where IServiceCollection is the collection of services defined to the DI.
Because the DI is integrated with the ASP.NET framework, from this point on you can generally define a constructor which takes ITransactionService and the DI will provide it for you.
However, if you were using the DI in a framework which did not know about it, you'd need access to the current ServiceProvider instance, and then you could ask the DI to create your object like this:
var transactionService = ServiceProvider.GetService<ITransactionService>();
I realise that this implemeting the Service Locator anti-pattern but it still has the benefit of decoupling my code from the concrete class implementations and allowing me to mock them out for testing at application start-up.
So back to the question
So to restate my question in the light of this context, how can I request a class from Guice at some random point in my code?
What would I need to change in this code to make it work?
public class TransactionModule extends AbstractModule {
#Override
protected void configure() {
bind(TransactionServiceBase.class).to(TransactionService.class);
}
}
// At startup
Injector injector = Guice.createInjector(new TransactionModule());
// Then, somewhere in the application, to get an instance of TransactionService
TransactionServiceBase transactionService = (TransactionServiceBase)Guice.getInstance(TransactionServiceBase.class);
I think you might be misunderstanding Injector.getInstance - in the same way that your example has a public static method to start things off, even though you don't usually write the rest of your app with all public static methods (I hope), you also don't call Injector.getInstance except in a very few specific cases.
Instead, this code is just used to get things going. Another popular "get this started" is injector.injectMembers(this) - let the main() create an instance manually of whatever is the basis of your application, with #Inject-annotated members, and then just ask the now-created Injector to populate the members.
As you continue "inward" to the rest of your application, you likely will never reference the Injector instance again, but instead rely on providers, assisted inject, or just guice-created instances.
In this way, you should never care about the Injector or the exact modules that were set up for it. Only one Injector should exist over the lifetime of the app (there are essentially no exceptions to this, except perhaps if you redefine what an "app" is), and 99% of the time it is hidden from you (exceptions: where your DI meets some other DI, and needs to request an instance of something by its Class, or where you have tooling that wants to introspect the set of all declared bindings). As such, you should be able to just provide setters, constructor args, or init methods, and then can call them manually, or have any guice context create them based on their own specific modules and rules.
I think that the answer is that there is no standard/supported way to do that.
The usual assumptions is that you have as few 'injections' points as possible, ideally one, and then you specify what each class needs by making dependencies constructor arguments.
The only scenario I know well similar to what you describe here is Dagger in android apps. The way they solved it is that they store the dagger "Injector" (sorta) in a global object - the Application, and then Dagger provides a static function to retrieve that object and perform the injections.
Long story short DI frameworks don't play well with paradigms where you don't instantiate classes yourself.
And the only solution I can think of is storing your injector in some global variable and get it from there when you need it.
Static injection might help to some degree in your case
https://github.com/google/guice/wiki/Injections#static-injections
I'm working on a project that consists of four parts:
The Main project that brings everything together. This contains the public static void main(String... args) entry point.
Component A
Component B
A 3rd party Common component that both A and B refer to.
I'm using Guice for the plumbing between all four parts, and this is my problem:
In both As and Bs main Guice modules I install a module that extends one that is defined in Common. At runtime this setup fails with the following error:
A binding to common.SomeClass was already configured at common.AbstractCommonModule.configure(). [source]
The reason for this is that I'm invoking common.AbstractCommonModule.configure() twice; once by installing a subclass instance of common.AbstractCommonPrivateModule from Component A's com.a.MainModule.configure(), and a second time from Component B's com.b.MainModule.configure().
Installing just one instance of common.AbstractCommonPrivateModule in Main is not an option, because AbstractCommonPrivateModule implements a specific binder method bindComplicatedStuff(ComplicatedStuff), for which I only know the argument inside A and B, respectively.
I tried working around this whole thing by wrapping A's and B's respective main Guice modules in PrivateModules. However, this failed with the next error:
Unable to create binding for %s. It was already configured on one or more child injectors or private modules %s%n If it was in a PrivateModule, did you forget to expose the binding? [source]
In my case, A's and B's respective main Guice modules are in fact ServletModules - which apparently I can install twice from Main.
How can I get around these errors and install the AbstractCommonPrivateModule module twice?
Edit: I uploaded some example code (with explanation about some details) to GitHub
Rather than having A and B install Common, have them requireBinding()'s for the classes they need from Common. Then modules that rely on A or B will need to also install Common. This may feel a little odd, but it's actually desirable, since A and B are now less tightly-coupled to Common.
Update
The reason I am installing two ShiroWebModules is because I want the Jersey resources in the ui module to only be secured using one Shiro configuration (one that unserstands password-protecting resources), while all Jersey resources in the api module should be be secured using an entirely different Shiro configuration (one that understands only bearer tokens as an authentication mechanism).
Broadly speaking, this is intractable. A Guice Injector provides one way of doing something (generally one implementation of an interface) to the whole application; not different mechanisms per package. Your two Modules, SwsApiServletModule and SwsUiServletModule provide a number of identical bindings, and SwsModule installs them both together. In essence you're saying "Guice, please provide a bearer-token-based authentication mechanism" then immediately after saying "Guice, please provide a password-based authentication mechanism". It can only do one or the other, so rather than picking one arbitrarily, it fails-fast.
Of course, there are a number of solutions, depending on what exactly your needs are. The most common is to use binding annotations and to have the UI and API code request different annotation. That way you can install two different implementations (with different annotations) of the same interface or class.
Here's an example:
package api;
public class ApiResources {
#Inject
public ApiResources(#ApiAuthMechanism AuthMechanism auth) {
this.auth = auth;
}
}
---
package api;
public class ApiModule implements Module {
public void configure() {
bind(AuthMechanism.class).annotatedWith(ApiAuthMechanism.class)
.to(BearerTokenAuthMechanism.class);
}
}
---
package ui;
public class UiResources {
#Inject
public UiResources(#UiAuthMechanism AuthMechanism auth) {
this.auth = auth;
}
}
---
package ui;
public class UiModule implements Module {
public void configure() {
bind(AuthMechanism.class).annotatedWith(UiAuthMechanism.class)
.to(PasswordAuthMechanism.class);
}
}
---
package webap;
public class WebappModule implements Module {
public void configure() {
// These modules can be installed together,
// because they don't install overlapping bindings
install(new ApiModule());
install(new UiModule());
}
}
You mention in a comment that you don't have control of the overlapping bindings being installed because they're coming from a third-party module. If that is the case (I didn't see where that was happening in your code) it's possible the third party doesn't want you doing what you're trying to do, for security reasons. For example,
simply binding the password-based mechanism might introduce vulnerabilities in the whole app. It might be worth trying to better understand how the third party intends for their modules to be used.
Another option, which isn't ideal but can work for some use cases, is to use two wholly separate Injector instances, one with each binding. Then you manually pass the instances you need to the UI and API code directly. This somewhat defeats the purpose of Guice, but it isn't always the wrong decision. Using child Injectors can make this less painful.
As an aside, your "sample code" is enormous, and probably more than 90% is unrelated to the problem. In the future please take the time to create an SSCCE that contains only the code relevant to the problem at hand. There's simply no way anyone's going to sift through 100+ Java files and 7,300+ lines of code to understand your problem. Not only will this make it easier for people who are trying to help you, but simply trying to create an SSCCE that demonstrates the problem will often be enough to help you understand and resolve it yourself.
To install the same module twice, override the .equals method in your module to refer to class rather than object equality. Guice won't install a module that is equal to one that has already been installed. This doesn't help much most of the time as you type:
install new AbstractCommonPrivateModule();
and so each object is a different instance which won't be equal to the last. Overriding the equals method gets around that:
#Override
public boolean equals(Object obj) {
return obj != null && this.getClass().equals(obj.getClass());
}
// Override hashCode as well.
#Override
public int hashCode() {
return this.getClass().hashCode();
}
However, note that this method is often incorrect.
Why not to do the above?
At this point, you're not really making use of Guice or dependency injection. Instead, you've tightly coupled the implementation of AbstractCommonPrivateModule with the implementation of B and C which install it. As mentioned by #dimo414, it seems like here the OP really wants to use two different ShiroWebModules, which is exactly what Guice is good at doing by installing those two different modules at a higher level. Likewise, higher level installs let you swap out while testing. If you actually want to swap one of the modules out at some point, Guice will again break.
This can also break if you override a module (which is another useful tool for testing).
The OP also wants to install a generic module twice. Wrapping another library's generic module adds additional risk; the original authors may have very good reasons for not implementing the above trick themselves, such as security.
I wonder, is any convenient and appropriate way to describe in Tapestry5 in AppModule some actions, which should be invoked before bind() method will run?
Of course, it is possible, to include such actions inside bind() method in top of method block. But it seems, that must be some other possibility for this.
BTW, #Startup is not eligible way for this, due in my case it uses already started services, but I need to some actions before services will be bound.
Outside of Tawus' answer; no, there's nothing you can do, short of a static code block (which is standard Java, not Tapestry related).
Sometimes I have found myself using an unnamed static block in the module class - mostly to initialize legacy services that my Tapestry services depend on. Something like:
public final class MyModule {
static {
// early set-up here
}
public static void bind(ServiceBinder binder) {
// binding here
}
}
This seems to improve the module code readability a bit, but at the same time could be somewhat difficult to set up for unit testing.
If it is a Tapestry web application, you can extend TapestryFilter and have the initialization step there. Look into the source code of TapestryFilter for inspiration. Also see TapestryAppInitializer
What is the difference between creating a new object and dependency injection? Please explain in detail.
Well, they're not exactly comparable. You will always have to create a new object by instantiating a class at some point. Dependency injection also requires creating new objects.
Dependency injection really comes into play when you want to control or verify the behavior of instances used by a class that you use or want to test. (For Test Driven Development, dependency injection is key for all but the smallest example).
Assume a class Holder which requires an object of class Handle. The traditional way to do that would be to let the Holder instance create and own it:
class Holder {
private Handle myHandle = new Handle();
public void handleIt() {
handle.handleIt();
}
}
The Holder instance creates myHandle and no one outside the class can get at it. In some cases, unit-testing being one of them, this is a problem because it is not possible to test the Holder class without creating the Handle instance which in turn might depend on many other classes and instances. This makes testing unwieldy and cumbersome.
By injecting the Handle instance, for example in the constructor, someone from the outside becomes responsible for the creation of the instance.
class Holder {
private Handle myHandle;
public Holder(Handle injectedHandle) {
myHandle = injectedHandle;
}
public void handleIt() {
handle.handleIt();
}
}
As you can see the code is almost the same, and the Handle is still private, but the Holder class now has a much loser coupling to its outside world which makes many things simpler. And when testing the Holder class a mock or stub object can be injected instead of a real instance making it possible to verify or control the interaction between the Holder, its caller and the handle.
The actual injection would take place at some other place, usually some "main" program. There are multiple frameworks that can help you do that without programming, but essentially this is the code in the "main" program:
...
private Handle myHandle = new Handle(); // Create the instance to inject
private Handler theHandler = new Handler(myHandle); // Inject the handle
...
In essence, the injection is nothing more than a fancy set method. And of course, you can implement the injection mechanism using that instead of in the constructor like the simple example above.
Of course, both create objects. The difference is in who is responsible for the creation. Is it the class that needs its dependencies or a container like Spring for example, which wires the component's dependencies? You configure the dependencies in a separate(typically XML) configuration file.
It is really a separation of concerns. The class says I need this, this, and this component to function properly. The class doesn't care how it gets its components. You plug them into the class with a separate configuration file.
To give you an example let's consider having a shopping class that needs a payment module. You don't want to hardcode which payment module will be used. To achieve this you inverse the control. You can change the used payment module with a few keystrokes in the configuration file of the container. The power is that you aren't touching any Java code.
Well,
creating a new object is as explicit as it can get - you create a new instance of the desired class.
Dependency injections is a mechanism that provides you with references where you need them.
Imagine a class that represents a connection pool to your database - you usually only have one instance of that class. Now you need to distribute that reference to all the classes that use it.
Here is where Dependency Injection comes in handy - by using a DI framework such as Spring you can define that the one instance of your pool will be injected into the classes that need it.
Your question itself is not easy to answer since the creation of an object and dependency injection can't be compared that easily...
Dependency injections adds a layer of configurability into your application. In the sense, when you hard code object construction, you need to re-build and re-deploy your app, but when you use dependency injection, you can re configure the XML and change the behavior without re-building and re-deploying. There are a large variety of use cases where this can save a lot of tie and effort.
When using an inversion-of-control container to perform dependency injection, the container creates the objects, and not the developer. This is done so that the container can "inject" these objects into other objects.
The answer to the following question may also give the answer you are looking for: Why is the new operator an anti-pattern? Well, the simple answer is that using the new operator may create a hidden, inaccessible dependency within the containing class. This makes testing the containing class more difficult because it involves testing the hidden dependency at the same time (barring MOCK frameworks of course). However, you can avoid this situation by not using the new operator and injecting the dependent object instead. This also has the following advantages:
For test purposes you can inject a different object.
The resulting containing class is more reusable because it can support different implementations of the dependent object.
I'm working with some existing code, trying to add to it and increase the unit tests for it. But running into some problems with getting the code testable.
Original Constructor:
public Info() throws Exception
{
_ServiceProperties = new ServiceProperties();
_SshProperties = new SshProperties();
}
I'm aware that this is bad, and obviously not testable. In a junit environment, this class will fail to create every time since it wont be able to find the necessary properties to construct itself. Now, I'm aware this class would be a lot more testable with the simple change of moving anything prefaced with 'new' as a parameter.
So I end up with:
New Constructor:
public Info(ServiceProperties srvProps, SshProperties sshProps) throws Exception
{
_ServiceProperties = srvProps;
_SshProperties = sshProps;
}
Which allows me to properly unit test this Info class. The problem though, is now all that work is pushed to some other class:
Some Other Class' Method:
public void useInfo() throws Exception
{
ServiceProperties srvProps = new ServiceProperties();
SshProperties sshProps = new SshProperties();
Info info = new Info(srvProprs, sshProprs);
doStuffWithInfo(info);
}
Now this method isn't testable. All I've managed to do is push off where the constructions of these Property objects are occurring, and somewhere else some piece of code is going to be stuck actually having to call "new".
Here's the rub for me: I can't figure out how to break this chain of events of simply pushing these "new" calls somewhere else. What am I missing?
Look at using a Dependency Injection framework such as Spring. This application of Inversion of Control means that each of your types can avoid the pitfall you've seen, leaving the configuration to "wire" components together.
This introduction to Spring (pdf) gives a comprehensive overview of Spring. The first chapter or two should be sufficient to explain the concepts.
Also see Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler
You have the right idea. Perhaps this will help you. I recommend you follow two rules for all your classes of significance, where "of significance" means if you don't follow the steps it will be more difficult to test, reuse, or maintain the class. Here are the rules:
never instantiate or self-acquire a dependency
always program to interfaces
You have a start at rule #1. You changed your Info class to no longer create its dependencies. By "dependency" I mean other classes, configuration data loaded from property files or whatever, etc. When you depend on how something is instantiated you are tying your class to it and making it more difficult to test, reuse and maintain. So, even if a dependency is created via a factory or a singleton, don't have your class create it. Have something else call create() or getInstance() or whatever and pass it in.
So you chose the "something else" to be the class that uses your class, and realized there is a bad smell to it. The remedy is to instead have the entry-point to your application instantiate all dependencies. In a traditional java app, this is your main() method. if you think about it, instantiating classes and hooking them up to each other, or "wiring" them together, is a special kind of logic: "application assembly" logic. Is it better to spread this logic throughout your code, or to collect it in one place to more easily maintain it? The answer is that collecting it in one place is better - not only for maintainance, but the act of doing so turns all your classes of significance into more useful and flexible components.
In your main() or equivalent of main() you should create all the objects you need, passing them into each others' setters and constructors to "wire" them together. Your unit tests would then wire them differently, passing in mock objects or similar things. The act of doing all this is called "dependency injection". After doing as I say, you will likely have a big ugly main() method. This is where a dependency injection tool can help you out and in fact make your code infinitely more flexible. The tool I would suggest when you get to this point, as others have also suggested, is Spring.
The less important rule #2 - always program to interfaces, is still very important because it eliminates all dependencies on implementation, making reuse much easier, not to mention leveraging other tools like mock object frameworks, ORM frameworks, etc. easier as well.
Even dependency injection frameworks like Spring, Guice, PicoContainer etc. need some sort of boostrap so you always have to build something up.
I would suggest you to use a provider/factory that returns a configured instance of you class. This would allow you to exit the "creation"-hierarchy.
Your constructors aren't incorrect and the problem isn't about when/where code is executed, it's about what everyone else mentioned: Dependency Injection. You need to create mock SshProperties objects to instantiate your object. The simplest way (assuming the class isn't marked as final) is to extend the class:
public class MockSshProperties extends SshProperties {
// implemented methods
}
You can you use mock frameworks like Mockito:
public class Info {
private final sshProps;
private final serviceProps;
public Info() {
this(new SshProperties(), new ServiceProperties());
}
public Info(SshProperties arg1, ServiceProperties arg2) {
this.sshProps = arg1;
this.serviceProps = arg2
}
}
public class InfoTester
{
private final static SshProperties sshProps = mock(SshProperties.class);
private final static ServiceProperties serviceProps = mock(ServiceProperties.class);
static {
when(sshProps.someGetMethod("something")).thenReturn("value");
}
public static void main(String[] args) {
Info info = new Info(sshProps, serviceProps);
//do stuff
}
}
The easiest answer is Spring. However another answer is to put your config stuff into JNDI.
Spring in some ways is a better answer, especially if you don't have anything that changes depending on environment.
You let the some-other-class have too much knowledge about the Info class and its dependencies. A dependency injection framework would use a provider class. Using generic types one can make a Provider of Info objects:
interface Provider<T> {
T get();
}
If your some-other-class take a Provider<Info> in its constructor your method would look like:
public void useInfo() throws Exception
{
Info info = infoProvider.get();
doStuffWithInfo(info);
}
This has removed construction of concrete classes from your code. Next step is to make Info into an interface to make it easier to create a mock for the specific unit-test case.
And yes, this will push and push all the object construction code further and further up. It will lead to some module that only describes how to wire things together. The "rules" for such code is that it should be free of conditional statements and loops.
I recommend reading Misko Heverys blog. All the presentations are useful and printing out the guide to writing testable code as little rulebook once you understand the rules is a good thing.