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.
Related
On looking at the spring-boot-starter-web, spring-boot-starter-security projects on github, i find them to be empty with just a build.gradle file present there.
I hope this is as expected, but this leads me to understand where the actual source code can be found. And I use maven, so I was expecting atleast a pom.xml in these projects. But since it is not present, I am wondering how spring boot team publishes there artifacts to maven central repo.
I hope this is as expected
This is as expected. Spring Boot's starter modules exist purely to being multiple dependencies together into a convenient "package". For example, if you want to write a Servlet-based web application using Spring MVC and Tomcat, a single dependency on spring-boot-starter-web provides all of the dependencies that you need. You can learn a bit more about the starters in the reference documentation.
Where the actual source code can be found
The majority of the code can be found in spring-boot-autoconfigure. For more production-focused features, you'll also find some code in spring-boot-actuator-autoconfigure. The code in these two modules is activated automatically when the dependencies that it requires are on the classpath. You can learn more about this conditional activation and auto-configuration in the reference documentation.
And I use maven, so I was expecting atleast a pom.xml in these projects. But since it is not present, I am wondering how spring boot team publishes there artifacts to maven central repo.
Spring Boot is built with Gradle which, unlike Maven, completely separates the configuration needed by the build system to build the project and the information needed by a build system to consume the project. The build.gradle files provide all of the information that Gradle needs to build the project. As part of this, it generates Gradle module metadata files and Maven pom.xml files that contain all of the information needed to consume the project with Gradle and Maven respectively. These generated files are then published to Maven Central alongside the jar files, source code, etc.
I'm trying to convert a multi-module Maven project from vanilla Java EE 8 to Quarkus, and it seems that ArcAnnotationProcessor throws exceptions about unsatisfied dependencies for all injection points referencing dependencies located in a different module.
Is there any workaround, short of merging the modules?
Answering my own question:
According to the Quarkus CDI guide,
The bean archive is synthesized from:
the application,
application dependencies that contain a beans.xml descriptor or a generated Jandex index (META-INF/jandex.idx),
and Quarkus integration code.
After adding a beans.xml to each of my reactor modules, ArC no longer complains about missing dependencies.
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
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.
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).