How to use two Guice modules that install a common dependency module - java

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.

Related

Java inject implementations from multiple modules using TypeLiteral

I have an issue with multiple implementations of interface, or rather with injecting them as a List.
This question is a direct follow up for question:
Java inject implementation using TypeLiteral
so I will refer havilly to those examples and refer to their solutions.
I have an interface:
public interface IImplementMe {
public String getValue();
}
and
I have multiple implementations of the IImplementMe interface from different modules of my project binded:
register(IImplementMe.class).annotatedWith(Names.named("someName")).to(SomeImplementation.class);
Everything zipped into list in module
private static class CustomTypeLiteral extends TypeLiteral<List<IImplementMe>> {
}
bind(new CustomTypeLiteral()).toRegistry();
And there are two assumptions (that makes this story different from linked question)
I do not know too much about implementations of IImplementMe, in particular if they are Singletons (I can force it if really needed)
They are binded in different modules not managed by me directly (and i don't want to bind those implementations myself)
Similarly, I want to inject a List of all of them in #Singleton class and call them whenever needed.
#Singleton
class SomeEndpoint {
#Inject
public SomeEndpoint(final List<IImplementMe> implementations){
///
}
}
And the question is: Is it guaranteed that Guice will pick up all implementations ? I know that they won't be available in constructor(the list will be empty) but after that the list should be refreshed as I understand Guice. I'm most concerned about scenario where implementations are not Singletons and they are not used anywhere else beside my class that injects List(SomeEndpoint in the example) (I'm worried that they'll never be initialized so never added to the list).
One additional thought: I'm not using Multibinder(I would like to avoid it if possible since I don't want to force other users to use it aswell, it will be a bit clearer if they could just register #Named implementation of IImplementMe it theirs modules).

Guice configure scope

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.
}
}

Is there a way to create Model here without duplicating the code?

I need to use two similar libraries one for one specific session of MVC. Means, they (their methods) won't be used simultaneously (I'll use If...Else around that specific session to choose methods of only one library at a time). The problem is:
For both libraries to work, its mandatory for my Entities (Model) to extend their classes (wished I was with C++).
They don't provide any Interface. So, I can't do multi-inheritance.
The only choice I have left: Create two different Models each for both libraries & use specific Model based on session (or being used libraries).
But, it'll duplicate the codes in Models. At this time there's no need to sync data between them due to use of persistent storage between MVC sessions. But still, duplicate code is a big headache to manage. Is there a way to avoid this?
You could create Adapters for each specific libraray. This would keep your own code clean from the other libraries.
Also you should consider using the Strategy Pattern for switching between both libraries. This becomes handy when the code becomes more complex and you can mock the libraries in tests.
You can't get around including both libraries if that's what you're asking. You could have a few options just depends on how you want things to work.
From what I understand, you could create two classes, each extending a different library, these classes implement an Interface, override any methods you need to.
Pseudo code:
private class Lib1Adapter extends Lib1 implements LibAdapter {
// wrapper methods call lib1 methods
}
private class Lib2Adapter extends Lib2 implements LibAdapter {
// wrapper methods call lib2 methods
}
public interface LibAdapter {
// method signatures for publicly accessible methods
}
public class YourModel {
public LibAdapter la = < boolean statement > ? new Lib1Adapter() : new Lib2Adapter();
}

Exposing static methods through proxy classes

We have a Shared Utilities project, two independent SDK projects (each referring to the Utilities) and some plugin projects, each using only one of those SDKs. Shared Utilities contains some all-static classes, which need to be made visible to the plugins mentioned, but we'd like to hide the rest of its classes from them.
How we can go about resolving the issue? We'd like to keep the build process as simple as possible (we're using Ant for the build) with least possible dependencies.
Here's the options we've considered so far and why we've discarded each approach:
Second Shared Utilities project, which will be made available to the plugins - will make deployment harder.
Build 2 separate .jar-s from the Shared Utils project, one containing only the all-static utilities and the other - whatever needs to be hidden. This would make the build more complex, i.e. additional dependencies to the plugins' build scripts.
Proxy all-static classes in each of the SDKs - duplicate method definitions, but the implementation simply calls the corresponding static method from the Shared project - seems most painless, downside is we'd need to copy the Javadoc by hand. Is there a simple Javadoc tag, which would do this automatically upon generation?
Convert all-static classes to "normal" and simply create subclasses in each SDK - unnecessary (to my mind) performance overhead.
"Exposing static methods through proxy classes"
I've read your complete question and I'm not sure what is your issue exactly.
Exposing static (non-instance related) method through a proxy (instance).
What you wan't to hide from what exactly. What you want to expose to what exactly.
public class A {
private A(){} //prevent instanciation
public static void doSomething(){} //want to expose to some class, hide from other
}
To limit exposition of doSomething you can set the visibility: Controlling Access to Members of a Class.
You can also remove the static nature and use a static factory pattern to return the object like:
public class A {
private A(){}
public void doSomething(){} //want to expose to some class, hide from other
//the new A can also be set in a member variable and
//return always the same instance, if it is unmuttable it will be thread safe.
public static A getInstance(){ return new A();}
}
This can look like the "same thing" but you can now control the visibility of all method in A by controlling only the visibility of the getInstance(), the javadoc stay on A, now to control exactly how the getInstance can be access... I would have to understand exactly what you want to do.

Design Phase - Many references to same object

I am designing an application where a class named Rights is used. This class contains information about what the user can /can't do and also contains other classes like DocumentFilters.
The issue here is that I have a lot of different parts of the application getting an instance of that class through their constructor or get method, in order to be able to verify a user action before allowing it. It seems like this is bad practice (I might be wrong). Are there ways to improve this?
The way it works is having the main class of the application creating the Rights class and then creating different components and passing it to those. The components don't have instance of the main class ether.
Example code. This is repeated over several Modules.
public class ModuleA{
private Rights rights;
public ModuleA(Rights rights){
this.rights=rights;
}
private boolean verifyRights(ActionEvent e){
if(e.getSource("copyButton"){
if(rights.allowedToCopy){
return true;
}
return false;
}
}
That is a valid design and it is called Inversion of control and more specificly Dependency Injection. You can try to use an IoC container for java if you don't want to inject your dependencies manually.
It is also possible to separate the security code into aspects by using AOP. This is a more advanced option, but doing so you can separate the code that checks the security from the real business code.
If the method you showed is duplicated exactly in your Module classes, you should extract the method into a base class. This base class should then be used for all your Module classes.
public class ModuleBase
{
private Rights rights;
public ModuleA(Rights rights)
{
this.rights=rights;
}
public boolean verifyRights(ActionEvent e)
{
/// implementation
}
}
public class ModuleA : extends Bicycle
{
public ModuleA(Rights rights)
{
super(rights);
}
}
First of all I would suggest to isolate all the rights checking code into some special layer. Usually, the Facade patten is helpful here - it can check rights and then forward requests to the underlying business logic.
But this is not always possible. In this case you still have to provide classes with references to Rights instance. There are several patterns here:
Pass it to constructor/method (like you do) - still works.
Introduce Context which will store the Rights instance and make it available for necessary classes. But context is really helpful when it stores many reusable instances, not only one.
Use any dependency injection framework.
Hope this helps.

Categories