Cloning Spring Application Context in OSGi bundle - spring

I have a Spring-enabled OSGi bundle. I'd like this bundle to export a factory-type OSGi service which client software can use to create multiple instances of the application context defined in this bundle.
By default the Spring DM library bundles will automatically scan and create an instance of an application context from any Spring XML configuration found under "META_INF/spring". To avoid this I moved the Spring XML configuration files under a different folder and then tried creating the application context programmatically on demand from the factory class. Unfortunately I ran into issues with Spring schema files not being available on the bundle classpath. I really don't want to embed the required Spring jars within my bundle just to get access to those schemas.
Is there a simpler way to clone Spring application contexts under an OSGi environment?

I do not understand your problem in detail but if you just want to load the application-context from a different location than META-INF/spring you can define this in the MANIFEST.MF file using 'Spring-Context', e.g. for files in the root folder
Spring-Context: /application-context-core.xml,/application-context-osgi.xml
See the documentation for further information.

Related

Spring framework library

Can I make a library with Spring framework, and then include that library in an application that uses the Spring framework?
Yes you can make a library that uses Spring, and then include a dependency on that jar in another application created with Spring. You will want a build tool that handles dependencies, like Maven or Gradle, and probably a repository manager like Nexus or Artifactory to store artifacts that you create.
You have to make sure that the jar gets included in the component scan performed by the hosting application. See the Spring reference documentation on Importing configurations.
If the library has its own Configuration, importing the Confuguration gets it included in the component scan.
Alternatively create a marker interface in your library like this:
#ComponentScan
public interface MyLibrary {}
then in the including application have a Configuration class annotated with
#ComponentScan(basePackageClasses= { MyLibrary.class })
and the including application will scan all Components in the package hierarchy starting from the package of the marker interface.
Spring is open source so you can contribute to it. Refer to https://github.com/spring-projects/spring-framework/blob/master/CONTRIBUTING.md for more details.
Yes, any Java based applicaiton (like spring framework) can be packaged as a JAR file and published to a repository (or store it locally to start simple)
This Jar file can be included as a dependency in another Java based application (like spring framework)
To add dependencies you can either use Maven or place it in a directory and add it to local classpath for the next application to use the library.
Your library becomes a reusable library (usually a JAR file) for all other java based applications

Unable to load Spring Framework Libraries in Wildfly accessible to deployed JAR

I am writing a custom Keycloak User Storage SPI, which is JAR file. I would like to use Spring DI in the JAR. I have added Spring JARs as Modules in Keycloak's Wildfly server.
Also, not able to load Spring context as Keycloak User Storage SPI initiate from META-INF.services "org.keycloak.storage.UserStorageProviderFactory" and invokes UserStorageProviderFactory.init method.
It also doesn't read the properties file inside resources directory.
Please advise how can I make this work.
May be, there would be workaround by using .ear file with your jar wrapped into it. If you are using maven then you can reside all required spring dependencies in that pom of your jar.
For further reference, you can go to this git link which might be related to what you are doing.
https://github.com/thomasdarimont/keycloak-user-storage-provider-demo

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.

Spring mvc with maven module

Currently, I am working on a Spring MVC project and want to divide the project to smaller modules. I have been searching for the info and found this page. Although this page describes how to build multiple maven module but I think it lacks of configuration information such as: how can I load persistence.xml to my persistence module? How can I read my applicationcontext.xml in service module? In my original code, the web.xml will locate and load the persistence.xml and applicationcontext.xml, but maven module doesn't have web.xml. So do I have to build java configuration class for each module? If anyone can provide basic information of working with multiple maven modules and Spring MVC, I am really thankful for that.
Assuming that the whole purpose of creating multiple modules for your project is to isolate the code by its functional parts, then yes, you will want to have separate config files for each deployable instance. This means that the only place (outside tests) where config files/classes will exist in your project, will be in your web app. Since your web app is likely using your other modules as dependencies packaged as JARs, config files in those JARs would not be very convenient.
Note: It is possible to bake config files into your other modules, but in my experience, this only causes confusion and headaches down the road.

Initialize Spring Application Context for spring projects packaged as a jar

We have several java projects. Most of them are built with Struts 2.0 framework and few built with Spring 3.2. We want to consolidate all the back-end integration service into a separate project using spring 3.2 and import this jar file on all the projects. Here are my questions
What is the best way to initialize spring application-context for a jar based spring project? This jar is utilized by multiple web-project that are built using Struts and other non spring MVC frameworks.
I read How to package spring based library for reuse?. However, this question didn't answer on how to auto-load the application context when you a call a Service from the built spring-example.jar file.
For example. I have a WeatherService.java class in spring-framework.jar file. I want to import the spring-framework.jar file into another Struts-MVC based application and call WeatherService.java from an Action Class. I want the spring bean configuration to initiate automatically when calling the WeatherService.
You can use #Import annotation if using Java configurations or <import> tag if using XMl configs. With this approach you can reuse import one Spring context into another one.
Link to documentation:
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-java-using-import
EDIT:
If you are using maven, place your application-context.xml into src/main/resources. If not, make sure that it's on classpath.
Than if you are using XML config do
<import resource="classpath:application-config.xml"/>
or if you are using Java config do
#ImportResource("classpath:application-config.xml")

Resources