Whhy is Spring published under two systems of artifact names?
For example, the spring core is (usually?) used as
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
(see: http://mvnrepository.com/artifact/org.springframework/spring-core/3.1.1.RELEASE )
but it is also published as
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.core</artifactId>
<version>3.1.1.RELEASE</version>
</dependency>
(see: http://ebr.springsource.com/repository/app/bundle/version/detail?name=org.springframework.core&version=3.1.1.RELEASE )
Questions:
Why do they publish the same (?) jar as two different artifacts?
Which one should I use?
Why can I find the first jar in the maven central repository, but not the second jar? In which repository can I find the second jar?
The first is the standard packaging, the second is the OSGI-conforming version.
Check out Obtaining Spring 3 Artifacts with Maven on SpringSource Blog. It should answer all your questions:
In general, Spring publishes its artifacts to two different places:
Maven Central, which is the default repository Maven queries, and does not require any special configuration to use
The Enterprise Bundle Repository (EBR), which is run by SpringSource and also hosts all the libraries that integrate with Spring
So the first thing you need to decide when obtaining Spring with Maven is which place you'll get it from. In general, if you care about OSGi, use the EBR, since it houses OSGi compatible artifacts for all of Spring's dependencies, such as Hibernate and Freemarker. If OSGi does not matter to you, either place works, though there are some pros and cons between them. In general, pick one place or the other for your project; do not mix them. This is particularly important since EBR artifacts use a different naming convention than Maven Central artifacts.
... ...
Related
I saw other similar questions but none of them had the answer I was looking for.
My question is related to the Log4j2 vulnerability recently.
I have a Maven Spring boot project where I did not switch the default logging system to Log4j2. When I run mvn dependency:tree I only see the log4j-to-slf4j jar and log4j-api jar but not the log4j-core jar, so according to https://spring.io/blog/2021/12/10/log4j2-vulnerability-and-spring-boot I assume my app is not affected.
But when i generate the effective POM I see the following
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core<artifactId>
<version>2.14.0</version>
</dependency>
I see many other dependencies in the effective POM like log4j-couchdb which the app is definitely not using (the app is not using database), so my thinking is a dependency that is in effective POM does not mean it is packaged to the app jar and used?
When I read up on definitions of effective POM, I got the feeling that whatever is in effective POM is being packaged and used by the app, so I am confused. Hope someone can help me on this. Thanks!
I made custom dependency which uses spring 4.x version and I include it in a project which uses spring 3.x version. When a method from this dependency is called it uses classes from spring 3.x version not from 4.x. Is it possible to force this dependency to use spring 4.x whereas the project itself will use spring 3.x ?
I don't think that is possible due to the fact that, when finally project is running, the dependencies are resolved on the basis of group id and artifact id and not on their version. Which is why your application is using 3.x dependency as it is overriding the one mentioned in the parent project. Hope this helps.
Yes, you can if you separate your application (which you probably don't want to). Another approach: You might think about using another class loader within the same JVM. This, however, leads to a probably bigger bunch of problems, especially using Spring.
Dzone article about loading the same class from libs with different versions.
As pvpkiran noted, you want to exclude the spring v3 transitive dependency from your custom artifact. From the maven documentation - Optional Dependencies and Dependency Exclusions:
<project>
...
<dependencies>
<dependency>
<groupId>sample.ProjectA</groupId>
<artifactId>Project-A</artifactId>
<version>1.0</version>
<scope>compile</scope>
<exclusions>
<exclusion> <!-- declare the exclusion here -->
<groupId>sample.ProjectB</groupId>
<artifactId>Project-B</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
The description for the "provided" scope of maven dependencies contains this note:
"For example, when building a web application for the Java Enterprise
Edition, you would set the dependency on the Servlet API and related
Java EE APIs to scope provided because the web container provides
those classes. This scope is only available on the compilation and
test classpath, and is not transitive."
Question is if there is a xml snippet available (maybe an official one) that gives me the "provided" dependencies for a specific tomcat version.
The thing you are looking for is a Bill of Materials (BOM). This can be imported in the dependencyManagement section of your pom.xml by setting the type and the scope of the dependency to pom and import, respectively.
Unfortunately, Tomcat does not seem to provide an official BOM for its provided dependencies. There is an unofficial version on Github, but depending on what you want to use it for, this may not be the best solution. According to the docs at github, you can us it like this:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>fr.husta.tomcat</groupId>
<artifactId>tomcat-provided-spec-bom</artifactId>
<version>8.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
When you use a full-blown JavaEE-Server like JBoss EAP, official BOMs are provided, e. g. this one.
I am learning Spring framework and while trying "various" sub-projects within this, I got this doubt.
Spring framework has "core spring" at the heart of it. Now, as the project grows, e.g. trying other features like: spring-mvc, spring-web flow , spring security etc. Are all those sub-projects part of same release. For example, if I look for spring 4.0.2 release, would all these sub-projects be included in this? (hence release for various sub-project with same number: 4.0.2).
If this is not correct, then how do we ensure to chose the compatible sub-projects?
Thanks
spring-mvc is part of the spring framework, the others are separate projects following their own versioning. In general there is a minimum version for the projects and most work fine with newer versions.
If you want to be sure use the Spring IO Platform to manage your dependencies.
In your pom add
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>1.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Then you can simply add the dependencies (without version) to your dependencies section
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
</dependencies>
For a list of managed dependencies (and version) check Appendix A of the reference guide.
Spring framework has "core spring" at the heart of it. Now, as the
project grows, e.g. trying other features like: spring-mvc, spring-web
flow , spring security etc. Are all those sub-projects part of same
release
spring-mvc and spring-web are both individual artifacts that you'll find within a single Spring release. They are versioned together, and you should always use the same version for all of them in any given project.
spring-security, however, is a completely different beast. It sits on top of Spring, but it's versioned completely separately. You need to make sure that the version of Spring Security you use is combined with a compatible version of Spring.
For example I have dependency:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.5.6</version>
</dependency>
Can I exclude one class, for example org/slf4j/Marker.class?
Try it with the shade plugin
Details on why use shade and basic usage
Excluding a single class in not possible. Within <dependency> tags you can define <exclusions/>. However, these are for entire dependencies.
The shade plugin should be handled with care. Generally, it's not good practice to be creating a jar containing all your dependencies in one place as it tends to lead to problems if you are to be using the produced artifact in another project as a dependency. For example, shading slf4j in your jar and then depending on your artifact in another project where you have another slf4j will bring you grief.
You could change those classes and define them in a different jar/module which should be included as a dependency before the jar that supplies the dependency where your class to be excluded resides (Marker.class).
Maven remembers the classpath ordering from version 2.0.9.