I'm currently going into a huge problem and any help would be highly appreciated.
First of all, the following is occuring in a J2EE environment and I know I shouldn't be managing a Thread myself, but unfortunately I can't change that nor use EJB. The environment is based on the Tomcat Web Container and Weld CDI manager.
My structure contains lots of RESTful services, Service layer and DAO layer implementations, and all of them are getting one another injected by using
#Inject and it works fine. The issue comes when I need to get my Service layer injected into my Run method and I get
WELD-001303 No active contexts for scope type javax.enterprise.context.RequestScoped.
I already have a method to return the desired bean with its contextual, as the following code describes:
BeanManager manager = (BeanManager) jndiContext.lookup("java:/comp/BeanManager");
Bean<T> bean = (Bean<T>) manager.getBeans(beanClass).iterator().next();
CreationalContext<?> ctx = manager.createCreationalContext(bean);
return (T) manager.getReference(bean, beanClass, ctx);
But even I use this method I get the error. So, is there any way in which I could inject my beans inside a Thread created and managed by me?
Thank you.
Sorry, but nope - this just won't work.
CDI, as it is, does not support context propagation across threads. It is bound to one thread only. Having it otherwise would present a severe overhead due to synchronization.
As a proof of my thread-bound claim above, look at Weld source code, where there is ThreadLocal<BeanStore> used as a storage for beans in given context. The class I refer to in the link is a predecessor to context implementing classes. Also note that this is not Weld-only "problem", any CDI impl out there work on the same basis.
You could activate given Context/Scope in a different thread but that means everything will be created anew and any state you had saved in your (for instance) #ApplicationScoped bean, will not propagate. Also, with some definitely not nice hacking, you might be able to access the bean store and make a copy to the other thread. That would give you a read-only access but I am not sure how to do that and if that's even worth the efforts.
Last but not least, CDI allows you to implements you own context or even supplement your version of built-in contexts. That way you would be able to provide a full-blown version of context working across threads, but there are so many challenged to it, that I am not sure it's doable/reasonable.
Related
This question already has answers here:
What is difference between singleton and prototype bean?
(9 answers)
Closed 3 years ago.
When I using spring framework to write business code, I always use the singleton scope and avoid using the prototype scope. I think there is a performance difference between prototype and singleton. Because of the prototype scope, spring creates a new instance every call. And I think it is slower than using the singleton scope. Am I right? And am I giving too many considerations to the performance?
I can relate to the question, I have been researching it recently. Construction of objects is very cheap, unless they actually do some heavy lifting in the constructor. You never think twice about constructing a bunch of lambdas in one statement. That's not the problem.
The problem is Spring's inefficiency, the way it wasn't architectured right. I have recently benchmarked Spring vs Guice. Singletons are slightly faster with Spring, but Prototypes are 20 times slower.
From code sanity point of view, you should always prefer Prototypes. Guice defaults to prototypes. javax.inject.Inject documentation defaults to prototypes. Spring lists some vague historical reasons and does Singletons.
Prototypes are safer because they cannot accidentally store state and use it in the wrong context. They cannot store "userId" from one request and use it in another, since with Prototypes, a brand new instance with clean state gets created every time. That's how I learned this pattern: we cached the wrong user context accidentally when using Singletons with RequestScoped Providers. Ouch. That mistake is important to avoid. Getting CPU is a much smaller problem.
To summarize: use Prototypes for better code, and dont use Spring if performance is very important.
Yes, you are right prototype scoped beans consumes more resources. According to the documentation:
The non-singleton prototype scope of bean deployment results in the creation of a new bean instance every time a request for that specific bean is made.
The constructor is called at each request instead of only once for a singleton scoped bean. But there is another aspect to take into account. The documentation says:
Thus, although initialization lifecycle callback methods are called on all objects regardless of scope, in the case of prototypes, configured destruction lifecycle callbacks are not called. The client code must clean up prototype-scoped objects and release expensive resources that the prototype beans hold. To get the Spring container to release resources held by prototype-scoped beans, try using a custom bean post-processor, which holds a reference to beans that need to be cleaned up.
In some respects, the Spring container’s role in regard to a prototype-scoped bean is a replacement for the Java new operator. All lifecycle management past that point must be handled by the client.
If you want to avoid an out of memory exception, you have to take care yourself of the release of all resources (such as database connections) hold by the prototype scoped beans.
Unless it's really needed, it's better to use singleton scoped beans.
I don't think you'll see any noticeable performance difference between prototypes and singletons in general in the most basic sense.
It's true that there is only one singleton bean instance in the application context, and instances of beans defined with "prototype" scope are created for every request to that bean, however, we're talking about the performance of new object creation and its very cheap these days and optimized for non-expensive objects.
However here are some caveats:
What if the Constructor of the bean calls some pretty expensive code, its not spring's fault of course, because the programmer wrote the code this way, but still, actually, some pretty expensive code will be called every time the bean is created and it can drain the performance.
Slightly more interesting: we usually don't place code like this in consturctor, instead we use "lifecyle" methods like #PostConstruct / #PreDestroy.
For Singletons spring will call the post-construct method once when it creates a singleton and after that will place the bean onto the application context.
When the application context gets closes (usually when the app shuts down) the pre-destroy method is called to free up the resources, etc.
However, with Prototype scoped beans it's not the case:
Spring creates them upon every request to the bean, then calls the post-construct method, again for every single instance of the bean it creates, then doesn't store the instance in the application context. This means that spring doesn't call at all pre-destroy methods (because it doesn't have a clue who are these objects, it doesn't really manage them after they're created).
So this can (again, not spring's fault) lead to serious performance differences between the two.
If we'll take it further, sometimes spring has to wrap the object into some sort of proxy. These proxies are usually done with java.lang.Proxy in case of interfaces or with Cglib which is based on inheritance. Now this fact alone, when we're talking about wrapping prototype-scoped beans into proxy, can become a source of the serious difference in performance because Proxies are generated in runtime and Wrapping an Object with proxy (especially with CGlib) is pretty expensive.
Maybe I'm not using the right terminology and that's why i can't find an answer, but I want to know how can I take information from a database to create beans that I can inject into the application?
Here's an example, rather than having this coded in a configuration file, I would like to possibly loop some values stored in a database and build these beans based on that:
#Bean
public CronTriggerFactoryBean cronTriggerFactoryBean() {
CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
factory.setJobDetail(jobDetailFactoryBean().getObject());
factory.setStartDelay(3000);
factory.setCronExpression("0 0/2 * 1/1 * ? *");
return factory;
}
How can I build beans like this and have them become a part of the application?
There are probably multiple ways how to achieve that, but all of them are pretty complex with a lots of pitfalls. I would say that in your example you should not create triggers as separate beans but rather have a single service to manage your schedules (and leave it out of Spring).
The thing with Spring is, that it is not designed to act as a dynamic container (like OSGi for example). This means that for example #Autowired dependencies are initialized during context startup and stays the same till the application context is destroyed.
However it is possible to construct bean definitions on the fly during initialization. Best place would be BeanFactoryPostProcessor. But this would be called during context initialization. This means you will have no other beans available (like EntityManager, DataSource, ...).
Another possibility is to somehow take advantage of context hierarchy. You can create and destroy application contexts on-the-fly. However implementing that would require deeper knowledge of Spring's internals.
Question for others: not sure if it is possible to reference initialized beans from parent context during child context initialization.
After you load the necessary bean properties from Database , use BeanDefinitionBuilder. You can refer this link
Looks like I have a huge issue which is making me quite confused on how to fix it.
I am using 4.0.3.RELEASE of Spring and created an MVC rest application. Most of the configuration is done via Java config as wrote a class WebMVCConfig which extends WebMvcConfigurerAdapter.
I have a spring bean that loads a text mining system which has some heavy lists. In a standalone application, I just load it once and everything I need to process some text I just call the process sentence method out of it. The constructor for that loads all lists once and after that it is just a matter of calling that function. The process function sometimes takes about 10 seconds, but sometimes it takes a few milliseconds to run all depends on the data.
Now, putting it on a Spring MVC application is interesting. If I set the scope to session scope for that bean: #Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) it works just great, of course takes sometime to load on my rest application.
However, eventually it will run out of the memory as sessions are never killed right away.
If I do it on request it will be the same issue.
If I do it default application scope than I have an issue with concurrent usages of that bean. One user runs well, the other crashes.
I have no idea of what to do. Although session scope seems to be the correct answer to it as the state is preserved on each call. Not only the Bean is heavy but it can take 10 seconds sometimes to perform the analysis.
I have a Java Configuration class where I inject that bean into my Service Implementation class via #Inject annotation. Wonder if the correct would be #Autowire instead.
Basically I have my datamining Bean that is injected into my services bean via #Inject. I had assigned the 2 beans to be Session beans.
Wonder if I should assign the datamining Bean as session and the service bean as application and which method to use to wire that Datamining bean. Whether I use an #Autowire annotation or something else to avoid the problems I am having.
Also, what about ScopedProxyMode? Which one should be used on this case?
The situation, again, is a Heavy Bean which can have a slow processing time (10 seconds).
Thanks,
I have some old code that basically uses singleton services inside entities to perform some tasks, and to start cleaning up thinks, I want to inject those services on entities, so at least I can break that hard dependencies for now.
I'm trying to find some place in Hibernate where I can control entities instantiation, by now I've found some possible hooks, like:
- org.hibernate.tuple.Instantiator
- org.hibernate.Interceptor
I need to control that instantiation when an object is first loaded from database, as well as when it's loaded from cache... Also, maybe a global PreLoadEvent may help, I just need to make sure that when an object is returned from Hibernate, it has all it's (service) dependencies injected (spring is already here).
Can someone please point me to where to continue the search?
You could use #Configurable annotation,
see this blog post for more info.
Well, after some testing, an instance of org.hibernate.event.PreLoadEventListener does the trick.
It gets called always, no matter where the instance came from. This way I'm not controlling instantiation, but at least I have a place to inject dependencies befor the instance is returned to client code.
Thanks all for your time!
Usually I'm using #RequestScoped or #SessionScoped (from javax.enterprise.context) to inject objects (for instance in faces beans) using #Inject.
I am also using EJBs. As I understood, a set of stateless EJB copies (pool) is used to be injected to objects. The reason there are many copies is to ensure one instance of EJB isn't accessed concurrently. When speaking about stateful EJBs (again as I understood), one instance of such is bound to concrete injection point. And they are injected using #EJB (the stateless ones too).
Frequently I can see on the web examples of using #Stateless or #Stateful in conjunction with #Scoped. What is the meaning of them?
Edit: (trying to clarify as no one responded to this moment):
I'm especially interested whether such scoped annotations change anyhow (and if they - how) moment of creation of EJB's instance.
For my understanding: if I have, #EJB annotated field, object of proper class is injected there. If such EJB is stateless, container simply take free instance from the pool of pre-created instances. Pool can be resized if necessary. It is stateless, because object isn't guaranteed to be preserved across method calls of our class (i.e. class which has field containing reference to EJB).
We can also use stateful EJB and in that case one instance is preserved during method calls. As I think, it will be simply injected once per object creation. (There is also singleton EJB, which is shared between all objects).
I can't find the purpose of #Scoped annotations for EJB here.
Edit 2:
One can use such combination of annotations if class is to be injected via EJB and DI (by #Inject) mechanisms. This is rather, however, special case and not elegant. I am asking if you know any other reasons.
Edit 3:
Please see my comment under arjan's answer.
A #Stateless or #Singleton bean may be explicitly scoped to prevent its scope being automatically modified to a scope that may be illegal. E.g. both these bean types are not allowed to be #RequestScoped. See this link for some more info: http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html/CDI.html
#Stateful makes a lot of sense to be (explicitly) scoped. Namely, without a scope you as a programmer have to take care to call the #Remove annotated method. This can be troublesome to guarantee, since such a bean is typically not used in a single method where you can call the #Remove method in a finally block. With a scope, the bean is exactly removed when the scope ends.
Furthermore, without a scope you can't always use injection to obtain a reference to a stateful bean's stub. Namely, every time the injection happens, you'll get a new instance. This is particularly troublesome when injecting a stateful bean in a request scoped (JSF) backing bean, where you have the intent to preserve the stateful bean across a couple of requests.
Then, in combination with #Named, you can also use a session bean directly as a backing bean to flatten your application layers (see e.g. http://jaxenter.com/java-ee-6-overview-35987-2.html). Obviously you want an explicit scope in that case. Now flattening your layers may not be a best practice in larger applications, but for smaller applications and/or people just beginning with Java EE there is definitely a wish to put business logic directly into the backing bean. It's then required that backing beans have access to the same kind of services (mainly transactions) that 'business beans' normally have.
Finally, Gavin King (CDI spec lead) has suggested to always use #Inject instead of #EJB. The only exception concerns remote EJBs, where #EJB is still used.
Part of the confusion around EJB and CDI is that CDI is a new component model in Java EE and still relatively new. Although they integrate fairly well with each other, they are still two different component models and not all best practices have been thought out yet. Reza Rahman (EG member, EJB book writer, and author of CDI implementation CanDI) has suggested that the EJB model could possibly be retrofitted in the future as a set of CDI services. Indeed, in Java EE 7 a step is being made by separating the transactional services from EJB and making them available via (CDI) annotations.