Not able to get bean when loading application context from jar - spring

I am loading my application context from a jar file. The jar file contains all class files of war that is been created from maven by using attachclasses=true. The war file uses <mvc:annotation-driven /> and <context:component-scan />. The components inside are annotated by #Component,#Service and #Autowired is also used. When I am doing
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("classpath*:web-controller-application.xml");
applicationContext.getBean(AccountServiceImpl.class);
It says no qualified bean of this type is found where as the same works fine as spring mvc web-application.

Related

Error when using #StepScope with Spring Batch Admin

I'm using Spring Batch Admin to launch batches from a batch module of my main project.
The batch module compile as a JAR addedstrong text in the dependency of the Spring Batch Admin project as follow:
<dependency>
<groupId>company.project</groupId>
<artifactId>project-batch</artifactId>
<version>1.10.0-SNAPSHOT</version>
</dependency>
Since I added "#StepScope" on one of my reader classes, I get the following error when deploying Spring Batch Admin
Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy71]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy71
I had the same error when running my unit test on the batch module (without Spring Batch Admin) but I resolved it using the following bean declaration in my test configuration:
<bean class="org.springframework.batch.core.scope.StepScope">
<property name="autoProxy" value="false" />
</bean>
But I don't find how to use similar declaration to prevent the error in the Spring Batch Admin project.
I tried to add the bean into a configuration on the module side or on the SBA project side but nothing seems to work.
As far as I can see this error not caused by SBA. This is usual attempt of spring to proxify your bean. Please check your class annotated with #StepScope and remove final from class definition and public method definitions.

context:component-scan in both applicationContext.xml and dispatcher-servlet.xml

I created a servlet filter which is using some Autowired fields. For making it work I declared it as DelegatingFilterProxy in web.xml . Before this filter, my enitre spring config was in dispatcher-servlet.xml but for some reason declaring bean for this filter was not working in dispacher-servlet. So, I declared it in applicationContext.xml. It started working then but Autwired fields inside filter were then throwing null. To tackle with it I moved
<context:component-scan base-package="com.myproj.abc" />
to applicationContext, filter started working then but url paths defined by my controller classes are no longer mapped. So I need to pull following two lines also in applicationContext
<mvc:default-servlet-handler />
<mvc:annotation-driven />
This solves the issue. But I was wondering is this the right place for all this code? Because Spring security and for static resources and view mapping all these code goes in dispatcher. In one of my other project I faced same issue and there I did like this, declared only following line in applicationContext
<context:component-scan base-package="com.myproj.abc" />
And in dispatcher-servlet I change component scan package to controller only and kept all other code there only(in dispatcher)
<context:component-scan base-package="com.myproj.abc.controller" />
Could anyone please enlighten me on this confusion.
Some terminology: ServletContext is the class. Servlet context is the Spring ApplicationContext for the DispatcherServlet. Application context, also know as root context is the ApplicationContext loaded by the ContextLoaderListener and stored in the web application's ServletContext. It is therefore available to other web application components.
The servlet context is loaded by the DispatcherServlet. The DispatcherServlet retrieves the application context from the ServletContext and uses it as the parent of the servlet context.
A servlet Filter is web application component that has no relation to the DispatcherServlet, ie. it doesn't know about the servlet context.
The javadoc for DelegatingFilterProxy states
Supports a "targetBeanName" filter init-param in web.xml, specifying
the name of the target bean in the Spring application context.
So the Filter bean has to be declared in the application context, not the servlet context.
Put all beans that have application scope in the application context.
Put all beans that have relevance to the MVC stack in the servlet context.
Your component-scan should scan the appropriate packages to support the two rules/suggestions above.
Further reading:
What is the difference between ApplicationContext and WebApplicationContext in Spring MVC?
Web-application context/ root application context and transaction manager setup
Difference between applicationContext.xml and spring-servlet.xml in Spring Framework

override spring bean in a jar file

I have a dao jar file that contains all the domain objects and service classes. it has a config file dao-resource.xml with id=datasource.
I am using this jar file in another project which has its own app-context.xml, but i want to override the bean with id="datasource" in the jar file
how do i do this. I tried to add a bean with same id in app-context.xml and added both files to classpathxmlapplicat.... first dao-resource.xml then app-context.xml
but that did not seem to work.
how else can i override a bean
Having spring config files in jars makes things a bit harder to manage. If you have annotated your classes it would be easier.
But anyway, I'd suggest splitting the dao xml in two parts - your beans, and infrastructure-related beans (like the datasource). Then you can include only the ones you need in your app-context.xml.
Another way would be to use primary="true" on your overriding bean. This would mean all injection points that need a bean of type DataSource, would pick your primary bean. But that won't work if you refer to your datasource in your dao xml.
So in short - you can't override a bean, so split your xml file and include only the parts you need.

Configuration to do the spring dependency injection in action class in struts 2?

i have legacy j2ee project which is using struts 2 with spring. Now when i put debugger in first method call in action
class, i find all instance variables dependecies are injected automatically. i mean where do we configure dependency
injection for action class in struts? i explored the web.xml too , i do not find any related stuff?
Does your struts configuration (struts.xml) contain an element like this?:
<constant name="struts.objectFactory" value="org.apache.struts2.spring.StrutsSpringObjectFactory" />
Read more at http://struts.apache.org/2.2.3/docs/spring-plugin.html
If Spring is beiing used to inject the Dependencies for struts2 which includes results/actions etc.that means your code must be using Struts2-Spring plugin.Struts2 by default use its own Object factor to create instances of Action classes/ Results and Interceptors etc.
In order to use Spring one need to tell Struts2 about which object creation factory to be used.for that we need to define the following entry in to either struts.xml file or struts.properties file
struts.xml
<struts>
<constant name="struts.objectFactory" value="org.apache.struts2.spring.StrutsSpringObjectFactory" />
...
</struts>
struts.properties
struts.objectFactory = org.apache.struts2.spring.StrutsSpringObjectFactory
I belive that in your web.xml you will find an entry to Spring's ContextLoaderListener which will load the applicationContext xml file from the class path.
when uusing Spring the action will be create by spring in its xml file and in the action configuration file the bean reference is being used in place of Action Class name.
So all you need to check applicationContext.xml in your Project where Action will be initiated as a prototype beans and those bean references being used in struts.xml file to defining your Struts2 Action class

How to load a spring beans which are in jar file in projects lib folder

How can I load a spring beans which are in jar file say for eg. sample.jar with all the beans declared in that jar with sample-applicationContext.xml?
Now I am using some of the beans from this jar in my project so when I deploy my ear file this sample.jar is in lib folder. Now when I deploy this project to server(jboss -5) it is not injecting the bean i have referenced in my main project.
we dont have any web app in this ear so the way we are loading beans are using ClassPathXmlApplicationContext. Can somebody gave me an example of how to load those beans from sample.jar(lib folder) first and then load those are in the project, so when spring creates beans in the main project it will have beans from sample.jar and would inject them.
Thanks
Beans are looked-up on the classpath, so if they are annotated and your have the proper component scan, they should be discovered.
If they are not annotated, but only listed in the sample-applicationContext.xml, then you can <import resource="classpath:sample-applicationContext.xml" />

Resources