Spring MVC : Asynchronous giving beancurrently in creation exception - java

I am working on a Spring-MVC application in which I want to use #Async at-least for the methods which are fire-and-forget. When I try to use #Async and I have used #EnableAsync annotation too for class, the actions inside the method are not performed. When I add task executor in servlet-context.xml, then I get an error bean is getting currently created. I am new to Async, can anyone tell me how I can use it.
I am not using Eager loading btw.
Error log :
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'groupNotesService': Bean with name 'groupNotesService' has been injected into other beans [mattachService] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.
Code :
GroupNotesServiceImpl :
#Service
#Transactional
#EnableAsync
public class GroupNotesServiceImpl implements GroupNotesService {
#Override
#Async
public void editGroupNote(GroupNotes mnotes, int msectionId) {
//Code to be executed, which is not getting executed
}
}
Servlet-context.xml :
<task:annotation-driven executor="executor" />
<task:executor id="executor" pool-size="20"/>
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<resources mapping="/resources/" location="/resources/" />
If I remove any of the mvc lines above, I get a servlet.init() threw load exception error.
Also, Is it possible to use Async where I am returning int? I checked out the Future tag, but I don't know what modifications are required.
Here is the method that returns int.
#Override
public int saveGroupNoteAndReturnId(GroupNotes mnotes, int msectionid) {
// saves note and returns its id.
}
MattachService bean :
<beans:bean id="mattachDAO"
class="com.journaldev.spring.dao.GroupAttachmentsDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
<beans:bean id="mattachService"
class="com.journaldev.spring.service.GroupAttachmentsServiceImpl">
<beans:property name="groupAttachmentsDAO" ref="mattachDAO" />
</beans:bean>
Edit
I checked out that there is a problem to run #Transactional and #Async both in one class. Jira SPR-7147. The workaround suggested there was to introduce a normal facade, and I really don't know what that means.

#EnableAsync should be in configuration, not the service itself. Since you seem to use xml configuration, check this https://stackoverflow.com/a/20127051/562721. It recommends to declare org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor to take care of #Async annotations

Related

#Async with JavaMelody #MonitoredWithSpring not working

I have problem with asynchronus execution of my code.
Method startConversion() should be called asynchronusly. call goes trought AOP proxy.
Everything separated works fine. Problem occurs when I put together #Async and #MonitoredWithSpring annotations
javamelody is defined in webxml in first xml - OK
Spring async support is defiend in xml - OK
Code works well without #MonitoredWithSpring. But i need this bean to be monitored.
Sample code:
#MonitoredWithSpring //L1 - if this line removed #async will work
public interface IOfficeConversionService {
void startConversion ();
}
Implementing class
#Service
public class COfficeConversionSevice implements IOfficeConversionService {
#Override
#Transactional
#Async ("officeFileConversionExecutor")
public void startConversion () {
//ASYNC work
}
}
With L1 present, code will call method startConversion() synchronusly.
Without L1 everything works fine, and method startConversion() is called asynchronusly in new thread
In stacktrace don't even create async pointcut.
#Async annotation is never processed by its postProcessor. #Transactional works, and transaction is created. No error in initialization
Spring configuration
<context:annotation-config />
<aop:aspectj-autoproxy />
<task:executor id="mailexecutor" pool-size="25-100" queue-capacity="1000" rejection-policy="ABORT" />
<task:executor id="pnpexecutor" pool-size="5" />
<task:executor id="officeFileConversionExecutor" pool-size="5" />
<task:scheduler id="systemScheduler" pool-size="5" />
<task:annotation-driven executor="mailexecutor" scheduler="systemScheduler"/>
Can you help me? Some suggestion ?
I am out of ideas.

How to load two ResourceBundles and inject them separately

I am using Spring for loading localized resource bundles into my application. Here is what I have done.
<bean id="systemMessages" class="o.s.c.s.ResourceBundleMessageSource">
<property name="basename" value="locale/system">
</bean>
<bean id="clientMessages" class="o.s.c.s.ResourceBundleMessageSource">
<property name="basename" value="locale/client">
</bean>
I want to load messages based on the locale in my controller, and I tried both these ways below
#Autowired
#Qualifier("clientMessages")
ResourceBundleMessageSource clientMessages;
#Resource(name="systemMessages")
ResourceBundleMessageSource systemMessages;
EDIT
The application is a JAXRS application and the injection is being tried in a Global Exception Mapper. From the comments I now understand that this class would have been created by the JAXRS container and not Spring ( Code below). How to let Spring know that this injection must work?
import javax.ws.rs.WebApplicationException;
//other imports
public class GlobalWebApplicationException extends WebApplicationException{
private String systemMessage;
private String clientMessage;
//Autowire the multiple resourcebundles
public GlobalWebApplicationException (String key, Locale locale) {
// this is where I want to use the injected object fetch the property
}
public doSomething(){
// Business Logic
}
}
But the injection is not happening and I am getting an NPE. How do I achieve this?
When using Spring and having it do auto wiring using annotations the fields cannot be null. The dependencies need to be satisfied on startup of the application. If that doesn't happen there can be 1 of 2 things wrong
You haven't enabled annotation processing
You aren't using a spring managed bean but are creating instances yourself
For the first option add <context:annotation-config /> to your application context, or if you want to do component scanning add <context:component-scan /> the latter already implies annotation processing.
For the second option you need to make your bean a spring managed bean and use that instead of creating new instances yourself.

Declaration of beans in applicationContext.xml

I have a question regarding declaration of classes in applicationContext.xml
In applicationContext.xml do we need to specify all the classes from the application?
E.g.
In my small web application I have a Entity class, Service class and DAO class. So currently it is defined as
<!-- Beans Declaration -->
<bean id="Employees"
class="net.test.model.Employees" />
<!-- User Service Declaration -->
<bean id="
EmployeeService" class="net.test.employees.service.EmployeeService">
<property name="employeesDAO" ref="EmployeeDAOImpl" />
</bean>
<!-- User DAO Declaration -->
<bean id="EmployeeDAO" class="net.test.employee.dao.EmployeeDAOImpl">
<property name="sessionFactory" ref="SessionFactory" />
</bean>
So if I have multiple entity, service and dao classes do I need to mention all those classes in applicationContext.xml?
Any insight into this is highly appreciable.
Regards
Update 1
ManagedBean
#ManagedBean(name="empMB")
#Named
#Scope("request")
public class EmployeesManagedBean implements Serializable {
and I have Inject annotation
#Inject
EmployeesService employeesService;
In EmployeesService I have annotations like
#Named
public class EmployeesService implements IEmployeesService {
#Inject
EmployeesDAO employeesDAO;
#Override
public List<Employees> getEmployees() {
return getEmployeesDAO().getEmployees();
}
and finally in applicationContext.xml I have
<context:component-scan base-package="net.test" />
Now the problem is when I run my application I am getting
java.lang.NullPointerException at
net.test.managed.bean.EmployeesManagedBean.getEmpList(EmployeesManagedBean.java:53)
What am I doing wrongly to get nullpointer exception?
In applicationContext.xml do we need to specify all the classes from
the application?
No. Declaring model classes like your net.test.model.Employees is pointless unless you need a prototype to work with, something like initializing its values, but you can do this directly in the class and just instantiate it.
So if I have multiple entity, service and dao classes do I need to
mention all those classes in applicationContext.xml?
As I explained before, entity classes no. Services and DAOs are ok because most of the time you need DAOs injected to the Services (and that's the point of DI). But of course, if you create 3 DAOs and you want them to be injected in your 3 Services, then mention them in your Spring XML Bean Definition file (what you call applicationContext.xml).
But one thing, you may want to use package scanning autodetection and annotation based config to avoid writing everything in your Bean Definition File.
The bean declaration in the application context is to register the bean in the application container.
If the bean is not registered, the container wouldn't be able to dependency inject any instance of that class, or apply interceptors to the object of the class.
So unless the reference of bean is not required for any task like intercepting it or inject it, or create default singleton object of it, there is no need to declare it in the applicationContext.xml
Hope this helps.
Ideally yes, another way can be using Spring Annotations so that you don't to add multiple entries in xml.

How to instantiate spring bean without being referenced from aop:aspect

Using Spring and Java;
I have a pointcut which works OK. Now I want to remove the pointcut and AOP from the spring and just trigger the event with an event from inside the java code but I want "myAdvice" bean still called via Spring and its properties set.
I want to get ridoff all advice things even in java code, no more advice or any trace of AOP, I already have a nice event system working. I just want to instantiate my bean via Spring.
When I remove the second code block (one starting with "aop:config") then I noticed the bean "myAdvice" is not called and instantiated anymore. How can i stil call it set its properties without referencing it from the "aop:aspect" ?
in my application context ;
<bean id="myAdvice" class="com.myclass">
<property name="name1" ref="ref1" />
<property name="name2" ref="ref2" />
</bean>
<aop:config proxy-target-class="true">
<aop:aspect id="myAspect" ref="myAdvice">
<aop:pointcut id="myPointcut" expression="execution(* com.myexcmethod" />
<aop:around pointcut-ref="myPointcut" method="invoke" />
</aop:aspect>
</aop:config>
Your configuration looks fine . Your bean should be instantiated as a singleton bean when the ApplicationContext loads up . Maybe you would want to check if you have a default-lazy-init setting which prevents eager loading of the beans.
If you want to be able to get at the bean itself, you can pass it into this function:
public static Object unwrapProxy(Object proxiedBean) throws Exception {
while(proxiedBean instanceof Advised) {
proxiedBean = ((Advised) proxiedBean).getTargetSource().getTarget();
}
return proxiedBean;
}
Note that you need to have the loop in order to ensure that you unwrap all the AOP advice.

Spring not injecting bean if it is instantiated on definition

I have a session scoped bean defined like so:
<!-- this is where the serviceImpl bean is defined -->
<import resource="classpath:META-INF/*-core-context.xml"/>
<bean id="myBean" class="com.company.Bean">
<property name="service" ref="serviceImpl"/>
</bean>
Now inside the bean I have defined a default value for the injected service like so:
public class Bean {
private Service service = new NullService();
public void setService(Service service) {
this.service = service;
}
}
What I want to do is to provide the ability to optionally inject the service and if you choose not to the Bean will use the NullService implementation which simply does nothing, not affecting the bean logic in any way.
The problem is that for some reason the serviceImpl is never injected and I always end up with the NullService implementation.
So is there some spring setting or feature which prevents it from injecting it ? Or do you have any other ideas on why this might happen ?
More info
This is the setter that spring uses to inject the service:
public void setPermissionsService(PermissionService permissionsService) {
this.permissionsService = permissionsService;
System.out.println("setting permissions service to: " + permissionsService.getClass().getName());
if (this.permissionsService instanceof NoopPermissionsServiceImpl) {
System.out.println("NULL IMPLEMENTATION");
}
else if (this.permissionsService instanceof PermissionServiceImpl) {
System.out.println("CORRECT IMPLEMENTATION");
}
else {
System.out.println("WHAT ?!?!");
}
}
It prints "WHAT ?!?!".
So it turns out spring sets it to a dynamic proxy $Proxy859. Is there a way to see the class the proxy is proxying ?
You seem to be lacking a definition for your serviceImpl bean in your configuration. Something like
<bean id="serviceImpl" class="com.company.ServiceImpl" />
The only solution I see to your problem is to reverse-engineer this a bit. Do something like that in the same spring.xml:
<bean id="myBean" class="com.company.Bean">
<property name="service" ref="testServiceImpl"/>
</bean>
<bean id="testServiceImpl" class="com.company.TestServiceImpl" />
Then implement the TestServiceImpl with simple debug messages indicating that construction and your service call is actually working. This has to work. If it does you have a problem with your original service definition. If not you have a problem in your Bean.
Try to narrow the problem to a simpler. And then work into the simpler problem.
Good luck!
Instead of using instanceof use Class.isAssignableFrom(Class)

Categories

Resources