Spring boot: submodule dependency - spring

I have multi-module spring boot application. I have organized it in such way that it contains web module which has #SpringBootApplication class and several other modules which are being imported by web module (e.g. batch-jobs module).
web module contains all dependencies from spring boot:
compile('org.springframework.boot:spring-boot-starter-batch')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-integration')
...
providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
testCompile('org.springframework.boot:spring-boot-starter-test')
etc...
I wonder whether I should include all spring-boot-starter dependencies into this modules or it's better to have pure spring dependencies like here:
dependencies {
compile 'org.springframework:spring-core'
compile 'org.springframework:spring-context'
compile 'org.springframework.integration:spring-integration-java-dsl'
compile 'org.springframework.batch:spring-batch-core'
...
testCompile 'org.springframework:spring-test'
testCompile 'org.springframework.integration:spring-integration-test'
}
Those dependencies are taken anyway from upper dependency-management configuration. Which approach is better? Can you please advise here?

I think this post will be flagged as opinion-based but anyway:
My thoughts on this topic are (or were if I look at spring boot) to explicitly name the dependencies you actively use in your code (and the specific modules). But with spring boot you cannot really match the dependency in your modules against the starters in the 'project'. Of course you may know that a starter-web will provide mvc from looking in the dependencies outside your project but I think that it will be hard for others to get into the definitions if the project
grows and maintain them.
Pure speculative: What if a starter gets an update and drops a dependency in favour of another? Just to give an example: LibX provided by vendorA is now switched to vendorB. You will still have a JSON dependency to vendorA in your module config but also vendorB gets in your classpath. If they have the same fully qualified name...(bam)
You could extract several starters like persistence related ones to the persistence module and web to web and so on.

Related

What is micronaut-bom?

While I worked on a Micronaut project und tried to solve some problems, like dynamic versioning of dependencies and creating a multi module micronaut project with Gradle. I found in some code examples of the build.gradle this dependency:
annotationProcessor platform("io.micronaut:micronaut-bom:2.0.0")
But I could not find any official documentation referring to it. What does it do? Can it help me with versioning my dependencies?
The Micronaut BOM (Bill Of Material, further reading) declares all the framework dependencies of a specific Micronaut release. In your example it is the BOM of Micronaut release 2.0.0.
By declaring the as a platform dependency you don't have to worry about Micronaut about the versions of supported JARs, since they already are defined in the BOM.
For example if you decide to use the Caffeine Cache with Micronaut you simply declare it as a dependency but omit the version number.
dependencies {
implementation("io.micronaut.cache:micronaut-cache-caffeine")
}
That way you make sure that you are using well tested dependencies with your Micronaut release.
why is it an `annotationProcessor?
An update since the following question came up.
Uuh. Nice. So its a collection of dependencies with the best working versions for my specific micronaut version? Cool. And why is it a annotationProcessor?
annotationProcessor is Gradle related and is called a dependency configuration. When using the java Gradle plugin you have out of the box dependency configurations such as implementation or api.
With a dependency configuration you configure the dependencies for e.g. an annotation processor by using the configuration annotationProcessor. implementation is used for your compile time dependencies. And if you want to expose the dependencies to other modules that use your module you might want to use api instead of implementation.

Managing runtime dependencies in a maven reactor project

I have a maven reactor project with a rest module and a war module. The war module is a wrapper for the rest module along with the web.xml file. I am trying to understand if it's a good practice to maintain all the runtime dependencies in war module. For instance, if I am pulling in a dependency X (which has an interface X) in the rest module, I want to pull the runtime dependency of X as part of the war module. This way all the compile scoped dependencies are in the rest layer pom and all the runtime dependencies are in the war layer.
Note: I don't see a case where the rest layer will be pulled in by any other pom file other than the war project.
Can anyone see a problem with this approach? Am I missing anything that I would regret down the road?
Example:
Project A has two modules: project-rest and project-war. Project-war is a wrapper for the project-rest and has some web filters around authentication in the web.xml (there is no source code in this module).
Project-rest obviously has REST resources and makes calls to the service layer. The service layer is divided into different projects based on the implementations, project-service is the interface and project-service-hibernate is the implementation. As far as managing dependencies in project-rest, all I need is the compile-time dependencies for the project to build. I am planning to add the project-service dependency to the project-rest pom file and project-service-hibernate as a runtime dependency on the project-war pom file. The goal here is to separate out and manage all the runtime dependencies in the war module and the compile-time dependencies in the rest module.
Actually, I would prefer to pack all the dependencies (both the runtime and the compile dependencies) into the rest module.
In this way, you see what compile and runtime dependencies belong together.
Especially, if the war has no source code, I would not add dependencies.

Spring boot war file with unnecessary jars

I am making war packaging of my spring boot. made spring boot starter tomcat as provided, removed spring boot maven plugin.
But I still see tomcat jdbc and tomcat juli, to name a few (even junit, but it could be from other custom dependencies, so discounting this for this question). I am using logback, but I see log4j over slf4j from starter web.
Can I ask, how to skip unwanted jars and keep my package nice and tidy
Maven has the concept of "scope" for dependencies. You probably know the scope test which is used for unit test dependencies which should not go into the final product. Use this scope for junit.
What you need is the scope provided for the Tomcat dependencies. This tells Maven: "Don't include it; when the code is run, someone else will make sure this dependency is on the classpath".
The dependency log4j-over-slf4j is necessary when one of your dependencies still uses log4j to log. log4j-over-slf4j contains the code to redirect those calls to logback.
Now you will face the case where you can't change the scope because it's in a POM of someone else.
The correct solution here is to define the dependency with the correct scope (and version) in a dependencyManagement element in your POM. This definition will be used when any POM asks for this group+artifactId. So even when some deep dependency of Spring Boot pulls that in, your WAR will be build with the version and scope from the dependencyManagement element.
See also:
Dependency Scopes
Dependency Management

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')
}

What is the difference between spring-context and spring-core dependencies?

Hello I am new to the Spring and maven world, and I want to know what is the difference between this 2 dependencies?
Its a simple question.. I am having trouble with my pom.xml file, so I want to know everything :).
Thanks in advance.
These are actually 2 of many Spring Framework modules. You can easily find what packages these artifacts contain, using this site:
http://mvnrepository.com/artifact/org.springframework/spring-core/3.1.1.RELEASE
This can give you information about classes contained within a particular artifact and probably about the its purpose.
For Spring Framework, spring-core contains mainly core utilities and common stuff (like enums) and because it's really critical for Spring, probably all other Spring modules depend on it (directly or transitively).
In turn spring-context provides Application Context, that is Spring's Dependency Injection Container and it is probably always defined in POMs of artifacts that use Spring Framework somehow. In fact, spring-context depends on spring-core so by defining spring-context as your dependency, you have spring-core in your classpath as well.

Resources