Maven dependency version in profile section when defined in dependencyManagement - java

We have several of our project modules defined in our master pom within the dependencyManagement section so that they can be used in child poms but maintain a consistent version. This is pretty standard, I think.
Now, within a profiles section of a child POM I would like to add a dependency and not define the version as I know this dependency definition exists in the Parent POM dependencyManagement section.
e.g.
...
<profiles>
<profile>
<id>DEV_PC</id>
<dependencies>
<dependency>
<groupId>com.our.project</groupId>
<artifactId>module1</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
...
I am seeing some odd behavior in the build and wonder if it this approach is allowed or do you always have to define the version of a dependency in a profile section?
To answer my own question:
You can use dependencies that are defined in a dependencyManagement section without a version in the profiles section as shown above in my example.
I have added a comment below explaining the odd behavior I had seen.

Related

How to have maven resolve a dependency of a dependency which was created by a non-default profile for some classifier?

Given a library which has different dependencies depending on a profile, say for example
<profile>
<id>default</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<envClassifier>cuda-10.1</envClassifier>
</properties>
<dependencies>
<dependency>
<groupId>org.jcuda</groupId>
<artifactId>jcuda</artifactId>
<version>10.1.0</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>cuda-10.0</id>
<properties>
<envClassifier>cuda-10.0</envClassifier>
</properties>
<dependencies>
<dependency>
<groupId>org.jcuda</groupId>
<artifactId>jcuda</artifactId>
<version>10.0.0</version>
</dependency>
</dependencies>
</profile>
I am creating artefacts with different classifiers, say for example
library-1.0.0-cuda-10.0
and
library-1.0.0-cuda-10.1
(here cuda-10.0 and cuda-10.1 are the classifiers for the artefact library-1.0.0).
If another project references this library, say for example as
<dependency>
<groupId>net.finmath</groupId>
<artifactId>library</artifactId>
<version>1.0.0</version>
<classifier>cuda-10.0</classifier>
</dependency>
then the correct artefact is pulled (here library-1.0.0-cuda-10.0.jar) but the dependency tree (via mvn dependency:tree) shows the wrong dependencies of the dependency. In this example it shows jcuda-10.1.0 and not juda-10.0.0.
This issue is due to an artefact having a single pom.xml for all classifiers (and the default profile kicks in).
Question 1: Can you have dedicated pom.xml in the repositories for different classifiers, to reflect the correct dependencies?
Apparently the issue cannot be resolved by setting a profile (-P parameter) on the outer project, because profile selectors are not passed to the poms of the dependencies. It looks as if profiles do not walk down the dependency tree.
Question 2: Is there a way to pass a profile selector to a pom of a dependency to select the right dependencies of the dependency?
I found two options to resolve the problem, but I am not very happy with them.
The first one would be to not have a default profile with a dependency in the pom of the library. In that case the user of the library (here library-1.0.0) has to specify the correct classifier and the correct downstream dependencies. This appears to be cumbersome. Also note that in this case the build of the library would fail without specification of the profile.
It is possible to use the profile to alter the name (or version) of the artefact. Since each version or artefact comes with its own pom, this allows to specify profile specific dependencies to be resolved.
However, I believe there should be a better solution, because otherwise it looks as if the specification of dependencies in profiles makes no sense for artefacts which are libraries, that is, which are themselves dependencies of another projects.
Question 3: What is the Maven way to resolve this issue?
PS: The question arose in this project: http://finmath.net/finmath-lib-cuda-extensions/
I found a lightweight solution for the problem.
You may activate a profile though a property.
Properties may not be passed from a pom to the poms of it's dependencies, but a property which is set on the command line acts on both poms.
Hence, instead of using a profile on the command line, use a property and activate the corresponding profiles in your project's pom and the library's pom.
So in the above example, the (outer) project (which references the library) has a profile
<profile>
<id>cudaversion</id>
<activation>
<property>
<name>cuda.version</name>
</property>
</activation>
<properties>
<finmath-cuda.classifier>cuda-${cuda.version}</finmath-cuda.classifier>
</properties>
</profile>
which sets the classifier of its dependency, that is this project has a dependency to library-1.0.0
<dependency>
<groupId>net.finmath</groupId>
<artifactId>library</artifactId>
<version>1.0.0</version>
<classifier>${finmath-cuda.classifier}</classifier>
</dependency>
And the pom of library-1.0.0 has a profile which is activated by the same property as in
<profile>
<id>cuda-10.0</id>
<activation>
<property>
<name>cuda.version</name>
<value>10.0</value>
</property>
</activation>
<properties>
<envClassifier>cuda-10.0</envClassifier>
</properties>
<dependencies>
<dependency>
<groupId>org.jcuda</groupId>
<artifactId>jcuda</artifactId>
<version>10.0.0</version>
</dependency>
</dependencies>
</profile>
The outer project is then build with mvn -Dcuda.version=10.0 to activate both profiles.

Why are SLF4J Logger and LoggerFactory imports missing from maven project? [duplicate]

What is the difference between dependencyManagement and dependencies?
I have seen the docs at Apache Maven web site.
It seems that a dependency defined under the dependencyManagement can be used in its child modules without specifying the version.
For example:
A parent project (Pro-par) defines a dependency under the dependencyManagement:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8</version>
</dependency>
</dependencies>
</dependencyManagement>
Then in the child of Pro-par, I can use the junit:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
However, I wonder if it is necessary to define junit in the parent pom? Why not define it directly in the needed module?
I'm fashionably late to this question, but I think it's worth a clearer response than the accepted one (which is correct, but doesn't emphasize the actual important part, which you need to deduce yourself).
In the parent POM, the main difference between the <dependencies> and <dependencyManagement> is this:
Artifacts specified in the <dependencies> section will ALWAYS be included as a dependency of the child module(s).
Artifacts specified in the <dependencyManagement> section, will only be included in the child module if they were also specified in the <dependencies> section of the child module itself. Why is it good you ask? Because you specify the version and/or scope in the parent, and you can leave them out when specifying the dependencies in the child POM. This can help you use unified versions for dependencies for child modules, without specifying the version in each child module.
Dependency Management allows to consolidate and centralize the management of dependency versions without adding dependencies which are inherited by all children. This is especially useful when you have a set of projects (i.e. more than one) that inherits a common parent.
Another extremely important use case of dependencyManagement is the control of versions of artifacts used in transitive dependencies. This is hard to explain without an example. Luckily, this is illustrated in the documentation.
The documentation on the Maven site is horrible. What dependencyManagement does is simply move your dependency definitions (version, exclusions, etc) up to the parent pom, then in the child poms you just have to put the groupId and artifactId. That's it (except for parent pom chaining and the like, but that's not really complicated either - dependencyManagement wins out over dependencies at the parent level - but if have a question about that or imports, the Maven documentation is a little better).
After reading all of the 'a', 'b', 'c' garbage on the Maven site and getting confused, I re-wrote their example. So if you had 2 projects (proj1 and proj2) which share a common dependency (betaShared) you could move that dependency up to the parent pom. While you are at it, you can also move up any other dependencies (alpha and charlie) but only if it makes sense for your project. So for the situation outlined in the prior sentences, here is the solution with dependencyManagement in the parent pom:
<!-- ParentProj pom -->
<project>
<dependencyManagement>
<dependencies>
<dependency> <!-- not much benefit defining alpha here, as we only use in 1 child, so optional -->
<groupId>alpha</groupId>
<artifactId>alpha</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>zebra</groupId>
<artifactId>zebra</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>charlie</groupId> <!-- not much benefit defining charlie here, so optional -->
<artifactId>charlie</artifactId>
<version>1.0</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
<dependency> <!-- defining betaShared here makes a lot of sense -->
<groupId>betaShared</groupId>
<artifactId>betaShared</artifactId>
<version>1.0</version>
<type>bar</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
<!-- Child Proj1 pom -->
<project>
<dependencies>
<dependency>
<groupId>alpha</groupId>
<artifactId>alpha</artifactId> <!-- jar type IS DEFAULT, so no need to specify in child projects -->
</dependency>
<dependency>
<groupId>betaShared</groupId>
<artifactId>betaShared</artifactId>
<type>bar</type> <!-- This is not a jar dependency, so we must specify type. -->
</dependency>
</dependencies>
</project>
<!-- Child Proj2 -->
<project>
<dependencies>
<dependency>
<groupId>charlie</groupId>
<artifactId>charlie</artifactId>
<type>war</type> <!-- This is not a jar dependency, so we must specify type. -->
</dependency>
<dependency>
<groupId>betaShared</groupId>
<artifactId>betaShared</artifactId>
<type>bar</type> <!-- This is not a jar dependency, so we must specify type. -->
</dependency>
</dependencies>
</project>
There's still one thing that is not highlighted enough, in my opinion, and that is unwanted inheritance.
Here's an incremental example:
I declare in my parent pom:
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
</dependencies>
boom! I have it in my Child A, Child B and Child C modules:
Implicilty inherited by child poms
A single place to manage
No need to redeclare anything in child poms
I can still redelcare and override to version 18.0 in a Child B if I want to.
But what if I end up not needing guava in Child C, and neither in the future Child D and Child E modules?
They will still inherit it and this is undesired!
This is just like Java God Object code smell, where you inherit some useful bits from a class, and a tonn of unwanted stuff as well.
This is where <dependencyManagement> comes into play. When you add this to your parent pom, all of your child modules STOP seeing it. And thus you are forced to go into each individual module that DOES need it and declare it again (Child A and Child B, without the version though).
And, obviously, you don't do it for Child C, and thus your module remains lean.
It's like you said; dependencyManagement is used to pull all the dependency information into a common POM file, simplifying the references in the child POM file.
It becomes useful when you have multiple attributes that you don't want to retype in under multiple children projects.
Finally, dependencyManagement can be used to define a standard version of an artifact to use across multiple projects.
Sorry I am very late to the party.
Let me try to explain the difference using mvn dependency:tree command
Consider the below example
Parent POM - My Project
<modules>
<module>app</module>
<module>data</module>
</modules>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
</dependencies>
</dependencyManagement>
Child POM - data module
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
</dependencies>
Child POM - app module (has no extra dependency, so leaving dependencies empty)
<dependencies>
</dependencies>
On running mvn dependency:tree command, we get following result
Scanning for projects...
------------------------------------------------------------------------
Reactor Build Order:
MyProject
app
data
------------------------------------------------------------------------
Building MyProject 1.0-SNAPSHOT
------------------------------------------------------------------------
--- maven-dependency-plugin:2.8:tree (default-cli) # MyProject ---
com.iamvickyav:MyProject:pom:1.0-SNAPSHOT
\- com.google.guava:guava:jar:19.0:compile
------------------------------------------------------------------------
Building app 1.0-SNAPSHOT
------------------------------------------------------------------------
--- maven-dependency-plugin:2.8:tree (default-cli) # app ---
com.iamvickyav:app:jar:1.0-SNAPSHOT
\- com.google.guava:guava:jar:19.0:compile
------------------------------------------------------------------------
Building data 1.0-SNAPSHOT
------------------------------------------------------------------------
--- maven-dependency-plugin:2.8:tree (default-cli) # data ---
com.iamvickyav:data:jar:1.0-SNAPSHOT
+- org.apache.commons:commons-lang3:jar:3.9:compile
\- com.google.guava:guava:jar:19.0:compile
Google guava is listed as dependency in every module (including parent), whereas the apache commons is listed as dependency only in data module (not even in parent module)
There are a few answers outlining differences between <depedencies> and <dependencyManagement> tags with maven.
However, few points elaborated below in a concise way:
<dependencyManagement> allows to consolidate all dependencies (used at child pom level) used across different modules -- clarity, central dependency version management
<dependencyManagement> allows to easily upgrade/downgrade dependencies based on need, in other scenario this needs to be exercised at every child pom level -- consistency
dependencies provided in <dependencies> tag is always imported, while dependencies provided at <dependencyManagement> in parent pom will be imported only if child pom has respective entry in its <dependencies> tag.
If the dependency was defined in the top-level pom's dependencyManagement element, the child project did not have to explicitly list the version of the dependency. if the child project did define a version, it would override the version listed in the top-level
POM’s dependencyManagement section. That is, the dependencyManagement version is only
used when the child does not declare a version directly.
Just in my own words, your parent-project helps you provide 2 kind of dependencies:
implicit dependencies : all the dependencies defined in the <dependencies> section in your parent-project are inherited by all the child-projects
explicit dependencies : allows you to select, the dependencies to apply in your child-projects. Thus, you use the <dependencyManagement> section, to declare all the dependencies you are going to use in your different child-projects. The most important thing is that, in this section, you define a <version> so that you don't have to declare it again in your child-project.
The <dependencyManagement> in my point of view (correct me if I am wrong) is just useful by helping you centralize the version of your dependencies. It is like a kind of helper feature.
As a best practice, your <dependencyManagement> has to be in a parent project, that other projects will inherit. A typical example is the way you create your Spring project by declaring the Spring parent project.
The difference between the two is best brought in what seems a necessary and sufficient definition of the dependencyManagement element available in Maven website docs:
dependencyManagement
"Default dependency information for projects that inherit from this one. The dependencies in this section are not immediately resolved. Instead, when a POM derived from this one declares a dependency described by a matching groupId and artifactId, the version and other values from this section are used for that dependency if they were not already specified."
[ https://maven.apache.org/ref/3.6.1/maven-model/maven.html ]
It should be read along with some more information available on a different page:
“..the minimal set of information for matching a dependency reference against a dependencyManagement section is actually {groupId, artifactId, type, classifier}. In many cases, these dependencies will refer to jar artifacts with no classifier. This allows us to shorthand the identity set to {groupId, artifactId}, since the default for the type field is jar, and the default classifier is null.” [https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html ]
Thus, all the sub-elements (scope, exclusions etc.,) of a dependency element--other than groupId, artifactId, type, classifier, not just version--are available for lockdown/default at the point (and thus inherited from there onward) you specify the dependency within a dependencyElement. If you’d specified a dependency with the type and classifier sub-elements (see the first-cited webpage to check all sub-elements) as not jar and not null respectively, you’d need {groupId, artifactId, classifier, type} to reference (resolve) that dependency at any point in an inheritance originating from the dependencyManagement element. Else, {groupId, artifactId} would suffice if you do not intend to override the defaults for classifier and type (jar and null respectively). So default is a good keyword in that definition; any sub-element(s) (other than groupId, artifactId, classifier and type, of course) explicitly assigned value(s) at the point you reference a dependency override the defaults in the dependencyManagement element.
So, any dependency element outside of dependencyManagement, whether as a reference to some dependencyManagement element or as a standalone is immediately resolved (i.e. installed to the local repository and available for classpaths).
I do not recommend using dependencyManagement.
The only benefit of using it is that you can define the version in parent pom and do not need to define it again in child pom. But if you have a set of projects (especially micro-service projects). Using dependencyManagement has no benefits.
Different projects may need different dependency. Why inherit it from the same parent pom. Keep it as simple as possible. If one project needs A dependency, then add it to the pom file. Don't confuse developers.
In Eclipse, there is one more feature in the dependencyManagement. When dependencies is used without it, the unfound dependencies are noticed in the pom file. If dependencyManagement is used, the unresolved dependencies remain unnoticed in the pom file and errors appear only in the java files. (imports and such...)
One use case of <dependencyManagement> is for resolving library versions conflict.
Example:
Project A have library x:1.0.1
Project A have B library
B library have library x:1.0.0
Having this set you will get conflict having project A both x:1.0.1 and x:1.0.0.
To resolve this you can put dependency with specific version into <dependencyManagement> tag
If you have a parent-pom anyways, then in my opinion using <dependencyManagement> just for controlling the version (and maybe scope) is a waste of space and confuses junior developers.
You will probably have properties for versions anyways, in some kind of parent-pom file. Why not just use this properties in the child pom's? That way you can still update a version in the property (within parent-pom) for all child projects at once. That has the same effect as <dependencyManagement> just without <dependencyManagement>.
In my opinion, <dependencyManagement> should be used for "real" management of dependencies, like exclusions and the like.
It was explained by here to be easy to understand.
The conclusion difference between dependencyManagement & dependencies are declaration and actually addition

whats the use of the dependencies in the plugin element on a pom.xml

I've see you can add dependencies element of the plugin element in a pom.
Question: What's for? Should'nt all the lib used by a plugin be include inside it? Do it surcharge some lib used by the plugin?
<plugin>
<groupId>org.raml.plugins</groupId>
<artifactId>raml-jaxrs-maven-plugin</artifactId>
<version>1.3.4</version>
<dependencies>
<dependency>
<groupId>org.raml</groupId>
<artifactId>raml-parser-2</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</plugin>
From official Maven POM Reference documentation:
dependencies: Dependencies are seen a lot within the POM, and are an element under all plugins element blocks. The dependencies have the same structure and function as under that base build. The major difference in this case is that instead of applying as dependencies of the project, they now apply as dependencies of the plugin that they are under. The power of this is to alter the dependency list of a plugin, perhaps by removing an unused runtime dependency via exclusions, or by altering the version of a required dependency.
That is, you can exclude some libraries from the plugin classpath or override certain versions, within the scope of that specific plugin.
Adding dependencies to a plugin would not alter the classpath of the application being built. The dependencies for a plugin is an entry point for further configurability, to directly change its classpath.
In most of the cases you would not need to work at that level of granularity, but indeed is quite useful in some cases and some plugin would actually need or recommend to add specific dependencies, for example plugins working on transformation or code generation (WSDL to Java, e.g.) would probably need a further dependency (you choose which one and which version) and so on.
A further official example is provided by the official Maven - Guide to configure plugins documentation:
You could configure the dependencies of the Build plugins, commonly to use a more recent dependency version.
For instance, the Maven Antrun Plugin version 1.2 uses Ant version 1.6.5, if you want to use the latest Ant version when running this plugin, you need to add <dependencies> element.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.2</version>
...
<dependencies>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-launcher</artifactId>
<version>1.7.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
...
</project>
Another example is provided by the official Exec Maven Plugin documentation in case you want to use its java goal to execute a Java program and you actually need to add libraries to its classpath but you don't want to alter the classpath of the application under build: this is a much cleaner and reasonable approach.
Dependency in plugin element allows you to define a specific version you will like the plugin to use.
Here is a good example on maven.apache.org
For instance, the Maven Antrun Plugin version 1.2 uses Ant version 1.6.5, if
you want to use the latest Ant version when running this plugin, you need to add <dependencies> element

Maven aggregation module serving as a bulk dependency

Is it possible to use an aggregating module (pom that aggregates modules for building purposes) as a dependency that transitively includes its modules as dependencies? Considering it must declare those dependencies that correspond to its submodules, otherwise if you declare it as a dependency, it hasn't own dependencies, so that no transitive deps are included.
I already tried it but I got a cyclic dependency error.
Otherwise I would have to create an extra module (say my_module_deps) that just declares all those dependencies, so I could use it as a dependency that transitively includes its dependencies. I don't like having maven modules that do not have any specific purpose except for being a dependency bulk.
This is the desired state, so I can use it for both module aggregation and a dependency to be used for getting its transitive dependencies :
<project>
<artifactId>aggregationModule</artifactId>
<modules>
<module>a</module>
<module>b</module>
<module>c</module>
</modules>
<dependencies>
<dependency>
<artifactId>a</artifactId>
</dependency>
<dependency>
<artifactId>b</artifactId>
</dependency>
<dependency>
<artifactId>c</artifactId>
</dependency>
</dependencies>
</project>
Do any of the sub-modules have that aggregating project defined as its parent?
If so, this cannot work, since for being parent the project must be build first.
But if the parent itself defines the modules as dependencies at the same time, the modules must be build first, so you created your cyclic dependency error.
You cannot declare a dependency to a project with packaging type "pom". If you do so maven will show the same error as when you declare a dependency to a jar module which does not exists in your local repository and could not be downloaded from your repository list.
Maybe some of the alternatives proposed to this question could help you.

Clean up Maven dependency management

In a big Maven 2 project it is nice to have the dependency management to make sure that only one version of a dependency is used in the whole system. That makes the system consistent.
But when I generate effective POMs I have no chance to see where the dependency versions came from. Likewise in a POM at the top of the hierarchy I have no idea where in the child POMs the defined versions of the dependency management section are really used.
So how do I keep the dependency management cleaned up? When I remove a dependency in one project, I always check in all other projects if it is still needed at all, so that I can also remove in from the dependency management at the top?
Also, how do I build up the dependency management, making sure it is not duplicated somewhere in the child POMs? When I add dependencies I always check all other projects to see if it possibly could be aggregated on top in the dependency management? Or would you just always move all dependency versions to the top from the beginning so they are always in only one place?
Thanks for any thoughts.
You could create one or more boms (bill of materials) for your project. These pom.xmls will declare all the dependencies used in your project within dependencyManagement section.
In each child pom, you would import these boms and use those dependencies that are required for the project.
In this way, dependency versions are managed centrally, while at the same time, each child pom uses only those dependencies that it needs.
See Importing Managed Dependencies
BOM project
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>my.group</groupId>
<artifactId>My-Project-Bom</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.7.0</version>
</dependency>
...
</dependencies>
</dependencyManagement>
</project>
Child project
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>my.group</groupId>
<artifactId>child1</artifactId>
<packaging>jar</packaging>
<name>Child1</name>
<version>1.0</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>my.group</groupId>
<artifactId>My-Project-BOM</artifactId>
<version>1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
</dependency>
</dependencies>
...
</project>
maven dependency plugin has a few goals to help you get the dependency hierarchy.
mvn dependency:list
mvn dependency:tree
mvn dependency:analyze
If you are using eclipse, the m2eclipe plugin allows you to view the Dependency Hierarchy for you pom. This can be very useful when trying to determine where dependencies are brought into your project and where conflicts are occurring.
You should explicitly declare the dependencies in the projects in which they are used, unless it is being used in ALL of the projects. If, for example, Spring is used for all of your projects, then put that in the parent POM. If it is only used in some projects, declare it in each one and put a spring.version property in the parent which each child pom can use for its version.
Moving all dependencies to the parent removes the responsibility from each project to manage its own dependencies. I would consider this a misuse of maven as it makes things more difficult to maintain instead of easier. It now adds dependencies to projects that doesn't need them. Often the scope of a dependency is different for projects as well, and you cannot manage that unless you declare your dependencies locally.
You can get the POM to POM dependencies, and the code-references that cause them, using the Structure101 composition perspective. Create a new s101 project, type Maven, specify the root pom.xml file, finish (use defaults for the rest of the wizard), then select the composition perspective (2nd button down on the vertical toolbar top left of the UI) and you will see something like this:

Categories