'import' scope and specify path? - maven

We have a pom file that specifies all our common dependencies (a BOM file), that is imported as follows:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.mycompany.myproduct</groupId>
<artifactId>external-modules-bom</artifactId>
<version>1.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
It is possible to specify a system path for the pom file so that it does not need to be present in the maven repository? It seems that systemPath can only be used when using system scope, and then the BOM isn't imported properly. Is there some other way to do this?

There's no way of doing that if you want to use built-in import scope, what I strongly recommend in your case.
Of course, probably you will be able to find some hacky combination of 3rd party plugins that effectively give you what you want, but I believe Maven is all about convention over configuration and you should prefer standard solutions to keep it simple and readable.
BTW, under the cover import scope does actually copy and paste the pom dependency of that scope, after basic syntax processing. The dependency resolution here is the standard one.

Related

Import maven property used in bill of materials (bom)

We have a project layout with sub-modules and dependencies in bom files:
projectA
bom
module1
module2
The actual version numbers are defined as properties in the bom file, so for each dependency we have something like
<properties>
<guice-version>4.1.0</guice-version>
</properties>
<dependencies>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>${guice-version}</version>
</dependency>
</dependencies>
The top-level pom in projectA import the bom in the dependecyManagement section with
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group</groupId>
<artifactId>bom</artifactId>
<version>1.0.0</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
This all works fine and we have centralized dependency definitions.
However, at one point during the build process we need to use the version of one of the dependencies. I was hoping that importing the bom in the dependencyManagement section would also import the properties into the top-level pom, but that is not the case. It is also not possible to make the bom a children of the top-level pom with a section because this creates a cyclic dependency between pom files.
I thought about putting the properties into an external file and read it with the maven properties plugin where needed. That would be obviously in the bom and in the pom file where we need to get the version of the dependency. However, since the bom is not packaged as a jar, so the path would have to be hard-coded.
I could fix it by duplicating the properties to two places, but I don't want to do that. Is there a way to get the version of a dependency, e.g. using a property defined by the dependency?
The problem seems to be common enough and I am wondering if we did something wrong in the project structure. What is the standard way to centralize properties in this case?
You can try using the BOM as the parent of your parent module as a BOM is technically some kind of minimal version of a POM. This is what the official Maven project describes here:
http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
I don't like this solution, because if you already extend from a parent, you get into a multi-inheritance problem here.
It appears that a BOM is not fulfilling your requirements. It only assembles a bunch of dependencies like an extract of a dependency management section of a parent project. However its internal structure should not matter to your project. If the BOM changes structurally, your project won't be influenced by that. Perhaps it's a more proper solution not to use a BOM here, but instead pick the dependencies and use your own version property here. Depends a little bit on how complex the BOM is.
So either use the BOM as a parent or dismiss the BOM at all, since you need more than your BOM gives you.
The actual purpose about BOM import is precisely to avoid having to declare the exact version of the dependencies declared in the BOM.
So, consider that you have a BOM witch declares a dependency like
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>${guice-version}</version>
</dependency>
(we asume your BOM also declares the property in it).
So then, in your projects, you can declare the guice dependency without having to determine the version attribute as it is inherited from the BOM.
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
The benefit is that if you change your BOM version, this kind of dependencies will be updated accorndingly without having to do any change in the pom.xml of your project!

Does Maven's dependency type expand out to type + classifier?

Follow up question to the List of possible classifiers and types in dependencies. The accepted answer points at the Maven reference guide
type: Corresponds to the dependant artifact's packaging type. This
defaults to jar. While it usually represents the extension on the
filename of the dependency, that is not always the case. A type can be
mapped to a different extension and a classifier. The type often
corresponds to the packaging used, though this is also not always the
case. Some examples are jar, ejb-client and test-jar. New types can be
defined by plugins that set extensions to true, so this is not a
complete list.
In practice this means a dependency like
<dependency>
<groupId>com.group.id</groupId>
<artifactId>my-lib</artifactId>
<version>1.0.1</version>
<type>test-jar</type>
</dependency>
corresponds to a file named my-lib-1.0.1-tests.jar.
My question is could I alternatively define the dependency as
<dependency>
<groupId>com.group.id</groupId>
<artifactId>my-lib</artifactId>
<version>1.0.1</version>
<type>jar</type>
<classifier>tests</classifier>
</dependency>
as that's essentially what it expands out to.
This is question for me as I'm trying to generate a bom file for a project. This means I'll create a dependencyManagement section listing all the jars (etc) that can be consumed by other projects. But to create the bom I'm
Deploying the project to a local repo
Parsing that directory to figure out which dependencies are produced
As a result I've only access to the expanded type and classifier.

Set Maven dependency versions in properties file

We have a couple of different applications which may or may not interact together. When they interact together, there have been issues because of mismatch in third party library versions (Let it be Spring or something else).
The pom files for these applications are separate, but to solve the above issue, we want them to use the same versions of third party libraries. The easiest way to do this is to specify the versions in common properties file, and then let respective pom.xml read the versions from the properties file.
Usually I am used to specify the versions as properties in the parent pom, and let the module pom read it from there. Is there a way I can make pom.xml read the properties file for reading the versions?
Some projects, e.g. spring-cloud and spring-boot, express their 'release train' (a set of dependencies and their versions that are known to work well together) in a 'BOM' (bill of materials). The BOM is nothing but a POM with only a dependencyManagement section, where all these dependencies are listed with the correct version. That BOM is then included in each project's POM that should follow these dependencies/versions in its dependencyManagement section, with scope 'import'.
E.g.
You create your separate project 'my-bom', containing only a pom like this:
<project>
<groupId>your.organication.program</groupId>
<artifactId>my-bom</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.whatever</groupId>
<artifactId>somedependency</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.whatever</groupId>
<artifactId>someotherdependency</artifactId>
<version>4.5.6</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
And then you include that in each project that should be aligned with these dependencies/versions:
groupId>your.organication.program.project</groupId>
<artifactId>some-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>your.organisation.program</groupId>
<artifactId>my-bom</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencyManagement>
Within the projects the dependencies that are effectively used must still be referenced in dependencies-section, but without the version - the versions are managed by the BOM.

Change scope to provided generates compile errors

I had a dependency declared as followed:
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>${version.jboss.javaee6}</version>
<type>pom</type>
</dependency>
When I change the scope to provided I get compilation errors such as EJB cannot be resolved to a type. I didn't understand, the documentation says that dependencies declared as provided are still used at compile time, and discarded only at deploy time.
So can someone help me understand these compile errors?
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>${version.jboss.javaee6}</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
I think the problem is related to the type that you have mentioned in the dependency of that artifact.
Till now whatever I have played with Maven I cannot think of any case when one would need to add pom type dependency. Generally pom type packaging is used for parent module in a project (specify common project configuration like plugin versions, common dependencies, like log4j for example, repositories, properties etc.) and for utility package module (the one that assembles the project and does some other necessary things).
So, as a suggestion remove the type tag from the dependency until you need it for any specific purpose, let it be default i.e jar.

How to get the source code for the javax:javaee-api-6.0.jar

I use the javax:javaee-api-6.0.jar maven artifact.
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
I would like to download its source code with the dependency:sources mvn goal.
I was looking for the sources in the official maven repositories, but I still can't find it.
Could you give me a bit of advice on how can I achieve my object?
Thank you.
Mich is correct.
The purpose of the javaee-api module is to satisfy compile-time dependencies (That is why the Maven scope is set to provided). The module contains interface declarations (or contract) which must be satisfied by the J2EE container you plan to use.
If you really need/want to see the source code, I'd suggest taking a look at one of the open source J2EE containers.
see if these are any good and if they work for you http://repo1.maven.org/maven2/org/apache/openejb/javaee-api/
Try this: (it has sources attached)
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>3.0.3.Final</version>
<scope>provided</scope>
<type>pom</type>
</dependency>
It pulls in a huge number of dependencies, but as they are all provided you do effectively not alter your artifact.

Resources