So I am writing a library for some features and the inner library needs to use Spring. I don't want to put in the version of Spring in the inner library. I want that the application using the library defines the version of Spring to use.
Is this even possible? If yes, then how?
Maven wise, clearly your library needs to be dependent on spring because it has to be compiled somehow so at least spring annotations like #Autowire or #Configuration / #Bean need to be in the compilation classpath.
However in the pom.xml of the library you can declare the dependency on spring as "optional" (<optional>true</optional>)
So when maven will compile the application that has your library as a dependency won't need to "take" transitively the spring as well
You can read about optional dependencies here. Their example with ProjectA, ProjectB and ProjectX is relevant...
Related
I am developing two projects.
Project 1 is a spring-boot application based on gradle for dependency management. This application defines extension-points. If - at runtime - an extension is found on the classpath, this extension is being called from the main application under certain circumstances.
Project 2 is such an extension. This extension should only provide low-level functionality. So basically, I need spring annotations and an EntityManager within the application but I would like to prevent the full spring-boot dependencies to be present on the compile-path.
The obvious (and not satisfactory) solution is to define a compileonly-dependency on a specific version of, say, spring-context. This is somewhat dangerous, as the spring-boot version may progress and it may be easy to forget to adjust the spring version.
Providing a compileOnly dependency to spring-boot-starter (or even the main project) is out of the question.
So, is there a clever trick to tell gralde to use "the spring-version coming with spring-boot-xxx"?
Sometimes you are within a forrest and not seeing the trees...
Thanks to the comment of #emrekgn I looked for BOM/Gradle/Spring and found... the spring boot dependency-management plugin.
Adding this to your gradle file will allow you to include dependencies matching to the spring boot version you are using:
plugins {
id 'org.springframework.boot' version '2.6.2'
}
apply plugin: 'io.spring.dependency-management'
Obviously, you have to match the boot-version to your needs.
I have multiple microservices that rely on the exact same classes and configuration beans.
Is it possible to externalize this configuration to be included as e.g. module or dependency?
So that e.g. if I would want to change the configuration of these classes all other microservices will have this change.
I think you could clarify your question.
If you want properties outside the jar, this is possible following what is described here https://docs.spring.io/spring-boot/docs/2.1.9.RELEASE/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files
If you want to reuse a set of classes, you can create a separate maven module and add it as a dependency in your microservices.
Update #1 (Describing how to create maven module):
Create the module using this site: https://start.spring.io/
Move the reusable code to this new module
Run mvn clean install
Add the module as a dependency in your microservices
You can create a library in the "spring-boot-starter" style.
Here is how you do it:
https://docs.spring.io/spring-boot/docs/2.0.0.M3/reference/html/boot-features-developing-auto-configuration.html
Very short:
You will have a spring.factories file where you specify the beans which will be autoconfigured. I recommend you to create conditional beans in library so you will be able to create your own beans in the project, in case you need something else.
I have a simple maven project
<dependency>
<groupId>xyz</groupId>
<artifactId>common</artifactId>
</dependency>
which includes common methods(some string operations etc..). And i would like to use it inside of quarkus project by injecting its classes as CDI bean.Could i add this maven project as a dependency to my quarkus project via traditional way in pom.xml or should i convert it to quarkus extension? I have searched for it but there is no good enough documentation as well.
Thanks in advance.
If the dependency contains a META-INF/beans.xml file, it is automatically scanned for CDI beans. If not, you can explicitly mark it to be scanned by adding this to your main application's application.properties:
quarkus.index-dependency.MYDEPENDENCY.group-id=xyz
quarkus.index-dependency.MYDEPENDENCY.artifact-id=common
I understand the concept of Spring boot, but I am looking for the logic how it is implemented and where it is maintaining the configuration. When we add any Starter-pom immediately it is giving the dependency and the configuration needed for it. How it automated that feature and where is that automating code in the spring boot?
Thanks in advance
The configuration classes for Spring Boot are in the module spring-boot-autoconfigure. A starter POM has a dependency on that (through the general spring-boot-starter module) and the required 3rd party libraries, and then the autoconfiguration for that library is activated.
The SpringBoot project has been put there so to be more productive & build production ready app in no time. SpringBoot project referes many starter projects like spring-boot-starter-jdbc, spring-boot-starter-logging, etc. All these starter libraries are like maven sub module projects and they add a set of libraries to respective project in turn. Like the spring-boot-starter-jdbc library adds these libraries -> spring-jdbc,spring-tx,tomcat-jdbc.
Now for the configuration part, spring boot has maintained another library called spring-boot-autoconfigure which auto configures all needed configs depending on the libraries present on your pom and the initial set of config annotation been used on the app. For Eg. if it sees ojdbc jar present in your pom then it will autoconfigure oracle datasource to your project
From my bare understanding, this feature are not provided by Spring Boot. It is the power of Maven. Maven allow you to declare dependencies, and the dependencies themselves, PLUS the transitive dependencies will be retrieved.
The starter POMs are simply normal Maven POM-type artifact which declared essential dependencies, and hence, when you include in your own POM, related dependencies will be downloaded.
You may get some more understanding on Maven from Maven Site or Maven Guide by Sonatype
I am migrating an old project from Ant to Gradle (yes, there is still an Ant-based project in 2014). It has all sorts of nonsense thrown into its lib/ dir, and I'm very keen on dumping anything unnecessary as part of this migration.
The project is based on Spring 3.0.5 and Jersey 1.8. It is not using Hibernate but instead using Cassandra. The project seems to think it needs javassist 3.12.0, but didn't pull cglib.
I thought I had some vague recollection of perhaps one of these optionally using javassist, but it seems by recollection is lying to me. Is it safe to remove this dependency?
Depending on how you're using Spring you might need to add an explicit dependency on CGLIB. It's marked as an optional dependency in 3.0. In Spring 3.2, the CGLIB classes were repackaged into the Spring JARs so an explicit dependency on CGLIB is no longer required. You would need CGLIB if you're proxy-target-class="true" or #Configuration.
I just checked one of my projects that's similar to yours (Spring 3.0.x and Jersey 1.x). I have dependency on Javassist but Maven tells me it's because of Hibernate. I don't see an explicit dependency from Jersey 1.x to Javassist.
If I were you, I'd leave the Javassist dependency out of the POM and let Maven take care of pulling it in if it's necessary. I would only add an explicit dependency on Javassist if it was an optional dependency that I needed or if Maven made the wrong choice about which version to include.
Is it safe to remove this dependency?
It's hard to say without seeing your entire pom.xml or the list of JARs that the Ant script worked with.