How can I use ApplicationContext session scoped classes from a different thread - java

Using #Async annotation I want to call a method in a different thread that has access to Session and Request scoped classes.
However when the ApplicationContext tries to get the bean the following exception is generated:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.sessionInfoClass': Scope 'session' is not active for the current thread;
I had tried extending ApplicationContextAware class to hold the main thread context.
Also I had tried the suggested solution from this question How to enable request scope in async task executor
Source coude is in Github
https://github.com/saavedrah/spring-threadSample

I have created a pull request for your repo that solves the issue.
Basically, I extended this solution also for Runnable case.
To verify it, run the ThreadSampleApplication class then hit http://localhost:8080/testAsync

Related

Spring upgrade transactional issue

I am upgrading my Spring 3 to Spring 4, and was facing issue reported in
OpenEntityManagerInViewInterceptor- No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
Now to resolve it I am putting #Transactional in my controller entry method and when I do so I am getting below exception at deployment:
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'com.sun.proxy.$Proxy47 implementing com.krawler.spring.accounting.payment.accPaymentDAO,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'com.krawler.spring.accounting.payment.accPaymentImpl' for property 'accPaymentDAOobj': no matching editors or conversion strategy found
This class only has messageSource entry for bean injection. And it is separate class from the controller.
When I remove the #Transactional from Controller method, I dont see this error.
Please let me know what can be done.

How to create a request-scoped bean manually?

I have a request-scoped bean which are used in app. Now I need to implement some predefined configuration beans. I tried both ways:
as a InitializingBean implementation
as a spring's ApplicationListener<ApplicationReadyEvent> listener
but the problem is that code within this config beans uses erquest-scoped bean and everytime I get a:
Caused by: java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread?
is there any way of simulating request?

Inject EJB into startup singleton bean

In my application, I have the following startup bean:
#Startup
#Singleton
#DependsOn("RecordAcumulator")
public class StartupBean {
private static final Logger logger = Logger.getLogger(StartupBean.class);
#Inject
RecordAcumulator recordAcumulator;
/**
* Initializes the EJB system on the post construct event
*/
#PostConstruct
public void init() {
The record accumulator is an EJB that accesses the database. The startup is intended to preload database tables into the cache.
#Stateless
public class RecordAcumulator {
When this launches, I get
Caused by: com.ibm.ws.exception.RuntimeWarning: CNTR0200E: The StartupBean singleton session bean in the EJB.jar module depends on the RecordAcumulator enterprise bean in the EJB.jar, but the target is not a singleton session bean.
I have tried many variations of this and I can't seem to get the thing to inject. My log file indicates that the RecordAcumulator EJB was bound prior to the startup bean being loaded, so I can't figure out why I can't inject the EJB into my startup.
If I remove the #DependsOn I get this:
Caused by: javax.ejb.NoSuchEJBException: An error occurred during initialization of singleton session bean bla#EJB.jar#StartupBean, resulting in the discarding of the singleton instance.; nested exception is: javax.ejb.EJBException: The #Inject java.lang.reflect.Field.recordAcumulator reference of type com.foo.bar.accum.RecordAcumulator for the StartupBean component in the EJB.jar module of the bla application cannot be resolved.
Any ideas how to pull this off?
EDIT----------
I found this link:
Controlling CDI Startup inside EJB 3.1
But the issue with that is i'm using WAS 8.5.5.0, That issue was supposed to be resolved in 8.5.0.2
From what I can see:
Remove the #DependsOn
Make your EJB #Singleton
There can be complexities with singleton EJBs, as all the traffic going through your application will go through that one instance. In your case that may not be an issue.

Override a spring scope in a child bean

I have defined a spring bean extending another bean defined as singleton. Which means this:
<bean id="aChildBean" parent="aParentBean">
<!-- ......->
</bean>
Now, I wonder if I could define the scope "request" in this bean. I know that the child bean inherits the scope of the parent, but I'm not sure that this could logically work. When I tested this, Spring spring generated the exception below:
Error creating bean with name 'aChildBean': Scope 'request' is not active for the
current thread; consider defining a scoped proxy for this bean if you intend to refer
to it from a singleton; nested exception is java.lang.IllegalStateException: No thread
bound request found: Are you referring to request attributes outside of an actual web
request, or processing a request outside of the originally receiving thread? ...
So, I wonder if I could do such action. And, if the definition of a scoped bean solve the problem ?
Thanks in advance for your answers..
Quote from documentation:
A child bean definition inherits constructor argument values, property values, and method overrides from the parent, with the option to add new values. Any initialization method, destroy method, and/or static factory method settings that you specify will override the corresponding parent settings.
The remaining settings are always taken from the child definition: depends on, autowire mode, dependency check, singleton, scope, lazy init.
So, your bean IS "request" scoped, but a "request" scope only makes sense in a web environment. See here the documentation of "request" scope.

Spring session scoped objects in #Scheduled

In spring, I have a lot of code that uses session beans defined like this:
#Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
In my webapplication all is fine, since a session scope is
available.
In my JUnit tests, all is also fine since i'm using a
WebContextTestExecutionListener (link) that registers a thread
scope for the session scope
But when a method with #Scheduled is called, I get an exception since there is no
session scope.
Now my question is: How can I register a thread scope for the session scope in my #Scheduled method?
I have tried something like this: beanFactory.registerScope("session", new SimpleThreadScope()); but that also overrides the session scope of my webapplication :(
Scheduled tasks have nothing to do with the sessionscope, the session may be even terminated by the time the scheduled task get executed. If you scheduled task requires data from the session, just pass a new object containing the data to the scheduled method.
It turned out, this question is very much related to: spring 3 scheduled task running 3 times. Since my ContextLoaderListener and DispatcherServlet were pointing at the same context config, the scopes got overridden.
#skaffman/Wesley: Thanks for your comments.

Categories

Resources