i Have a job which needs both a dao and 1 factory class
something like this
https://pastebin.com/kK7VcbW1
My question is how to inject them , i get this exception when the code reaches the dao calling getSomething in the Factory class
In the abstractDao i #Inject entityManager which i get from an #ApplicationScoped EnttityManagerProducer its getEntityManager is #RequestScoped
org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped
at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:691)
at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:89)
at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:164)
at org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63)
at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:83)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:99)
at org.jboss.weldx.persistence.EntityManager$1070085530$Proxy$_$$_WeldClientProxy.createQuery(Unknown Source)
at com.org.dao.impl.ConcreteDAOImpl.getByName(ConcreteDAOImpl.java:18)
at com.org.dao.impl.ConcreteDAOImp$Proxy$_$$_WeldClientProxy.getByName(Unknown Source)
at com.org.FactoryImpl.getObj(FactoryImpl.java:33)
(the real classes i replaced for the sake of the example)
I tried putting the annotations on both class and interface level i dont know which is preferrable
This type of functionality is built in out of the box with Apache Deltaspike, you can read about the scheduler module. The problem as you're aluding to is that by default, contexts are not started automatically when outside of Java EE. To do that, you need to manually start one. In CDI 2.0 this can be done by adding #ActivateRequestContext to a method/class and a request scope will be started for the duration of that method.
Prior to CDI 2.0, its platform specific. DeltaSpike solves the issue much cleaner.
Related
Well, i'm trying to use RequestedScoped beans inside a Quartz Job, see:
public class JobRoboFtp implements Job {
#Inject
private AcervoVideoService acervoVideoService;
#Inject
private ConfiguracaoService configuracaoService;
#Inject
private FtpManager ftpManager;
But i got always:
No active contexts for scope type javax.enterprise.context.RequestScoped
Well, If i change this Services to #Dependent scope everything works but i would like to use RequestedScope. There is any way ?
Since you didn't say much about versions, I am going to assume some of the latest versions of Weld 2.x (or even 3.x) - then there is a way. I also assume you are talking about SE environment, as otherwise request scope would auto-activate during requests.
If we are talking CDI 1.2 (Weld 2.x) then you need to add explicit dependency on Weld API and make use of it. The dependency is org.jboss.weld:weld-api and the functionality you are looking for is #ActivateRequestContext interceptor binding. If you are looking for a link to Weld docs, its here - note that this was added in Weld 2.4!
The principle is simple - it intercepts method calls and activated context when entering the method, then destroys it when you exit the method.
#ActivateRequestContext
public void myMethod() {
// any content in here will have request context ACTIVE
doAwesomeThings();
}
If we are talking about CDI 2.0/Weld 3.x - then the very same approach was adapted by CDI (Weld version works there as well). You can read about it here.
Env:
Wildfly 8.2.0 Final
JDK 8
Java EE 7
Please note that by 'POJO' i am referring to the classes that serve the other classes i.e other than value objects, entities.
This question was on back of my head for some time. Just wanted to put it out.
Based on CDI and Managed Beans specs and various other books/articles, its pretty clear that CDI injection starts with a 'managed' bean instance. By 'managed' i mean servlet, EJBs etc. which are managed by a container. From there, it injects POJOs (kind of crawl through layers) till every bean gets its dependencies. This all makes very sense to me and i see very little reason why developers ever need to use "new" to create an instance of their dependent POJO's.
One scenario that comes to my mind is when developer would like to have logic similar to
if(something) {
use-heavy-weight-A-instance
} else {
use-heavy-weight-B-instance
}
But, that also can be achieved via #Produces.
Here is one scenario that i verified to be true in wildfly 8.2.0 Final i.e. CDI is not able to inject bean when the JSP has
<%!
#Inject
BeanIntf bean;
%>
But, the alternative to use a servlet works fine.
That said, would like to know if there is any scenario(s) where a developer has to use 'new'. As i understand, by using 'new', developer owns the responsibility of fulfilling dependencies into that bean and all its dependent beans, and their dependent beans etc..
Thanks in advance,
Rakesh
When using CDI or other container you don't use new, because you expect a bunch of service coming from the container.
For CDI these main services are:
Injection of dependent beans (get existing instance or create a new
instance)
Lifecycle callback management (#PostConstruct and
#PreDestroy)
Lifecycle management of your instance (a #RequestScoped bean will make container produce an instance leaving until the end of request)
Applying interceptors and decorators on your instance
Registering and managing observers methods
Registering and managing producers methods
Now, on some rare occasion, you may want to add a part of these services to a class you instantiate yourself (or that another framework like JPA instantiate for you).
BeanManager bm = CDI.current().getBeanManager();
AnnotatedType<MyClass> type = bm.createAnnotatedType(MyClass.class);
InjectionTarget<MyClass> it = bm.getInjectionTargetFactory(type).createInjectionTarget(null);
CreationalContext<MyClass> ctx = bm.createCreationalContext(null);
MyClass pojo = new MyClass();
injectionTarget.inject(instance, ctx); // will try to satisfied injection points
injectionTarget.postConstruct(instance); // will call #PostConstruct
With this code you can instantiate your own MyClass containing injection points (#Inject) and lifecycle callbacks (#PostConstruct) and having these two services honored by the container.
This feature is used by 3rd party frameworks needing a basic integration with CDI.
The Unmanaged class handle this for you, but still prevent you to do the instantiation ;).
I am trying to integrate the Activiti-BPM Framework into a Java EE Webapplication.
The main goal at the Moment is, to inject an EJB as DelegateExpression into a Servicetask (to handle Database operations).
I read that Activiti does not (yet) work with EJBs, so i annotated the class like this:
#Named
#LocalBean
#Stateless
#Dependent
public class DatabaseWriter implements JavaDelegate {...}
and try to inject it in multiple ways like this:
activiti:delegateExpression="${DatabaseWriter}"
activiti:delegateExpression="DatabaseWriter"
activiti:delegateExpression="$DatabaseWriter"
respectivley to check if it is just a Bug or something:
activiti:expression="${DatabaseWriter.execute(execution)}"
In any case i get exceptions like "could not resolve DatabaseWriter, no bean foudn that implements JavaDelegate with name DatabseWriter ..."
I tested the Class itself - by not using cdi - JPA does nto work, but the class can be instantiated by Activiti and the execute method is executed - so the class code itself is ok.
I also tried injecting the class in a JAX-RS EJB - both with CDI and #EJB - it works. The problem definetly lies with my way of trying to bring it into Activiti.
I also made a Screenshot of the Problem (all code, xml, and a logmessage) for better understanding, if it helps:
http://s29.postimg.org/tmiknudjb/problem.jpg
Thanks for help or tipps!
Regards,
BillDoor
From the Oracle documentation
Annotating the boundary (Cart) with the #Named annotation makes the
Cart immediately visible for expression language (EL) expressions in
JSP and JSF. This #Named annotation takes the simple name of the
annotated class, puts the first character in lowercase, and exposes it
directly to the JSF pages (or JSP).
Activiti uses same expression language(EL) so my guess is to you try with;
activiti:delegateExpression="${databaseWriter}"
Also, I nevered use EJB and Activiti so I'm just guessing, but upper example is how it works with Spring.
Hope it helps.
I have a bunch of dependencies written as fast binary web services (aka Ejb3.1). Here is the service delcaration:
#Remote
public interface MyService {...}
You would inject an EJB into a servlet or managed bean with the following syntax:
#EJB
MyService myService;
I don't want to use the #EJB injection however. I'd like to use plain vanilla CDI:
#Inject
MyService myService;
One way to accomplish this would be to Create a #Produces method for every EJB:
#Produces MyService produceMyService(InjectionPoint ijp){
//jndi lookup for MyService interface
}
However, InjectionPoint is capable of giving you all the information you need, such as the target class name (MyService in this case).
Is there a way in CDI to do something like this? I'd want to call this producer last, if the required injection point couldn't be fulfilled in any other manner.
#Produces Object produce(InjectionPoint ijp){
Class ejbInterface = ijp.getType();
//jndi lookup for ejbInterface
}
This is a confusing post, so ask clarification questions. Thanks a ton!
Assuming that I understood your question (see comment): No, there is no API for this.
Good news is that there is a way to achieve this - but you probably don't want to do this at runtime, that's rather a task for application startup.
The CDI extension mechanism offers you some well defined hooks into bean processing at container startup. This is a perfect place for logic that decides about enabling / disabling of certain managed beans (probably based on static classpath information).
Have a look at function and implementation of Seam Solder's #Requires. That should be pretty close to your use case...
I'm working on a Java EE application, primarily JAX-RS with a JSF admin console, that uses CDI/Weld for dependency injection with javax.enterprise.context.ApplicationScoped objects. Minor debugging issues aside, CDI has worked beautifully for this project.
Now I need some very coarse-grained control over CDI-injected object lifecycles. I need the ability to:
Remove an injected object from the application context, or
Destroy/delete/clear/reset/remove the entire application context, or
Define my own #ScopeType and implementing Context in which I could provide methods to perform one of the two above tasks.
I'm fully aware that this is across, if not against, the grain of CDI and dependency injection in general. I just want to know
Is this remotely possible?
If yes, what is the easiest/simplest/quickest/foolproofiest way to get the job done?
Weld Reference Documentation Section 2.1.2
Keep in mind that once a bean is bound
to a context, it remains in that
context until the context is
destroyed. There is no way to manually
remove a bean from a context. If you
don't want the bean to sit in the
session indefinitely, consider using
another scope with a shorted lifespan,
such as the request or conversation
scope.
Custom scope example Porting the veiwscoped jsf annonation to cdi
If you really don't want to take the path of the Custom scope type.. You can use a non-portable method by using BeanManager.getContext method and cast this context in a weld AbstractSharedContext to have access to the beanstore or the cleanUp() method of the context.
Check this thread on how to get a BeanManager instance for your environment
A custom scope which might fit your needs is available at https://github.com/openknowledge/openknowledge-cdi-extensions/tree/master/openknowledge-cdi-scope/src/main/java/de/openknowledge/cdi/scope Maybe you have to adjust the implementation a bit.
Out of the box there is only the Conversation scope that gives you total control on its lifecycle. But you can create your own scope if conversation doesn't suit your needs.
Creating a scope is a tough job, but you can go to weld code and look how conversation was implemented.
In CDI 1.1 there is a javax.enterprise.context.spi.AlterableContext interface, which allows you to individually destroy a bean instance. All normal scopes (request, conversation, session) are alterable.
AlterableContext ctxConversation = (AlterableContext) beanManager.getContext(ConversationScoped.class);
for (Bean<?> bean : beanManager.getBeans(Object.class)) {
Object instance = ctxConversation.get(bean);
if (instance != null) {
ctxConversation.destroy(instance);
}
}
The beanManager here is a javax.enterprise.inject.spi.BeanManager instance. You can get it via JNDI lookup:
InitialContext.doLookup("java:comp/BeanManager");
or via CDI static method:
CDI.current().getBeanManager();
, but be aware of the issues with the static method in some Weld versions:
javax.enterprise.inject.spi.CDI implementation does not support multiple deployments;
CDI.current().getBeanManager() returns a beanmanager from a different deployment.