I'm using JBoss AS 7.1 and leveraging Contexts and Dependency Injection. There is no spring involved here.
My question is how can i inject a dependency into a hazelcast MapStore implementation? Might there be a programmatic way? Any help is appreciated.
For instance
public class ClientRepositoryCache implements MapStore<Integer, ClientItem> {
#Inject
ClientRepository repository;
#Override
public ClientItem load(Integer clientNumber) {
return repository.getClientById(clientNumber);
}
}
At the moment Hazelcast supports dependency injection using only Spring. Instead you can use MapStoreFactory which gives ability to create your own MapStore instance.
See a related Hazelcast group post;
MapStore/MapLoader configuration
...
To integrate with Guice, for example, you can supply the name of a singleton MapStoreFactory implementation that is statically injected with enough information to implement newMapStore(String name, Properties properties) with Injector-aware logic.
If you use programmatic configuration, as I do, you can avoid the static injection by passing an already-injected factory to MapStoreConfig.setFactoryImplementation.
-Tim Peierls-
See also MapStoreFactory and MapStoreConfig javadocs.
https://github.com/hazelcast/hazelcast/issues/440
This works very well! Integration with CDI done with a CDI Extension.
Related
I have a Quarkus application using current versions of Vaadin Flow and Quarkus (23.2.4 and 2.13.1.Final). I want to have a VaadinServiceInitListener to check access annotations on the views (#RolesAllowed(...)) using AccessAnnotationChecker. I believe annotating the implementation with #VaadinServiceEnabled
should fix this, but I need to register it in META-INF/services/com.vaadin.flow.server.VaadinServiceInitListener to have it activated. This is how to do it when not using a dependency injection framework. Then everything works as expected and I can use AccessAnnotationChecker to see if the user has access to that view, on BeforeEnterEvent.
I also notice the message Can't find any #VaadinServiceScoped bean implementing 'I18NProvider'. Cannot use CDI beans for I18N, falling back to the default behavior. on startup. Strangely, implementing I18NProvided in a class and annotating it with #VaadinServiceEnabled and #VaadinServiceScoped makes that message go away, eg. it is recognized by CDI.
Why isn't my VaadinServiceInitListener implementation recogized? Currently it is annotated with
#VaadinServiceEnabled
#VaadinServiceScoped
#Unremovable
My pom.xml include
vaadin-quarkus-extension,
quarkus-oidc,
quarkus-keycloak-authorization,
vaadin-jandex
Instead of using a listener, you can use a CDI event.
Quarkus's dependency injection solution is based on CDI, so you can use the same events. Here's an example
public class BootstrapCustomizer {
private void onServiceInit(#Observes
ServiceInitEvent serviceInitEvent) {
serviceInitEvent.addIndexHtmlRequestListener(
this::modifyBootstrapPage);
}
private void modifyBootstrapPage(
IndexHtmlResponse response) {
response.getDocument().body().append(
"<p>By CDI add-on</p>");
}
}
More information here https://vaadin.com/docs/latest/integrations/cdi/events
I have a service that needs to use Neo4jRepository (regular repository provider by spring data).
public class SomeServiceBean<T>{
#Autowired
private Neo4jRepository<T,Long> Neo4jRepository;
}
This class will generate en error:
expected single matching bean but found 2: systemUserRepository,systemClaimRepository
The problem is that systemClaimRepository and systemUserRepository is extending Neo4jRepository<T,Long> as a bean without implementation.
Spring see systemClaimRepository and systemUserRepository as Neo4jRepository<T,Long> because they are extending it.
Is there anyway to inject Neo4jRepository<T,Long>?
Thanks
No how should this work?
You have two beans that match the interface and Spring does not know which implementation to inject.
We are facing weird injection issues in Widfly due to CDI changes. We have interface
public interface Command<I, O> {
}
and many classes implement this interface like this
public class ApproveUserRequests implements Command<ApproveUserRequestsRequest, List<String>> {
}
Application listener classes likes to get list of all classes available and uses injection like this
#Inject
private Instance<Command<I, O>> mActions;
However instance returned by mActions were always null. After debugging source found that the only way to get list of all instances is to use
#Inject
private Instance<Command<?, ?>> mActions;
Also we faced injection issues while using generic types , however using wildcard type helped us.
- See more at: https://developer.jboss.org/thread/256783#sthash.1s6tuXsR.dpuf
The rules for parameterized types have been clarified in CDI 1.2. Have look at Section 5.2.4 Assignability of raw and parameterized types of the spec.
I just started playing around with OSGi services and have the following situation. I have a project which contains 2 services. Service A requires Service B, so I tried to inject the dependent service using
#Inject
private ServiceB svc;
but the framework wont inject. If I setup the following two methods in Service A
and set these methods as "bind / undbind" in my OSGi componentA.xml the framework calls
these methods and I can use Service B in Service A.
public synchronized void bind(IServiceB service)
{
this.svc = service;
}
public synchronized void unbind(IServiceB service)
{
if (this.svc == service)
{
this.svc = null;
}
}
The question is, why does it not work with #Inject ? Sorry if this is a stupid question, I'm quite new to this whole topic. Many thanks in advance!
It looks like you are using Declarative Services, which does not support field injection or the JSR-330 annotations. Field injection has limited utility in OSGi, where services may be injected or "un-injected" at any time. Method injection is more generally useful because it gives you an opportunity to do something when this happens.
However I do urge you to use the annotations for Declarative Services. This will save you from having to write the component.xml by hand.
I am using JBoss 7.1 and Java 1.6.
I would like to integrate a Guice service with by JAX-WS endpoint. Using the interceptor pattern described by Gunnar.Morling I am able to properly instantiate the Guice modules when using a stateless bean as a webservice. However i am not able to do the same with a simple POJO annotated webservice. Is this possible has anyone found a workaround. Below is a summary of my efforts so far.
#UsesGuice #Interceptor
public class GuiceInterceptor {
#Inject
private GuiceInjectorHolderBean injectorHolder;
#AroundInvoke
public Object aroundAdvice(final InvocationContext ctx) throws Exception {
if (ctx.getTarget().getClass().isAnnotationPresent(UsesGuice.class)) {
final Injector injector = injectorHolder.getInjector();
injector.injectMembers(ctx.getTarget());
}
return ctx.proceed();
}
}
The GuiceInjectorHolderBean is the a sinlgeton bean responsible for triggering the guice wiring. The annotation class required follows
#Retention(RUNTIME)
#Target(TYPE)
#InterceptorBinding
public #interface UsesGuice {}
the JAX-WS POJO class
#UsesGuice
#WebService(serviceName = "EchoServiceService", portName = "EchoServicePort", ame = "EchoServiceImpl", targetNamespace = "lala")
public class EchoServiceImpl implements EchoService
{
#Inject
MyGuiceInjection injection;
#Override
#WebMethod
public String sayHello(final String msg)
{
return "Hello " + injection.call(msg);
}
}
Thanks in advance
Dimitri
Your Current Approach
In your code, javax.interceptor annotations #Interceptor, #InterceptorBinding and #AroundInvoke are supported by CDI and EJB standards and not by Guice. Guice uses proprietary AOP interception via org.aopalliance.intercept.MethodInterceptor interface and calling the method AbstractModule.bindInterceptor.
So you're trying to bootstrap Guice injection on your endpoint by:
using a non-Guice interceptor on the endpoint's method
within the #AroundInvoke method, programmatically invoking the Guice Injector, with injection target being the intercepted endpoint
That begs the Q, what to use for 1?
'Bootrap' Interception Mechanism for Your Current Approach
Obviously, an EJB interceptor works, as you've stated.
Other than an EJB or Guice AOP interceptor... an obvious alternative would be the standard, a CDI interceptor.
But that would make it all rather circular and heavy-weight... Why use CDI just to boostrap, so that you can configure and execute to your desired DI competitor: Guice?
Suggested Alternative Solution - JAX-WS Support for Manual Endpoint Instance Initialisation
If you want POJO web services, maybe consider back-tracking a bit, instead of interceptor-driven Guice initialisation, maybe this could be what you need:
javax.xml.ws.Endpoint.publish(String address, Object implementor)
Endpoint.publish javadoc
Initialise Guice in the standard way, use injector.getInstance() to construct your endpoint instance, and then use Endpoint.publish to set the endpoint instance against the port. The following gives a good example:
Using Guice 3 with JAX-WS in Java 6 outside web container