FileNotFoundException in a testing a Maven module - spring

I'm working on a recently mavenized legacy project with following multi-modular structure:
Parent:
Web
Service
Dao
("Service" module is dependent on "Dao" module)
Problem: some tests of Service classes call DAO code that creates beans using Spring's ClassPathXmlApplicationContext (this part is not really DAOs but caching related). Since, ClassPathXmlApplicationContext uses spring config xml of the DAO module - the Service tests fail throwing FileNotFoundException. I think this is because tests run in Service module and the spring config xml being referred lies in Dao module.
Please advise on how can I resolve the above issue in tests referring to code/resources of other modules?

Put a copy of the Spring configuration under src/test/resources in the Service module. Quite often you want a different configuration for testing anyway, but also it means your tests are less dependent on configuration changes in another module.

Related

PF4J Spring - not able to load any components in the plugin other than the beans declared in configuration class

We are using plugin architecture for one of our projects and we decided to use Spring pf4j for the same.
When we load the plugin via extensions - the application context is not able to find the beans created using #component in the plugin project- but the beans declared in #configuration classes are injected properly when we configure the plugin using register method - Is there anyway to scan and load the spring components in the plugin?
#Component in plugin is registered to main ApplicationContext via SpringExtensionFactory, make sure you set it up correctly in DefaultPluginManager correctly.
If you are going to use pf4j in SpringBoot, I would suggest you take a look sbp project. It is built upon pf4j and provides better integration with SpringBoot.

Dynamic loading of spring bean from jar along with dependent beans

I am running a spring application.
My requirement is user will be placing a plugin jar file at run time at designated lib folder location.
This plugin jar file will have spring application context file as well. I want to load this jar, means all the classes - spring beans
and all its dependent beans/components(this is important), from this jar file at run time.
I do not want to create new/child application context and want to use the existing spring bean context loaded at application start up.
I reffered to few other similar threads/questions on SO and could resolve the issue of dynamically loading of spring beans.
But i am not able to resolve issue of loading all the dependent beans for the spring beans.
Could you please provide any pointers/hints to dynamically load all the dependent beans of spring bean(which is also)loaded at run time?
Thanks in advance,
Picku
If you want to be able to load the plugin after startup you are not going to get away with not creating another application context as a child.
I'd suggest you do exactly this and then create some hooks in parent context whereby your plugin will integrate itself.
The alternative is to include that plugin.jar in the main classpath and then restart the application to include the plugin.

Prevent SpringBoot from creating an EmbeddedServletContainer

I'm trying to convert an existing spring application into a spring boot application. this application is not a web application but somewhere deep in it's maven dependencies hierarchy it includes a spring-web jar and therefore spring-boot tries to autoconfigure a WebEnvironment and in turn complains about not finding an EmbeddedServletContainerFactory. But this is intended as I'm using spring-boot-starter instead of spring-boot-starter-web.
My questing is: how can I prevent spring-boot from autodiscovering web specific items in the classpath? I already tried something like
#EnableAutoConfiguration(exclude = { EmbeddedServletContainerAutoConfiguration.class })
but it doesn't seem to work. Debugging the startup process I see that it runs into a method called deduceWebEnvironment() which is called unconditionally. This method returns true as soon as the following classes are on the classpath:
javax.servlet.Servlet, org.springframework.web.context.ConfigurableWebApplicationContext
But again, even this classes exist in the cp, I don't want to startup a web-application.
Try new SpringApplicationBuilder(YourApp.class).setWebEnvironment(false).run(args) You can also disable the web mode via configuration in application.properties
spring.main.web-environment=false
See the documentation

Classloader issue on Mule server

I am running my application on mule server. Mule server has there own sets of jars and my application that is running on mule server also has few jars. While working on Spring batch I found that JettisonMappedXmlDriver class exists in my application xstream jar as well as mule server jar as well. This class internally refer MappedXMLOutputFactory class that is in jettision jar which is also in my application but some how I am getting classnotfound error for MappedXMLOutputFactory class. This looks like class-loader issue.
If I add jettision jar in mule server then everything work fine but, I can't add this jar on my production environment. Can some body tell me how do I force to load the class from my application jettision jar file. It looks weird to me as classloader should have load MappedXMLOutputFactory class from jettision jar that is in my application folder like it is doing for other classes.
Please let me know if anybody found such issue.
The Mule application classloader is configurable: http://www.mulesoft.org/documentation/display/current/Classloader+Control+in+Mule
So just configure your application's classloader to first look at the JARs it embeds in /lib before deferring to the Mule System classloader.
You will encounter this issue if you have multiple versions of the same class in differnet jars, albeit with different method signatures. The ClassNotFound Error is usually not the only exception that occurs, you will often see another one before that, typically a "NoSuchMethodException" which forces class loader to unload the offending class.
I would suggest using maven or gradle to assemble your application and then use the dependency:tree target to query version conflicts.

Structuring Spring application with decoupled modules

I am working on a webapp which uses Primefaces as a view, and I inject Spring beans from other projects into JSF Managed beans.
I have an architectural problem:
I've created separate projects(modules) for each component that I use (Business Logic, Persistence, and others) and also create separate projects with their interfaces.
I want my webApp to depend only on the interface of the Business Logic, and to inject the implementation of the BL using Spring Dependency Injection.
I want to achive this recursively: Business logic to depend only on other interfaces, and to inject implementations using spring.
The problem is that having no dependency in the Maven pom file to the actual implementations, when I deploy the application (on a web logic server) the implementation jars are not deployed, and Spring doesn't find the beans to wire.
Is there a way to achieve decoupling without adding dependencies to actual implementations?
Can I include Spring's bean configuration files from other projects if the projects are not added as dependencies?
Did I figured this decoupling all wrong?
I appreciate your ideas.
Well obviously you need the dependencies in your maven pom else nothing will be included. You can add the dependencies with a scope of runtime which includes them in your final war but not during development (scope compile).
For loading the context of modules you might come-up with a naming convention and/or standard location for your files. With that you could do something like this in your web applications beans xml
<import resource="classpath*:/META-INF/spring/*-context.xml" />
This would load all files ending with -context.xml from the /META-INF/spring directory on the classpath (including jar files).

Resources