Guice PrivateModule custom implementation - java

Is there a way to provide custom binding in my own Module which will override binding from other nested PrivateModule .
More precisely:
I have a module with implementation:
void configure() {
binder().install(new PrivateModule() {
#Override
protected void configure() {
bind(IResourceSetProvider.class).to(XtextResourceSetProvider.class);
bind(XtextResourceSet.class).to(SynchronizedXtextResourceSet.class);
expose(IResourceSetProvider.class);
}
});
}
I would like to provide my custom implementation for IResourceSetProvider.class.
This is how I try to make it:
void configure(Binder binder) {
binder.bind(IResourceSetProvider.class).to(ExtXtextResourceSetProvider.class);
super.configure(binder);
}
When the IResourceSetProvider instance is injected it returns all the time XtextResourceSetProvider. Is there any way to implement my module to return ExtXtextResourceSetProvider?
Adam

Related

Java binding instance using other instance using Guice

there is a configuration file that I want to bind using Guice but the problem is I get that file using my manager class and I don't have an instance of it. To make clear, I explain on code:
public class GuiceModule extends AbstractModule {
#Override
protected void configure() {
bind(ConfigManager.class).to(SimpleConfigManager.class).asEagerSingleton(); // My manager
bind(PropertiesConfiguration.class).annotatedWith(Names.named("versionConfig")).toInstance(configManager.getResourceConfig("version.properties"));
// ^ I need an instance of SimpleConfigManager here
}
}
So, how can I create/get an instance without using the "new" keyword?
You can use something called ProvidesMethod.
public class GuiceModule extends AbstractModule {
#Override
protected void configure() {
bind(ConfigManager.class).to(SimpleConfigManager.class).asEagerSingleton();
}
#Provides
#Singleton
#Named("versionConfig")
public PropertiesConfiguration providePropertiesConfiguration(ConfigManager configManager) {
return configManager.getResourceConfig("version.properties");
}
}

Creating guice injector of another module installed inside current module

Have an interface that needs many implementations to be bound to it.
Going for the following design because of many constraints (May not seem good, please ignore the design).
Is it possible to create an injector for another module installed in current module while still running the configure() method for the current module.?
public class CurrentModule extends AbstractModule{
#Override
protected void configure() {
install(new OtherModule());
final someInterface getInstance = methodToGetInstance();
bind(SomeInterface.class).to(getInstance);
}
public SomeInterface methodToGetInstance() {
Injector injector = Guice.createInjector(new OtherModule());
return new ClassImplementingSomeInterface(injector.getInstance(dependency));
}
}
Yes, what you ask is possible with provider methods. This is how you should do it:
class CurrentModule extends AbstractModule {
#Override protected void configure() {
install(new OtherModule());
// Optional, but it's good to write it if the dependency becomes missing from OtherModule.
requireBinding(DependencyFromOtherModule.class);
}
#Singleton
#Provides SomeInterface createSomeInterface(DependencyFromOtherModule dependency) {
return new ClassImplementingSomeInterface(dependency);
}
}

Guice get multiple instances at a time

I'm new to Java and Guice, but I am searching if it is possible.
For example, if a have the interface
public interface A {
}
and multiple implementations for that, which in a Guice module would be:
#Override
protected void configure() {
bind(A.class).to(Aimpl.class);
bind(A.class).to(Bimpl.class);
}
I wanted to have something like that:
A[] implementations = injector.getInstance(A.class);
So I can use all implementations of the same interface!
You can use a MultiBinder :
In a module configuration :
#Override
protected void configure() {
Multibinder<A> aBinder = Multibinder.newSetBinder(binder(), A.class);
aBinder.addBinding().to(Aimpl.class);
aBinder.addBinding().to(Bimpl.class);
}
then, you can inject a Set of A :
public class MyConsumer {
#Inject
public MyConsumer(Set<A> instances) {
}
}
see https://github.com/google/guice/wiki/Multibindings

Override jersey resource with guice

I'm looking for a method to override jersey resources bounded with guice in GuiceServletContextListener. My code, which I'm trying to get working:
//Define Jersey resource interface
#Path("/books/{key}")
public interface BookDocument {
public BookDAO getDao();
public void setDao(BookDAO dao);
}
//Define default implementation
public class BookImpl implements Book {
#Override
public BookDAO getDao() {
return dao;
}
#Inject
#Override
public void setDao(BookDAO dao) {
this.dao = dao;
}
}
//User wants to inject his implementation, so he define it
public class BookUserImpl implements Book {
#Override
public BookDAO getDao() {
return dao;
}
#Inject
#Override
public void setDao(BookDAO dao) {
this.dao = dao;
}
}
//Inject default implementation of resource
public class ApplicationResourcesModule extends AbstractModule
{
#Override
protected void configure()
{
bind(Book).to(BookImpl);
}
}
//But user wants to inject his implementation, so he bind it in users AbstractModule
public class ApplicationResourcesModuleUser extends AbstractModule
{
#Override
protected void configure()
{
bind(Book).to(BookUserImpl);
}
}
//Bind all resources
public class JerseyGuiceConfig extends GuiceServletContextListener
{
#Override
protected Injector getInjector()
{
//Override default binding by user bindings.
return Guice.createInjector(Modules.override(new ApplicationResourcesModule()).with(new ApplicationResourcesModuleUser()), new JerseyServletModule());
}
}
But unfortunately this doesn't work, while I can't bind jersey resources in guice like interface to implementation, only bind(BookImpl.class) work's. But such binding is impossible to overwrite. If I try to override bind(BookImpl.class) with bind(BookUserImpl.class) I get an error Conflicting URI templates. The URI template /books/{key} for root resource class. while #Path should be unique. So is there any solution for my use case?
i just wan't to warn you Modules.override does not work on Guice.createInjector(Stage.PRODUCTION,...) so you should use it carefully only for Development. You should create two context listeners and somehow (trough maven profiles lets say) setup the web.xml with proper implementation.
Better to use:
//Inject default implementation of resource
public class MainModule extends AbstractModule
{
#Override
protected void configure()
{
if(currentStage().equals(Stage.PRODUCTION) {
install(new ApplicationResourcesModuleUser());
} else {
install(new ApplicationResourcesModule());
}
}
}
//Bind all resources
public class JerseyGuiceConfigPROD extends GuiceServletContextListener
{
#Override
protected Injector getInjector()
{
//Override default binding by user bindings.
return Guice.createInjector(Stage.PRODUCTION, new MainModule(), new JerseyServletModule());
}
}
public class JerseyGuiceConfigDEV extends GuiceServletContextListener
{
#Override
protected Injector getInjector()
{
//Override default binding by user bindings.
return Guice.createInjector(Stage.DEVELOPMENT, new MainModule(), new JerseyServletModule());
}
}
You can use #ImplementedBy annotation to your interface to say the default implementation should be. So, you don't have to bind it explicitly and you, if you bind it, it will override the annotation binding.
#Path("/books/{key}")
#ImplementedBy(BookImpl.class)
public interface Book {
public BookDAO getDao();
#Inject //it is enough to put the injection here, i think
public void setDao(BookDAO dao);
}
I think this problem is not related to Book and Book implementations binding, but to a binding/registering of the servlets to the Jersey container. Could you paste whole stacktrace, the guice stacktraces are verbose and very helpful.

Injecting singleton in guice module

I have written some modules with guice. These are working great.
I have also some singletons or a logger I need in my modules which I want to inject into these modules.
For example I have my JpaModule where I need my Configuration.
ConfigurationModule:
#Singleton
public class ConfigurationModule extends AbstractModule {
#Override
protected void configure() {
bind(Configuration.class).toProvider(ConfigurationProvider.class).in(Singleton.class);
}
}
JpaModule:
public class JpaDaoModule extends AbstractModule {
#Inject
Configuration config;
#Override
protected void configure() {
// ... Read config and do something
}
}
Call to Guice:
Guice.createInjector(new ConfigurationModule(), new JpaDaoModule());
How can I accomplish this? Or how can I provide the configuration to the JpaModule the guicy way?
/Kind regards
Christian
This is not possible. In the configure() method you set up your bindings. You cannot expect them to be available already. Also, modules are not eligible for injection per se. You can, however, get access to Guice-managed instances in providers or #Provides methods.
#Provides
#Named("myConfigItem")
String provideSomeConfigItem(Configuration config) {
return config.get("myConfigItem");
}

Categories

Resources