Binding generated classes in gin - java

I am trying to dynamically generate some set of event handlers (using com.google.gwt.core.ext.Generator subclass). The whole generation process works fine, my generated handlers accepts EventBus via setter injection (#Inject annotation) and the whole idea is that these automagically generated handlers register themselves in the (injected) EventBus under the hood. The problem is that all these handlers must be somehow instantiated. GIN does not know anything about them until they will be bound in GIN module; something like below:
bind(MyDynamicallyGeneratedHandler.class).asEagerSingleton();
The problem with this code is that I have to generate gin module also (which will contain all bind(...) instructions). It works well but I cannot install generated module (#Inject it) into another not generated module so that its bind instructions are executed (as a result of install(MyDynamicModule.class)). I tried dirty tricks with static injection and providers - all without success.
Is there any way to configure dynamically generated GIN module? Or maybe is there any way to instantiate dynamically generated handlers so that setter injection (and thus event bus registration) happens?
Here is sample code snippet:
// it is standard interface
public interace DynamicHandler {
#Inject
void setEventBus(EventBus eventBus);
}
// one of dynamically generated handlers
// where (how) to instantiate me?
public class MyHandler implements DynamicHandler {
#Inject
AnotherHandlerSpecificComponent component
void setEventBus(EventBus eventBus) {
eventBus.register(...); // register myself
}
}
Important thing to note is that all these dynamically generated handlers have some other dependencies #Injected (apart from EventBus). And these dependencies (their types) ale handler-specific (AnotherHandlerSpecificComponent in the example above). So what I need to do is to instantiate these handlers in a way that triggers GIN injection (I cannot, for example, inject dependencies manually).
Thanks in advance for any clues. I am totally stucked...

How about a Factory where you inject the dependencies for the handlers and try to instantiate and register the actual handlers (e.g. by reflection or scanning the file system?)

Related

Using hystrix-javanica annotations on interfaces

I am integrating Hystrix into SilverWare microservices platform and I want to use hystrix-javanica annotations. These annotations are meant to be applied on the actual implementation of the methods that need to be executed using Hystrix. The problem is that I need to implement a generic solution where you only have a service interface. It has to be done this way in order to let developers use annotated references to other microservices (when they implement their own service) without any need to deal with the implementation of those services.
I came up with a solution where you annotate your microservice reference with something like this:
#Inject
#MicroserviceReference
#HystrixConfiguration(MyServiceHystrix.class)
private MyService myService;
And then you implement (or extend) the service interface and put Hystrix annotations on its methods:
public interface HystrixedMyService extends MyService {
#HystrixCommand
doSomething();
}
When there is #HystrixConfiguration annotation on a field in your microservice referencing another service, SilverWare will scan the class given as a parameter of this annotation and prepare a Hystrix command for every method of the service. The command will also receive a callable with an actual method invocation which will be executed in its run() method.
My question is: Is it possible to reuse some (internal) parts of hystrix-javanica so I do not need to scan all the annotations and create those Hystrix commands myself? I can see that most of the classes are designed to be used only with AOP.

creating multiple generated proxies

I have a spring application that uses rabbitmq-based RPCs. on the client side, I would like to generate a proxy object that delegates to the RPC based on annotated interfaces available on the classpath of the client. in a similar way, I want to be able to register exchanges, queues and consumers on the server side, based on annotated concrete classes.
the annotations i have are #RpcInterface and #RpcEndpoint, and I created a java proxy from the interfaces implemented by the RpcEndpoint.
My problem now is that I want to be able to scan the classpath for classes with these annotations and add beans for client- and server side to the application context based on that. The problem is that FactoryBean only allows instantiation of a single object, and BeanDefinitionRegistryPostProcessor requires me to add bean definitions, which isn't really possible, because on the client side, I might only have interface that cannot be instantiated.
Right now, I'm adding #Configuration classes with one #Beans method for each interface next to where the interfaces are defined, so if I add a dependency on the interface, i would also pull in the #Configuration. This feels like unnecessary code, if I could just have something that returns a bunch of instantiated beans rather than one single bean.
so, instead of:
#Bean
public Object createBlahBean() {
createProxyFor(MyInterface.class);
}
I would like to be able to do:
#Beans
public List<Object> createBlahBeans() {
List<Object> out = new ArrayList<>();
for(Class c : findAnnotatedInterfacesFromClasspath()) {
out.add(createProxyFor(c));
}
return out;
}
or similar. any pointers?

HK2 annotations not being handled

I'm using HK2 through Jersey, and am looking to get #Immediate services working. In the process, I notice that (as it seems) none of the annotations for my services are getting registered. E.g., after spinning up my ServiceLocator and looking at my descriptor for a service annotated with #Singleton, it is still set as #PerLookup. My code for initiating my application handler is below:
ApplicationHandler handler = new ApplicationHandler(resourceConfig, new AbstractBinder() { ... });
My binder registers a service like so:
bindAsContract(ShouldHaveSingletonScope.class);
Looking at my ServiceLocator immediately after this, I see that the scope is not being pulled from the class (still #PerLookup). Is there something additional I need to specify to tell HK2 to parse class annotations? This seems like a pretty standard use case so I must be missing something.
There is a method on ServiceLocatorUtilities called addClasses
So get access to the ServiceLocator and just do
ServiceLocatorUtilities.addClasses(locator, ShouldHaveSingletonScope.class);
The binders are very literal, and will only do what you tell it as opposed to looking at the classes directly.
This should work:
bindAsContract(ShouldHaveSingletonScope.class).in(Singleton.class);
You can either configure the locator manually using Binder
-or-
use hk2 annotations, run hk2-inhabitants-generator (see hk2 doc) which will generate META-INF/hk2-locator/default file, then you will need to create your own ComponentProvider (see jersey doc) to populate service locator from that.

Guice: how to get more than one #Provides for a type?

I'm working on a project and trying to bring two different 'data service' modules together into a web app (currently, the app is a desktop Swing app).
Each module has its own Guice (private) module. Each Guice module contains:
#Provides
#Inject
protected JPQLQuery provideJPQLQuery(EntityManager entityManager) {
return new JPAQuery(entityManager);
}
This is used later in the constructor of the classes that look things up from the db:
#Inject
public SomeClassThatLooksObjectsUpFromDatabase(Provider<JPQLQuery> queryProvider) {
this.queryProvider = queryProvider;
}
The 'queryProvider' is then able to execute queries.
Now, this works fine when only one of the Guice modules is installed, but once both are installed, I (predictably) get this error:
Unable to create binding for com.mysema.query.jpa.JPQLQuery. It was already configured on one or more child injectors or private modules
bound at ServiceOneGuiceModule.provideJPQLQuery()
bound at ServiceTwoGuiceModule.provideJPQLQuery()
Now, I understand why this is broken -- I'm saying that there's two Providers for the type JPQLQuery and Guice doesn't know which one to use.
Is there any way I can get Guice to separate these Providers? I would like to do this because each module has its own properly-configured Hibernate entities, and each has its own unique datasource (multiple databases in this project).
Ideally, it would involve something like somehow naming these providers and injecting them by their name (e.g. I could separately inject "ServiceOneJPQLQueryProvider" and "ServiceTwoJPQLQueryProvider"), but I haven't found any way of achieving anything like this.
(I suppose an alternative is to somehow configure Hibernate so it has all the different datasources it needs and then I'd only need one Provider for my queries, possibly, but that seems like a lot more work than what I'm describing above)
Have a look binding annotations, they're used to solve just the problem you've got.
They're recommended over using #Named because they are type-safe and will produce compilation errors and not runtime errors if you misspell them.
In short:
ServiceOne.java:
#BindingAnnotation #Target({ FIELD, PARAMETER, METHOD }) #Retention(RUNTIME)
public #interface ServiceOne {}
ServiceTwo.java:
#BindingAnnotation #Target({ FIELD, PARAMETER, METHOD }) #Retention(RUNTIME)
public #interface ServiceTwo {}
ServiceOneModule.java:
#Provides
#ServiceOne
#Inject
protected JPQLQuery provideJPQLQuery(EntityManager entityManager) {
return new JPAQuery(entityManager);
}
SomeClass.java:
#Inject
public SomeClassThatLooksObjectsUpFromDatabase(#ServiceOne Provider<JPQLQuery> queryProvider) {
this.queryProvider = queryProvider;
}
First of all, you're incorrect about #Named because providers are ubiquitous in Guice - in fact, when you create a binding like bind(...).to(...) or any other non-provider binding you're implicitly creating a provider. And it is just a shortcut for injecting providers when you inject objects directly - providers injection and direct injection are interchangeable in Guice (when you are not using special scopes like RequestScoped, but this is more like implementation detail of this shortcut). For example, even if you created #Provides method for JPQLQuery, you still can inject it directly, without a provider:
#Inject
public SomeClass(JPQLQuery query) {
...
}
Which approach to use depends on your requirements (do you need several fresh instances of JPQLQuery inside SomeClass methods?) and scopes in use (e.g. when scope of SomeClass is wider than that of JPQLQuery - for example, when SomeClass is singleton, and JPQLQuery is request scoped - sometimes provider usage is mandatory).
You're not getting what you want with #Named yet because you create #Named binding with #Provides, but still inject Provider<...> without annotation. It won't work because binding key consists both of injected type and (possibly absent) binding annotation, so if you have only bindings with assigned annotation but inject provider or type without annotation, Guice will fail. You should put #Named annotation onto the constructor parameter as well:
#Inject
public SomeClass(#Named("ServiceOne") Provider<JPQLQuery> queryProvider) {
...
}
This way it should work.
BTW, I strongly recommend against #Named. You'd better create separate binding annotation for each of your distinct binding for the same class, as described here. With custom annotations you won't have a chance to make a mistake in binding name when you inject it.
Also there is more advanced machinery for manipulating similar bindings. It is called private modules. However, you should rarely need it. It could be needed, for example, to create trees of objects which differ only in few bindings. This does not seem to be your case - binding annotations are your way to go.

Guice: Creating more than one object instance with different configurations

I would like to know what is the best practice for the following problem:
I want have 2 instances of some class (BlockingQueue in particular) to inject them into my other classes. Each of these instances is configured separately (in particular, they have different capacities) and they don't support automatic injection via #Inject annotation. The 2 instances are the only 2 instances of that class in the application.
Now, I know that I can use binding annotations to distinguish between the two instances and use instance binding to actually bind to a single instance. But the problem is that I also need to configure these two objects and I want to obtain configuration dependencies from Guice. What do you think would be a best way to do this?
One option is to use #Provides bindings
Create a method in your guice module that provides the dependency. You can add dependencies you need to construct the object in the method signature.
#Provides
#MyBindingAnnotation
#Singleton
BlockingQueue<String> provideBlockingQueue(MyGuiceManagedConfig config){
return new LinkedBlockingQueue<String>(config.getCapacity());
}
...and they don't support automatic injection via #Inject annotation
By the way, Guice has a feature called constructor bindings, which makes it possible to bind constructors without #Inject:
try {
binder().bind(Integer.TYPE).toInstance(10);
binder().bind(new TypeLiteral<BlockingQueue<String>>() {})
.toConstructor(LinkedBlockingQueue.class.getConstructor(Integer.TYPE));
} catch (NoSuchMethodException e) {
addError(e);
}

Categories

Resources