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

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" />

Related

How to add Spring dependency injection to a sub-module of a project not using Spring before

Noobish question here, but I'm struggling to make this work.
I've an old project with submodules which does not use Spring or anything, just final class and static Instance.
--- Main
------ Server
------ Business
------ Webservices
Server has a dependency with Business and Webservices.
Webservices has a dependency with Business
Server is the sub-module with the web.xml file.
I have to add a new service in Business sub-module and I want to start using Spring and dependency injection to do so, in order to start migrating the project to Spring.
(I'm not talking SpringBoot, just regular Spring).
In Business sub-module, I did:
add spring-core, spring-beans, spring-contet dependencies as well as javax.inject .
Using spring version 4.3.2
create an interface IMyService and its implementation MyServiceImpl and added the #Service annotation on the impl.
add a spring-context.xml file in src/main/resources declaring context:annotation-config and context:component-scan base-package
Then I created, in my submodule a "bridge" to try and use the Spring bean from my submodule in a non spring bean of another submodule, like described here : https://blog.jdriven.com/2015/03/using-spring-managed-bean-in-non-managed-object/
However the context never get injected.
I've tried adding in the web.xml of Server the contextConfigLocation but no dice either.
What Am I missing so that my Spring context get initialized in the Business module ?

Not able to get bean when loading application context from jar

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.

Spring autowire stops working for classes on the Tomcat classpath

Inside my library FooLibrary.jar Spring instantiates class com.example.FooImpl which has a property bars. I have lots of Bar instances also instantiated by Spring. A set of bars is autowired into FooImpl like this:
#Component
public class FooImpl {
#Inject
private Set<Bar> bars;
In a standalone application, Spring instantiates the Bar instances, instantiates the FooImpl instances, and then autowires FooImpl.bars with the set of Bars. It works.
Now I'm running the same Spring configuration in a webapp inside Tomcat. FooLibrary.jar is inside WEB-INF/lib, and everything continues to work as outlined above.
The problem is that the web app automatically compiles somes classes using JavaCompiler, which can't find its dependencies for dynamically compiling unless I place that library on the startup Tomcat path. The minute I add FooLibrary.jar to the Tomcat classpath (e.g. in in the launch configuration of Tomcat inside Eclipse, or I presume startup.sh or setclasspath.bat if running Tomcat standalone), autowire stops working.
That is, when my webapp starts up, Spring creates all the Bar instances, then instantiates FooImpl, but never autowires the set of Bars into FooImpl.bars. Any idea why?
(Does it have something to do with the Spring ContextLoaderListener being started from the webapp classloader, but the FooImpl and Bar instances coming from the Tomcat classloader, I wonder?)
Autowiring can fail due to incompatible types (e.g. classes loaded in multiple classloaders).
Since you already place the JAR in tomcat's boot classpath, it must be visible to the webapp as well without you having to place the JAR in WEB-INF/lib.
You can make the dependency scope provided to not have Maven place it in WEB-INF/lib.

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.

Can you package an ejb interceptor in a library?

And if so how do you do it?
I have got an ejb #javax.interceptor.AroundInvoke interceptor which I like to move into a library for reuse. I moved the code into a library fixed the dependencies in maven and all compiles well now. Only on deploy I get the following error message:
09.02.2011 14:19:48 com.sun.logging.LogDomains$1 log
SCHWERWIEGEND: Exception while invoking class org.glassfish.ejb.startup.EjbApplication start method
java.lang.RuntimeException: java.lang.ClassNotFoundException:
From JSR 318: Enterprise JavaBeans, Version 3.1 - EJB Core Contract and Requirements:
20.3 Packaging Requirements
The ejb-jar file or .war file must
contain, either by inclusion or by
reference, the class files of each
enterprise bean as follows:
The enterprise bean class.
The enterprise bean business interfaces, web service endpoint
interfaces, and home and com-ponent
interfaces.
Interceptor classes.
The primary key class if the bean is an entity bean.
We say that a .jar file contains a second file “by reference” if the
second file is named in the Class-Path
attribute in the Manifest file of the
referencing .jar file or is contained
(either by inclusion or by reference)
in another .jar file that is named in
the Class-Path attribute in the
Manifest file of the referencing .jar
file.
So I'd say yes, you can package the interceptor class in a library .jar file.
Check that: 1) the library actually got packaged in and deployed with the ejb-jar file; and 2) the library .jar is referenced in the Manifest file as described above.

Resources