How to inject an event in a Singleton Bean on Start up - singleton

Good day,
Can anyone give me an advise on how to inject an event in a Singleton bean on Start up.
Here is my code. (working OK on Weld (Glassfish 3.1.2))
#Singleton
#Startup
public class SingletonBean {
#Inject #Type private Event<Event> Event;
}
But this is the error when this code is deployed on WAS 8.5.5.1
The #Inject factory encountered a problem getting the object instance #Inject java.lang.reflect.Field.event binding object. The exception message was: Api type [javax.enterprise.event.Event] is not found with the qualifiers
Qualifiers: [#javax.enterprise.inject.Any()]
for injection into
Field Injection Point, field : javax.enterprise.event.Event package.SingletonBean.event,
I guess the the Event is not injected in the singleton bean on start up.
Thanks for the help.
EDIT 1. Code for qualifier #Type added.
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({
ElementType.METHOD,
ElementType.FIELD,
ElementType.PARAMETER,
ElementType.TYPE
})
public #interface Type{}

Related

Quarkus СacheManager injection in integration test

I have a Quarkus application that makes use of caches for methods.
These methods and cache eviction got to be tested somehow preferably when Quarkus context is fully operational.
This is what I figured (PostgresContainer for reference):
#QuarkusTest
class ScreeningRepositorySpec : PostgresContainer() {
private val cacheManager = CaffeineCacheSupplier().get()
init {
"test cache manager gets initialized" {
logger().info("Cache size: {}", cacheManager.size)
}
}
}
The problem arises when any kind of invocation happens for cacheManager: it fires NPE. https://github.com/im-infamou5/quarkus-cache-playground
Downstream code as follows is
#Override
public List<CaffeineCache> get() {
CacheManager cacheManager = cacheManager();
...
}
which ultimately yields:
public static CacheManager cacheManager() {
return Arc.container().instance(CacheManager.class).get();
}
And here comes that Arc.container() is null somehow.
What else was tried:
#QuarkusIntegrationTest - no bean for injection, null for arc container
Explicit #Inject for CacheManager - yields "no bean matches injection point"
Explicit Cache definition with manual CacheManager instantiation - same issue with null arc container
Variations for #Inject for default bean injection - same things about missing injection point
Looks like CacheManager bean lifecycle issue that expects it way too early and never succeeds as a result.
I've dug into quarkus tests which have quite a workaround but still hope easier approach is available to avoid this much dependensies just to test cache properly.
Version of Quarkus is 2.7.0.
Sample project can be found here with simple type of direct injection.
Output as follows:
org.acme.GreetingResourceIT > test cache size FAILED
kotlin.UninitializedPropertyAccessException at GreetingResourceIT.kt:11
Caused by: kotlin.UninitializedPropertyAccessException at GreetingResourceIT.kt:11

CDI Injection giving different instances across request

I am attempting to use CDI injection across a JAX-RS rest request. Specifically, I have a ContainerReqeustFilter, the rest end point class and a ContainerResponseFilter. In the ContainerReqeustFilter I have a simple bean injection:
public class BeanTest {
private String content;
public String getContent() { return content; }
public void setContent(String value) { content = value; }
}
And in my ContainerRequestFilter:
#Inject BeanTest beanTest;
And in my ContainerResponseFilter I also have:
#Inject BeanTest beanTest;
However I am getting two different instances of the BeanTest bean rather than the same one which I expected. Why is this? I expected the same BeanTest instance to be reused across the request.
I've also tried the following in one class:
#Inject BeanTest beanTest;
#Inject BeanTest beanTest2;
Again, beanTest and beanTest2 are different instances.
Finally, I've also tried:
#Inject #RequestScoped BeanTest beanTest;
and
#Inject #SessionScoped BeanTest beanTest;
Neither of which changed any noticeable behavior. My ultimate goal is a reusable bean across the classes invoked during a rest service call.
I do not see any annotation on BeanTest, meaning, if you are using bean-discovery-mode=all, such beans are considered by default to be in Dependent scope. That implies that their lifecycle is tired to the bean in which they are injected, and a different bean instance is injected in every different bean it is used.
Use the correct scope (if you need application wide bean, ApplicationScope, etc)
http://docs.jboss.org/weld/reference/latest-master/en-US/html/beanscdi.html#_scope

Java EE - dependency injection into batchlet

I am having issues with dependency injection in a batchlet.
#Named
public class SimpleBatchlet extends AbstractBatchlet {
#Inject
protected StorageService storageService;
...
public String process() throws Exception {
storageService.doSomething(); // this throws a null pointer exception
}
}
#Named
public class LocalFileStorageService implements StorageService {
public void doSomething() {
}
}
I have tried putting beans.xml in both META-INF and WEB-INF and removing it, all to no avail. I also tried changing the scopes of the beans to singletons, etc. I am invoking / starting the batch job through the use of an #Schedule annotation on a method that uses BatchRuntime to start the job.
I must be missing something simple as I know this should work. The actual scope of the beans I will use may need to vary, but the point I am trying to make is that I don't believe bean scope is a problem, but some other configuration issue.
I should also note that I only have 1 implementation of StorageService.
Not clear what really is your problem (NPE on injected CDI bean?), but annotating your Batchlet #Dependent should solve the problem :
#Named
#Dependent
public class SimpleBatchlet extends AbstractBatchlet {
#Inject
protected StorageService storageService;
}
Batchlet need to be #Named and #Dependent for integration with CDI.

EJB Singleton service fails at deploy

I'm rather newbie to JBoss and annotations. I have following code example. Irrelevant details are cutted out.
#Singleton
#Startup
public class SomeBean {
#Resource
TimerService timerService;
#Inject
AnotherSingleton anotherOne;
Timer timer;
#PostConstruct
private void ejbCreate() {
timer = timerService.createIntervalTimer(0, interval, tc);
}
#Timeout
public void run() throws Exception {
}
}
#Singleton
public class AnotherSingleton {
#Inject
Repository rep;
}
There is case that when war is deploying on JBoss it fails with exception from Repository producer (service in another Jboss is not available).
Caused by: java.lang.IllegalStateException: WFLYEE0042: Failed to construct component instance
So process ends with
WFLYCTL0186: Services which failed to start: service jboss.deployment.unit."someservices-view.war".component.SomeBean.START
What options do i have?
Can i tell JBoss to don't #Inject beans on startup but when code is executed by timer?
Can i somehow catch exception?
#Schedule is out of question becaouse i need to configure Timer.
Injections are handled by the CDI specification which provides a feature to "wrap" injections as it were, like so.
#Inject
Instance<AnotherSingleton> anotherOneInstance;
This basically creates a proxy around the AnotherSingleton and you can delay obtaining an actual reference to it at the time that you need it.
AnotherSingleton anotherOne = anotherOneInstance.get();
This should allow deployment to succeed and your timer to initialize, but of course if at the moment you attempt to use anotherOne and the repository is not available, the code will still break with an exception.
Alternatively, you can always do a manual lookup through the BeanManager to not have to rely on any form of dependency injection, but that should always be a last resort as it just leads to cumbersome code.

injecting named service in JAX-RS resource by constructor with OpenEJB

I'm using OpenEJB as application server and I want to deploy a Jax-RS resource that requires some named service to be injected in its constructor.
My resource looks like :
#Singleton
#Path("/")
public class Resource {
private Service service;
#Inject
public Resource(#Named("service") Service service) {
this.service = service;
}
}
Unfortunately, OpenEJB complains because it doesn't consider my constructor to be valid because of the #Named annotation decorating the Service argument.
java.lang.RuntimeException: Resource class class test.Resource has no valid constructor
at org.apache.openejb.server.cxf.rs.CdiResourceProvider.validateConstructorExists(CdiResourceProvider.java:138)
at org.apache.openejb.server.cxf.rs.CdiResourceProvider.<init>(CdiResourceProvider.java:100)
at org.apache.openejb.server.cxf.rs.OpenEJBPerRequestPojoResourceProvider.<init>(OpenEJBPerRequestPojoResourceProvider.java:28)
at org.apache.openejb.server.cxf.rs.CxfRsHttpListener.deployApplication(CxfRsHttpListener.java:522)
The implementation of the OpenEJB CdiResourceProvider clearly doesn't want something else than the Jax-RS #Context annotation for constructor arguments...
Is it supported by OpenEJB?
JAX-RS has a specific requirement for a no-args constructor. This will be true of any JAX-RS impl, its not specific to the OpenEJB integration.