Maven - how to add a module in parent project's pom as dependency - eclipse

I have a situation mentioned in this question.
I have a multi-module Maven project with a parent project P and two sub-modules A and B. When I only had A as a sub module it worked fine. I added a new source folder in the main project, created a package and added a class (am i doing something wrong here?), lets call it module B. Now i import the class in package B in a class in package A, but A's pom doesnt get updated to include B as dependency and thus when I try to mvn compile the parent project it gives the error undefined symbol B.
Am I adding project B wrongly? coz it doesnt have any pom in it?
How do I add B as dependency in main project's pom file as mentioned in the referenced question?
Edit: Adding poms and code
here is project A's pom
<dependencies>
<dependency>
<groupId>javax.slee</groupId>
<artifactId>jain-slee</artifactId>
</dependency>
<dependency>
<groupId>org.mobicents.servers.jainslee.core</groupId>
<artifactId>fault-tolerant-ra-api</artifactId>
<version>2.6.0.FINAL</version>
</dependency>
<dependency>
<groupId>org.mobicents</groupId>
<artifactId>hello-slee-world-sbb</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
nowwhere it has B's dependency mentioned. Here is the reference of B in project A.
import BPackage.*;
this is how I have used B in A.
there is only one class in BPackage named BClass. Now I am asking if I am adding the package wrongly i.e. do I need to maven add some thing? so that its pom gets created and its dependency is added in A.
Furthermore I want to build both B and A when I compile the parent so in that case I guess I need to add A in parents pom as well. Here is the parent's pom
<modules>
<module>sbb</module>
<module>customRAType-ratype</module>
<module>customAdaptor-ra</module>
<module>du</module>
</modules>
customAdaptor-ra is project A

Each of your projects needs to have a pom.xml. The top-level project needs to have
<modules>
<module>project1</module>
<module>project2</module>
</modules>
If project2 depends on project1, you need to define a <dependency/> to it inside project2's pom.xml.

Related

'parent.relativePath' of imported bill-of materials POM creating warning in Eclipse

Note that this question is about a parent.relativePath warning in an imported bill-of-materials (BOM), not in the hierarchy of my own POM as with 'parent.relativePath' points at my com.mycompany:MyProject instead of org.apache:apache - Why?.
In Eclipse EE 2022-09 using Java 17 I have a a project with a main POM that extends from our own root POM:
<parent>
<groupId>com.globalmentor</groupId>
<artifactId>globalmentor-root</artifactId>
<version>0.8.13</version>
</parent>
The main POM also brings in dependencies from a bill of materials POM (which we also published):
<dependency>
<groupId>io.clogr</groupId>
<artifactId>clogr-bom</artifactId>
<version>0.8.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
When viewing the POM as source, Eclipse shows this warning:
'parent.relativePath' of POM io.clogr:clogr-bom:0.8.3 points at io.clogr:clogr-bom instead of com.globalmentor:globalmentor-base, please verify your project structure pom.xml /foo-bar
(In case it is relevant, note that I also have the actual source of io.clogr:clogr-bom imported into Eclipse as a separate project.)
I am aware of the purpose of relativePath as used in my own POM and parent POM. But this warning seems to be saying that the it doesn't like the relativePath designation of the imported BOM! Nevertheless the warning references line 5 of my main POM, which is the designation of the parent POM (com.globalmentor:globalmentor-root). Moreover look closely at the error message: it says that the relative path of io.clogr:clogr-bom points to itself! This cannot be the case, as io.clogr:clogr-bom has no relative path designation, and the default I understand is ../pom.xml. There is no way I can think of that io.clogr:clogr-bom could have its relative path pointing at io.clogr:clogr-bom itself.
Why is there a warning for the relativePath of an imported BOM, yet the warning references the line for the parent POM coordinates?
How do I fix this: by publishing a new io.clog:clogr-bom using <relativePath />?
But if I publish a new a new io.clog:clogr-bom using <relativePath />, does that mean the children of io.clog:clogr-bom need to add an explicit <relativePath>../pom.xml</relativePath> on the aggregated children of io.clog:clogr-bom because they are now inheriting a relative path from io.clog:clogr-bom, or will they stil get a default of <relativePath>../pom.xml</relativePath> because the relative path does not inherit?
Eclipse is right: your bom is incorrect, let's elaborate that...
in order to build module pom (project object model, do not confuse with pom.xml) maven needs to know where the parent pom.xml is located (if parent is specified), and here we may raise a question: why do we need to specify both parent GAV coordinates (group-artifact-version) and relativePath? And the rationale is following:
maven may locate artifact using GAV coordinates only when that artifact was installed/published in local/remote repository, if that didn't happen maven obviously fails (example: we are bootstrapping new multi-module project)
technically, there is no strict requirement to publish parent pom files (for example, parent/aggregator pom files may contain some information about our build process and we do not want to expose such information), moreover, there is no requirement for parent modules to be a part of reactor, however in that case you must use flatten-maven-plugin when installing/publishing such artifacts
maven resolves parent's pom.xml using following algorithm:
if relativePath is "specified" maven uses it, please note, the absence of relativePath element means that relativePath is ../pom.xml (that is your case) - to nullify the value of relativePath you need to place <relativePath/> element into parent configuration
otherwise maven tries to locate parent pom.xml using GAV coordinates in local repository and in case of failure in remote repositories
so, the general recommendations when dealing with parents are following:
if parent module is a part of multi-module project set the correct value of relativePath (relying on default ../pom.xml is not good idea though)
if parent module is a not part of multi-module project nullify relativePath via specifying <relativePath/>
take advantage of flatten-maven-plugin
In regard to your clogr-bom - that is definitely not a Bill Of Materials, it is just a published aggregator module, in order to be a bom it's content should be following:
<groupId>io.clogr</groupId>
<artifactId>clogr-bom</artifactId>
<version>0.8.3</version>
<packaging>pom</packaging>
<name>Clogr BOM</name>
<description>Parent POM and bill of materials of all Clogr projects.</description>
<url>https://clogr.io/</url>
<inceptionYear>2016</inceptionYear>
<licenses>
<license>
<name>Apache-2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
<distribution>repo</distribution>
</license>
</licenses>
<organization>
<name>GlobalMentor, Inc.</name>
<url>https://www.globalmentor.com/</url>
</organization>
<developers>
…
</developers>
<scm>
<connection>scm:git:https://bitbucket.org/globalmentor/clogr.git</connection>
<developerConnection>scm:git:https://bitbucket.org/globalmentor/clogr.git</developerConnection>
<url>https://bitbucket.org/globalmentor/clogr</url>
</scm>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.clogr</groupId>
<artifactId>clogr</artifactId>
<version>0.8.3</version>
</dependency>
<dependency>
<groupId>io.clogr</groupId>
<artifactId>clogr-logback</artifactId>
<version>0.8.3</version>
</dependency>
<dependency>
<groupId>io.clogr</groupId>
<artifactId>clogr-logback-provider</artifactId>
<version>0.8.3</version>
</dependency>
<dependency>
<groupId>io.clogr</groupId>
<artifactId>slf4j1-shim</artifactId>
<version>0.8.3</version>
</dependency>
</dependencies>
</dependencyManagement>
UPD.
Q: Thus any POM that will be published as a parent POM or to be imported needs <relativePath/>
A: My opinion on that is following: any published artifact, which is not intended to be parent in any project must strip-off information about parent (that is not just about relativePath element, but about the entire parent element), the rationale is following:
when we consume external dependency, the only information which makes sense for us is it's transitive dependencies, on the other hand specifying parent in external dependency forces maven to resolve that parent as well, and, unfortunately, that process is error-prone because parent may reside in unreachable repository, may contain mistakes, etc - such glitches are pretty common for projects, which we are considering now as "legacy", however, anything what we are doing now will eventually turn into "legacy" as well.
Q: Who says an aggregate POM cannot also serve as a bill of materials by being imported into another project?
A: I do :) Well, actually there is no common opinion about "what is BoM" even across maven team, however I would prefer to share my opinion with Robert Scholte and consider "BoM" as a "Table Of Contents":
To me a BOM represents only the set of modules of a multimodule, that contain the versions that work together. This should prevent issues with dependency depth/distance which could pull in an unexpected version.
Ideally all multimodules also provide a BOM.
Other dependencies don't belong here, as they should be upgradable/downgradable independent of the BOM.

Parent project to include common maven dependencies

I have reached a point where there are a few projects that include the same dependencies.
I want to create a parent project which only contains a pom file where the common dependencies will reside.
Is there any particular type of project I should choose in jBoss/Eclipse that will help me with this parent project creation.
When making such construction, you usually have 2 choices:
1) Using a common parent that defines these dependencies
2) Adding a Maven module of type "pom", that just lists the common dependencies
Integrating solution 1) is easy, just make a module a child of that project (can be a grandchild of course). Dependencies will be inherited.
<parent>
<groupId>com.mycompany</groupId>
<artifactId>my-company-parent-having-common-deps</artifactId>
<version>1.0.0</version>
</parent>
Integrating solution 2) is easy too. Just add a dependency on the pom module wherever it is needed, for instance:
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>mycompany-module-declaring-bunch-of-deps</artifactId>
<version>1.0.0</version>
<type>pom</type>
</dependency>
</dependencies>
Depending on your project, you'll have to see if solution 1) or 2) suits better.
I recently used a construction like solution 2) when using a JBoss EAP 6 sample: https://github.com/jboss-developer/jboss-eap-quickstarts/tree/6.3.x-develop/helloworld-jms. They created some poms projects to aggregate dependencies that should be used together, such as all dependencies needed for a JMS client.

Missing Maven dependencies in Eclipse multi-module project

I’m using STS 2.9.1 (build on Eclipse 3.7.2) with m2e plugin bundled with STS (v1.0.200.20111228-1245).
I have a problem regarding missing dependencies in Eclipse project that contains several modules, or maybe I don’t fully understand how it should work.
It’s a maven project.
In my Project > Properties > Java Build Path > Libraries I have “Maven Dependencies” library, but it's empty (and that’s the problem).
The main POM doesn’t have any dependencies, but it has several modules declared in it.
Adding a dependency to module’s POM doesn’t add it to the “Maven Dependencies” library (what was my expectation) and leads to Eclipse showing errors in source files.
Adding a dependency to the main POM adds it to the “MD” lib, but of course I don’t want to add all of my modules’ dependencies to the main POM just to have it in “MD” lib and adding every single dependency to the Build Path doesn’t seem right nor practical.
I’ve tried:
Project > Clean,
Maven > Update dependencies,
Maven > Update project configuration,
Unchecking the checkbox: Project > Properties > Maven > Resolve dependencies from Workspace projects.
None of the above seems to do the trick.
Example:
Simplified project structure:
simple.project
...
sample-module
...
pom.xml
pom.xml
simple.project/pom.xml:
<project ...>
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>simple.project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>sample-module</module>
</modules>
<dependencies>
<dependency><!-- This dependency is present in "MD" lib. -->
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
simple.project/sample-module/pom.xml:
<project ...>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>simple.project</artifactId>
<groupId>test</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>test</groupId>
<artifactId>sample-module</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency><!-- I've expected this dependency also to appear in "MD" lib. -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
It is not supposed to work. A project only imports a dependency from another one if it depends on that project (using dependency) or if it inherits from it (using parent). The module element only represents an aggregation.
The question is from time ago, but I solved this creating a Maven Project and adding Maven Modules: right click on project and "New > Project... > Maven > Maven Module".
After that, no more errors were shown in code.
First thing that I see is that you're defining dependencies in a pom parent. There I would expect to see a <dependencyManagement> (see here the doc) structure. In this way the submodules will inherit properly those common dependencies.
Aside from that lets start for the most simple test. Try to compile your project from the maven utility in the command line. If it works then you have a problem in your Eclipse configuration, otherwise the problem is in the way you have defined your project.
If your project compiles properly from the command line, lets see what else can be happening.
The fact that the Maven Dependencies Library is empty means that the Eclipse Maven plugin is not resolving properly your poms. I had quite bad experiences with the embedded STS maven plugin. Try to downgrade it to the m2e 0.10 version. You only need to open the STS DashBoard / Find Updates / Install m2e 0.10
I hope some of these tips can help you.

Maven: Jar in Referenced Libraries despite not showing in effective POM

Before importing my Maven project, I build it using the following: mvn clean install
I then create the necessary Eclipse files as follows: mvn -Dwtpversion=2.0 eclipse:eclipse
I notice that my Referenced Libraries in Eclipse contains this jar: validation-api-1.0.0.GA.jar
However, when I view the effective POM in Eclipse no such jar appears. Therefore, I am wondering how this jar gets added to my Eclipse classpath?
I require this jar for #Valid annotation I am using and I need Maven to be aware of it. If I build my classpath files using Maven then how come Maven is not aware of it?
Thanks
Check the Dependency hierarchy-tab in your pom (in Eclipse), maybe the jar is a dependency of some other jar you use.
In this case, the reference was in the project's Java Build Path, and was probably added when the project was created because of the -Dwtpversion=2.0 -parameter.
Maven also adds to your class path the sub-dependencies of your main dependencies (which are those specifically declared by you in the pom.xml). Do a
mvn dependency:tree -Dverbose
To see what other dependencies are pulled in with a specific pom-declared dependency.
Also, if you only wanna see the subdependencies of a certain dependency, called x.y.z you can do:
mvn dependency:tree -Dverbose -Dincludes=x.y.z
(where x.y is the groupId and z is the artefactId)
One of your project dependencies probably has a dependency for this jar file. Check the graphical dependency graph or just search for that, find out your project dependency that is dependent on this and exclude this dependency, if possible, by using maven's 'exclude' tags.
You can use maven dependency exclusions, as below:
<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>
Source: Maven - Dependency Exclusions
I have encountered the same problem. And after some research I realized that transitive dependencies of your parent pom may not show up in Effective POM, but would be present in Reference libraries.
The whole confusion raised because when I ran the following command
mvn dependency:tree -Dincludes=X (where X is the group-id of the jar I was looking for)
It did no mention of parent pom, instead it referred to dependency in parent pom which brings X to the table. (Which make sense because we inherit from parent pom).

Eclipse Maven runtime dependencies and profiles

Im trying to understand maven profiles and have run into the following issue.
This is my simplified example, I have two maven projects, project A and Project B.
project A has a compile time maven dependency on project B.
project B includes a runtime dependency (lets say to project C) when the maven profile "TEST" is active.
so the problem is the class path generated when I run project A. it doesn't have project C in it, even though the TEST profile is active for project A.
this is using eclipse Helios service release 1, Maven Integration for Eclipse plugin vrs 0.10.2.20100623-1649
any ideas?
I'm not sure that profiles are the best way to handle with TEST.
The use of profile to change dependecies will change the POM of the generated project.
If you install Project B with TEST activated, the runtime dependency will be added. (Whatever project A profile).
Optional dependencies are not added by transitivity. You need to add the dependency in project A.
I just tested this in Eclipse using m2eclipse 0.12.x. The second project pom.xml look like this:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.test</groupId>
<artifactId>test2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<profiles>
<profile>
<id>TEST</id>
<dependencies>
<dependency>
<groupId>org.test</groupId>
<artifactId>test1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
Then I set profile TEST as an active on Maven panel in the project properties dialog and made sure dependency resolution from Workspace is enabled there.
After that you can run any classes from test2 project's src/main/java and generated classpath looks like this:
C:\Dev\Java1.6\bin\javaw.exe -Dfile.encoding=Cp1252
-classpath C:\Dev\Workspace\test2\target\classes;C:\Dev\Workspace\test1\target\classes org.test2.Test2
Note, that dependencies with runtime scope only works for "Java Application" launch configuration type in Eclipse, but not for "JUnit" launch configuration, which uses different classpath resolver provided by m2eclipse's JDT integration.
It seems dependencies that are within profiles of dependent projects (transitive) dont give there runtime dependencies to the person who depends on them, This seems strange.
A work around was to add the profiles (containing the dependencies) to a parent then the children inherit the dependencies.
i.e. introduce a parent to A, I could have put them directly in A as YMomb kindly suggested. but its the inheritance aspect of this issue I needed to resolve as I have lots of projects As.