Maven: How to include a dependency with a specific build profile? - spring

I have a project where I use Spring Boot 1.1.2.RELEASE which uses Spring 4.1.5, and Spring HATEOAS 0.10.0.RELEASE which uses Spring 4.0.9. This causes some dependency problems like the infamous java.lang.ClassNotFoundException: org.springframework.beans.factory.SmartInitializingSingleton.
I dug into the POM of spring-hateoas and found that there are different profiles defined, one of them being spring41 which depends on Spring 4.1.5. Is it possible to select this profile in my <dependency> section, or do I have to exclude the Spring dependencies?

Automatically selecting a profile for a build isn't easy. You can enable it by default in your personal settings.xml but that breaks the build for everyone who doesn't have the same file.
You can't enable a profile in the POM of the project.
With Maven 3.3, you can add the profile to ${maven.projectBasedir}/.mvn/maven.config. Since this file is part of the project, it's easy to share. You can use the Maven Enforcer plugin to make sure everyone uses a Maven version with actually uses the file.
If you can't use 3.3, then your best bet is to exclude the dependencies. If you have a parent POM, then you can use a dependencyManagement element to do it for all POMs in the reactor build.

Related

Need to know the difference between spring-boot-starter-parent and spring-boot-parent

Can some one explain me the difference between spring-boot-parent and spring-boot-starter-parent, As i have seen in one of the GIT HUB code link attached below where they have written separate modules for spring-boot-starter-parent and spring-boot-parent.
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/
If any one knows the difference between these two dependencies pls let me know, Also in most of the projects we generally use spring-boot-starter-parent as parent but not spring-boot-parent when both of them shares the same parent spring-boot-dependencies.
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/
As described at https://www.baeldung.com/spring-boot-starter-parent
Spring-boot-starter-parent
The spring-boot-starter-parent project is a special starter project –
that provides default configurations for our application and a
complete dependency tree to quickly build our Spring Boot project.
It also provides default configuration for Maven plugins such as
maven-failsafe-plugin, maven-jar-plugin, maven-surefire-plugin,
maven-war-plugin.
Beyond that, it also inherits dependency management from
spring-boot-dependencies which is the parent to the
spring-boot-starter-parent.
spring-boot-parent
Sometimes we have a custom Maven parent. Or, we may prefer to declare
all our Maven configurations manually.
In that case, we may opt to not use the spring-boot-starter-parent
project. But, we can still benefit from its dependency tree by adding
a dependency spring-boot-dependencies in our project in import scope.
Spring Boot Starter Parent helps us with managing dependency versions, the java version used by project and the default configuration for plug-ins, as we don't have to specify a lot of things manually.
It helps us with the following :
Configuration
Dependency management
Default plugin configuration (default configurations for maven-failsafe-plugin, maven-jar-plugin and maven-surefire-plugin etc)
According to spring-boot doc :
Starters are a set of convenient dependency descriptors that you can
include in your application. You get a one-stop shop for all the
Spring and related technologies that you need without having to hunt
through sample code and copy-paste loads of dependency descriptors
The spring-boot-starter is the Core starter and provides functionalities including auto-configuration support, logging and YAML.It defines spring-boot-dependencies as the parent pom .
In the github url that you provided , they have kept a separate module to specify the parent spring-boot-dependencies in the pom.It might be because they needed to use the spring-boot-dependencies , dependency tree alone without the auto-configuration and plugin configuration , and publish it as separate jar for some use-case.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${revision}</version>
<relativePath>../spring-boot-dependencies</relativePath>
</parent>
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent/2.1.6.RELEASE
I believe you meant the difference between spring-boot-starter-parent and spring-boot-starter.
spring-boot-starter-parent - has spring-boot-dependencies as the parent and hence provides various spring-boot dependencies and helps in dependency management. In addition to this spring-boot-starter-parent on it's own helps in plugin management as well.
So if you use only spring-boot-dependencies you can benefit from the dependency management provided by it but instead if you use the spring-boot-starter-parent, you get dependency management + plugin management.
spring-boot-starter - It is a dependency provided by spring-boot-dependencies which provides dependencies for autoconfigure, logging and also spring-core. In order to pull any dependency from the starter or from spring-boot-dependencies, you need to explicitly add it as a dependency in your main pom.

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

How does importing maven dependencies impact plugin management?

Maven allows one to import dependencies, for example importing Spring Boot dependencies, into a project that has a different parent using import scope. How does this impact plugin management?
I want to use the plugin versions defined in the <pluginManagement> section of the imported dependency (<spring-boot-dependencies> in this case), but I notice different versions of plugins, like surefire, used in different environments, like on TeamCity and locally.
With maven you can only inherit pluginManagement when using that POM as a parent.
Scope import only brings you dependencyManagement.
There is a ticket on the maven issue tracker though : https://issues.apache.org/jira/browse/MNG-5588
According to the Spring Boot docs, when Using Spring Boot without the parent POM, you can still keep the benefit of the dependency management (but not the plugin management).

Liferay plugin package dependencies and Maven

I'm starting to develop a Spring-MVC Portlet project. I did all the configuration needed in portlet.xml and web.xml but still a little bit confused about the Spring dependencies that have been declared in liferay-plugin-package.properties. In fact, should I add the required dependencies in this file and declare them as provided in the project pom.xml?
I use Maven as the build and dependency management tool and all examples I've found are based on the ANT project.
How does Liferay is processes the dependencies declared in liferay-plugin-package.properties ?
Besides, a maven compile fails since it does not find Spring MVC libraries required for the Spring MVC portlet project. What do you think is missing (or) incorrect in the configuration to create Spring MVC portlet ?
thanks in advance
The easiest way to go about this is to use the Maven Archetype that's been provided by liferay.
The Maven dependency is:
<dependency>
<groupId>com.liferay.maven.archetypes</groupId>
<artifactId>liferay-portlet-spring-mvc-archetype</artifactId>
<version>6.2.10.15</version>
Install this archetype in your local repository and then create a Maven project from this archetype.
This will have all the prerequisites needed for your project.
It is not necessarily to put any dependencies into liferay-plugin-package.properties file. All you need for your Spring MVC Portlet project should be presented in the project pom.xml file.
All dependencies are accessible from maven repo, e.g. http://mvnrepository.com/artifact/org.springframework/spring-webmvc-portlet

Maven: Managing Spring configurations

I have several set's of Spring configurations (XML files for bean initialization and properties files), for different kind of services/servers. I've also use maven to manage the dependencies and build (alternating with eclipse).
My intent was to have a flag I could pass to maven to build the project with a selected configuration profile.
Example:
mvn package production
will put the conf/production files in WEB-INF/classes
I've solved the problem by using the approach of Spring profiles as suggested by #gerardribas.
I've looked at the Jhipster implementation and follow that way. If somebody is following the same path, be aware that your need to upgrade your servlet version to 3.x.

Resources