What is a general way to use a Spring project inside another? - spring

I have a Spring project which is a regular jar file. It uses JPA and Spring Data.
I'd like to use it in another Spring project, which is a war running in Tomcat. It also uses JPA and Spring Data.
I have installed the jar into the local maven repository, and have declared it as a dependency in the parent project.
What do I need to do to make them work together correctly?
Are there naming conventions for the various context, properties, and persistence files?
Do I need to import the library configuration files in the "parent" configuration files?
I am getting the following error when trying to run the parent:
IllegalArgumentException: Not an managed type: class [some domain class in the parent project]

Use Maven Modules. Reference here:
http://books.sonatype.com/mvnex-book/reference/multimodule.html

Related

Use entity and repository definitions from Spring Boot outside of web application

I have a Spring Boot 2.1 web application. It works great. I can package it as either a WAR or a JAR.
In my pom.xml file I use:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
This application has many entity classes and quite a few Spring Data repositories. Almost always we deploy it as a WAR file.
Here's the question: sometimes we need to do a command line or batch process on our database. For example, we might want to run a process to resize all the images which are stored in the database, and that should be run by an administrator from the command line.
It would be great if mvn install would install a JAR file in the local Maven repository and I could use that artifact in another project to access my entity and repository definitions. I've tried many things, but whenever I build my project as a JAR file, and I look at the JAR, all my classes are within BOOT-INF/classes, which doens't allow them to be referenced from another project.
I was able to fix that by using a repackage goal in the spring-boot-maven-plugin. However, when I did that, it did generate a jar file but my CLI application couldn't start correctly with the repository beans created.
I read in the Spring Boot documentation:
Like a war file, a Spring Boot application is not intended to be used
as a dependency. If your application contains classes that you want to
share with other projects, the recommended approach is to move that
code into a separate module. The separate module can then be depended
upon by your application and other projects.
Is there any simpler way to do this, such that I don't have to create yet another project and manage that? Or is it a good practice to have a separate project for entities and Spring Data repositories?
So, in short words you just want to have a library with your entity and repositories? Then it should be enough to configure a simple maven project, a standard one, not inheriting from Spring Boot.
As spring Boot uses Spring Data JPA under the covers, you just need Spring Data JPA declarations, so add the dependency marking it as provided.
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>Some reference version<version>
<scope>provided<scope>
</dependency>
<dependencies>
This allows not to make the project include the Spring Data JPA dependency itself, as it will be included by the end project, which uses Spring Boot. However, you'll need to declare a reference version to use, you could take the one your current Spring Boot project uses (you can have a look in the maven dependency tree).
https://spring.io/projects/spring-data-jpa
Difference between maven scope compile and provided for JAR packaging

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

Spring Boot - package application classes as a jar in BOOT-INF/lib

I am using Spring Boot 1.4.1 with Gradle 3.1. The module which has the Spring Boot plugin applied creates its own jar with the jar task, and also has the 'fat' jar created with bootRepackage. However, the classes from that module are in BOOT-INF/classes, but I would like them to be in a separate jar in BOOT-INF/lib. How to do this?
EDIT: I know I can move the code to a separate module, but for various reasons I can't make such a split (unless there is no other way). I am looking for a single-module solution, if one exists.
You'll need to set up a multi-project build and move all of your Jersey-related classes into a separate project. You can then depend upon this new project in your Spring Boot project using a project dependency. For example:
dependencies {
compile project(':jersey-endpoints')
}

Spring with maven-shade-plugin

I am trying to use to versions of spring in the same application: the first one is a webapp with spring 2.6 and the second it a jar client, with spring 4.0.2. The client communicates with another application and will be a dependency for the webapp. The problem is that the classloader will just load one time the common classes from spring and it will certainly fail.
I tried to use ElasticSearch aproach of using shaded dependencies(maven shade plugin) and relocate spring from the client to a different package (from org.springframework to my.springframework) and the uber jar seems to be constructed fine.
The issue is that Spring is based on spring.schemas and spring.handlers for validating xml config files and loads this files from classpath (META-INF folder and this paths are hardcoded in Spring code - e.q. PluggableSchemaResolver). I modified this files to point from org.srpingframework to my.springframework.
At runtime it seems that the classloader reads these files from the webapp, which has this files but with the real spring path and the exception is something like
org.realsearch.springframework.beans.FatalBeanException: Class [org.springframework.context.config.ContextNamespaceHandler] for namespace [http://www.springframework.org/schema/context] does not implement the [my.springframework.beans.factory.xml.NamespaceHandler] interface.
To me it seems that is impossible to achieve what I am trying (use tho spring versions in the same application with one of them relocated). Any ideas here? Am I wright?:d

Pulling out domain classes from a Spring Roo project

We need to be able to pull out domain classes (i.e. entities) from a Spring Roo project in order to reuse them for a Spring Batch project.
Is this possible?
Bearing in mind that we rely on Maven as our build and dependency management tool, and that our Roo project is already created, can we switch to a multi-module architecture?
If so how?
I don't think there is a roo command for converting a single module maven project to a multi module project.
One option would be to use roo to create a separate persistence module in your current project and manually migrate your entities and configuration over.

Resources