Maven Plugin: accessing resources accross multiple modules - java

I'm currently writing a custom maven plugin for generating a XML file in a multi-module maven project.
My maven structure is pretty standard: one parent project and a module by project components in the parent project folder:
-- Parent
-- module A
-- module B
-- module C
I need to list, by module, a set of classes flagged by a custom annotation.
I already wrote a set of custom annotations and an annocation processor to create a XML file at compile time in the corresponding module output directory (${project.build.outputDirectory}) .
Now i need to merge each module XML into one file, but i don't know how to access each modules from within my maven plugin except having each path set as parameters (i don't like this method).
Any idea on how to do this ?
Does maven plugins can traverse project modules ?
Thank you in advance.

To get the list list of all projects you can use:
List<MavenProject> projectList = MavenSession.getProjectDependencyGraph().getSortedProjects()
If one of your goals is correctly executed you will get everything you need. Every MavenProject contains a getBaseDir() etc.

After some researches, it seems that MavenProject.getCollectedProjects() will return the list of projects beeing manipulated by a goal execution in a multi-module project.

Related

Reuse a Spring-boot submodule in another non Spring project

I'm working on a multi module spring-boot project to build a REST API. Here is my project structure:
Parent project (packaging is pom)
core module (#SpringBootApplication + handle path like / or /status)
restControllerA module (Handle path like /routeA/*)
restControllerB module (Handle path like /routeB/*)
Everything is working in this project :)
In another non Spring project I would like to reuse a service of restControllerB. This service return the result of the request body validation.
First I try to add the restControllerB.jar as a dependency to this new project... But this jar does not contain its depedencies (who are in the fatJAR "core.jar"). When I run the project, I get a lot of ClassNotFoundException.
How can I manage to reuse this service as a dependency ? I thought to create a validator module which implements the validatorService interface, but I'm not sure if it is the best solution.
After few hours googling, It seems that creating an external librairy is the right choice. I create an external module and add it as a dependecy to restControllerB.

The Uniqueness of an artifactId in maven

Let's say that there are 2 maven artifacts (local) with the same
groupId but with a different artifactId.
The different artifactId should make each maven artifact unique.
However, if both of the unique artifacts each have a class with that share the same name. that class will not be unique because when it is imported to java it will use the groupId.className format. and the neither groupId nor the className are unique (in the discussed case).
This will result in an issue of ambiguity as to determining which class to use.
Upon testing it seems that the dependency declared first in the pom.xml file will be used.
The Question Are
What is the best practice solve/avoid this issue?
Why does maven's artifactId coordinate contribute to the uniqueness of a maven artifact within the repository but not inside the java code?
Example Code:
Maven - Same Class Name Same GroupId Different ArtifactId
Project1 is the first artifact.
Project2 is the second artifact.
"Projects User" is the artifact/project that will depend on both Project1 & Project2.
Project1 & Project2 both have a class named Utilities.
The class Utilities have a static method public static String getDescription() that returns a string containing the current project's artifact coordinates as well as the project name.
Utilities.getDescription() resulting String is called to see if an error will occur somewhere, and to see how it will be resolved.
The output depends on which dependency was declared first in the pom.xml file of the "Projects User" artifact.
Edited : Follow up Question
Is there an archetype that will create the java package using both the artifactId and groupId instead of having to do it manually every
time?
What is the best practice solve/avoid this issue?
We include the groupId and artifactId as the base package in the module. This way it is not possible to have the same class in two modules as the packages would be different.
e.g.
<groupId>net.openhft</groupId>
<artifactId>chronicle-bytes</artifactId>
has everything under the package
package net.openhft.chronicle.bytes;
Also if you know the package of a class you know which JAR it must be in.
if you have a class two JARs need, I suggest creating a common module, they both depend on.
Note: it is general practice to use your company domain name (and notional division as well) as the base of your package. Maven recommend using your domain name as you groupId and if you release to Maven Central this is now a requirement. The above strategy supports both recommendations.
Why does maven's artifactId coordinate contribute to the uniqueness of a maven artifact within the repository but not inside the java code?
Maven doesn't take any notice of the contents of the JAR.
#Peter following your lead on suggesting best practices to avoid this issue.
Group Id : It is required to uniquely identify your project. Revese of your domain name ex :
com.github.dibyaranjan
artifactId is the name of the jar without version.
To distinguish two classes from different JARs, Create package as groupId.artifactId.
For Example, I would create a project TestDummy, I want the name of the JAR to be TestDummy-1.1, then my package would look like.
com.github.dibyaranjan.testdummy
The class would look like - com.github.dibyaranjan.testdummy.MyClass
For reference visit : https://maven.apache.org/guides/mini/guide-naming-conventions.html

add a new component to java maven project

I have a maven project that contains many components. I need to add a new one called "Component" witch has one module like described in the list below:
Component
com.module
src
main
java
resources
META-INF
module
test
java
Thanks
When you need to add a new component as a maven module with many packages, maybe this would be a suitable approach. The module itself is then part of a multi module project (see Maven by Example):
Component [Name of the maven module]
src
main
java
com.module.a
com.module.b
...
resources
META-INF
module
test
java
resources

Maven Assembly: config files best practice

I have a multi-module maven project, including a seperate assembly-project. As i develop and run my application from eclipse (during development), i have specific configuration-files (e.g. log4j or other property-files) in my main-module (which contains the main-class). These files contain development-time-specific information. The assembly-project contains each of the config-files for production. The assembled product then should use these configs instead. This is my current setup:
MainModule/src/main/resources
+configA.properties
+log4j.properties
Module1/src/main/resources
+configB.properties
AssemblyProj/src/main/resources
+configA.properties
+configB.properties
+log4j.properties
And the generated project has this structure:
libs/
+MainModule.jar
+Module1.jar
configs/
+configA.properties
+configB.properties
+log4j.properties
the config-directory overlays the config-files in each *.jar because of the classpath, i.e.
java -cp configs/;libs/* My.Main.Class
Now the problem that i have, is that there are still all dev-configs included in each jar. Also i have kind of a bad feeling about using that overlay-classpath-method. Is there any practice on how to do this in a better manner?
Extract these resources into classifier-based dependencies for each of the mentioned modules. Then define <profiles/> that trigger their usage. In your assembly use the classifiers as necessary.

aspectj-maven-plugin multi module project

I'm trying to use aspectj-maven-plugin in a multi-module project and can't understand where aspects have to be placed. I want to crosscut in-module and between-modules calls. Where .aj files should be located?
This is what I did so far (structure of maven modules):
foo
foo-api
foo-impl
foo-aspects
.aj files are located in src/main/aspect. All sub-modules (except foo-aspects) are using aspectLibraries option of aspectj-maven-plugin, where they use aspects from foo-aspects.jar.
At the same time every sub-module has its own aspects in src/main/aspect. Works fine for me so far.

Categories