Maven: Naming of a copy of a project - maven

I have a project that consists of 3 subprojects.
I handle it with Maven in Eclipse.
MyPrj
Server
pom.xml with
<groupId>MyPrj</groupId>
<artifactId>Server</artifactId>
<name>Server</name>
src/main/java/MyPrj/Server/Server.java with
package MyPrj.Server
Client
pom.xml with
<groupId>MyPrj</groupId>
<artifactId>Client</artifactId>
<name>Client</name>
src/main/java/MyPrj/Client/Client.java with
package MyPrj.Client
pom.xml with
<groupId>MyPrj</groupId>
<artifactId>MyPrj</artifactId>
<name>MyPrj</name>
<modules>
<module>Server</module>
<module>Client</module>
</modules>
All is working fine.
Now I need to have a copy of MyPrj that should represent a newer version.
I did a copy of MyPrj.
MyPrj2
Server
pom.xml with
<groupId>MyPrj2</groupId>
<artifactId>Server</artifactId>
<name>Server</name>
src/main/java/MyPrj2/Server/Server.java with
package MyPrj2.Server
Client
pom.xml with
<groupId>MyPrj2</groupId>
<artifactId>Client</artifactId>
<name>Client</name>
src/main/java/MyPrj2/Client/Client.java with
package MyPrj2.Client
pom.xml with
<groupId>MyPrj2</groupId>
<artifactId>MyPrj2</artifactId>
<name>MyPrj2</name>
<modules>
<module>Server</module>
<module>Client</module>
</modules>
I can compile and package it in Maven without a problem.
But if I try to import MyPrj2 in Eclipse (exsiting Maven project) it gets a problem with the subprojects (Client, Server).
I can not tick the subprojects ("Project Client is already imported into workspace").
So the dirtories are imported but they are not recognized as a Java project.
So must be some problem with the naming. But the groupId is clearly different.
Any help would be appreciated, thanks!

If importing an existing Maven project you can select in Advanced a naming template.
I selected [groupid].[artifactid] there and then both projects were able to co-exist in eclipse.

Related

Jenkins fails to build multi-module Maven project

I have a multi-module Maven project where I have multiple micro services as modules so I have modules listed in my parent pom.xml like below:
<modules>
<module>core</module>
<module>model-base</module>
<module>module1</module>
<module>module2</module>
...
<module>module5</module>
<module>module7</module>
<module>module6</module>
</modules>
Here the module7 is dependent on module5, 6 so I have dependencies listed like below in my module7 pom.xml:
<parent>
<artifactId>pojectA</artifactId>
<groupId>com.domain</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>module7</artifactId>
<dependencies>
<dependency>
<groupId>com.domain</groupId>
<artifactId>core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.domain</groupId>
<artifactId>module5</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.domain</groupId>
<artifactId>module6</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
When I run mvn clean package in my local the module5, 6 called before the module7 as expected but in Jenkins it is trying to build module 5 then module7 making build fail saying:
[ERROR] Failed to execute goal on project module7: Could not resolve dependencies for project module7:jar:1.0-SNAPSHOT: Could not find artifact module6:jar:1.0-SNAPSHOT -> [Help 1]
Do I need to run any other jobs or re-order the modules in my pom.xml, how is it differ from local to Jenkins? Appreciate any help on this.
The order of modules is not relevant. Maven recognizes which project depends on which other project(s) and sets the build order in the reactor accordingly. See POM Reference, Aggregation (or Multi-Module):
You do not need to consider the inter-module dependencies yourself when listing the modules, i.e. the ordering of the modules given by the POM is not important. Maven will topologically sort the modules such that dependencies are always build before dependent modules.
Add Pre-Step as per below attached screenshot. This will compile all your top modules.
Then we can execute which ever module we want.
As is probably quite well understood, the issue is that the dependencies between the child modules fail because they aren't installed in the local repository yet (because they are yet to be built). The goal that causes this (for me anyway) is mvn test, which is invoked by mvn package. Your local build probably works because at some point you've done a mvn install and this has bootstrapped your system.
In Jenkins the only way I've found to make these builds work is to use the Pre-build step invoking a Maven target of install, and then build the main step as usual.

Maven - import / group all modules of project

I have a parent project with around 20 child modules:
<project>
<modules>
<module>module-1</module>
<module>...</module>
<module>module-20</module>
</modules>
</project>
I would like to use this project as one single entity, with all 20 modules included, in other projects. What is the convenient way to do this in Maven?
Should I make a new child module which imports the other 20 modules and refer to this project? Should this be a JAR or a POM project?
<project>
<packaging>jar</packaging>
<dependencies>
<dependency>... module-1 ...</dependency>
<dependency>...</dependency>
<dependency>... module-20 ...</dependency>
</dependencies>
</project>
I think the way you mentioned in your question is a good idea. It is actually mentioned as a best practice in the Maven book, quoting:
If you have a set of dependencies which are logically grouped together. You can create a project with pom packaging that groups dependencies together.
You can create a new module called module-all, which would be of pom packaging, that simply has a dependency on each of the modules. The packaging should be pom because the primary artifact of this module will only be the pom.xml (there will be no sources to compile, no JAR...). Then, in your external projects, you can simply add a dependency to this new module (as <type>pom</type>) and every module-i dependencies will be included transitively.
There would be a cave-at if all of your modules did not share the same version: there would need to be a reference to a specific version of a specific module and you would have to update the module-all version each time a module's version changes. However, if they all share the same version, module-all release cycle would be in line with module-i's.

Maven dependency project export

I am using Spring in two 2 projects. First, I have a "web" project which depends on my second project that is a normal java project with maven nature enabled that I named "core".
So, in my "web" project I just add the reference of my "core" project:
<dependency>
<groupId>com.stackoverflow</groupId>
<artifactId>core</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>jar</type>
</dependency>
If I set the property "useProjectReferences" to false like here, everything works fine, But I am in developing phase, I don't wanna run maven install everytime I have a change in my "core" project.
I am running my projects in tomcat, so I can't package them in ear. All that I want is Maven export my "src/main/resources" source folder to Spring be able to find my coreContext.xml and bind my beans. What I have tried in my "core" pom.xml:
<build>
<resources>
<resource>
<directory>${basedir}src/main/resources</directory>
<targetPath>${basedir}WEB-INF/resources</targetPath>
</resource>
...
I tried to use shade-plugin but without success too. Any tip would be appreciated.
My suggestion would be to create a Multi Module Maven Project which contains both the core and web projects.

Intellij navigate through multiple maven projects

So I have a file structure that looks like this:
.git
.project
.classpath
app1
pom.xml
.classpath
.project
src
app2
pom.xml
.classpath
.project
src
app3
pom.xml
.classpath
.project
src
TheAppIWorkOn
pom.xml
.classpath
.project
src
TheAppIWorkOn uses jars from app1, 2, and 3 which are maven dependencies so when I need to edit something in app1, 2, or 3 it's a painful process. If I use the "jump to declaration" functionality it just shows me the locked jar. Is it possible to set it up so that when I "Jump to declaration" it take me to the actual code that I can make edits on?
If you would have a maven reactor build it would have made all the module setup for you. Now you only have dependencies to jar files and IntelliJ cannot know that you have the modules to depend on. But you can help IntelliJ by pointing out the module dependencies and after that you will be able to navigate between all the classes in the project.
The best way would be to create a pom.xml in the root directory of the project. This pom would keep together the different modules and also define the build order. When you want to open the project for the first time you just point IntelliJ to this pom file and all the dependencies would be resolved and setup so the navigation between classes in the different modules is a breeze.
Sample pom file for the root directory:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.stackoverflow</groupId>
<artifactId>Q16589702</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>${project.artifactId}-${project.version}</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<modules>
<module>app1</module>
<module>app2</module>
<module>app3</module>
<module>TheAppIWorkOn</module>
</modules>
</project>
If you cannot do this for some reason then you'll have to inform IntelliJ about the module dependencies. You do this by opening up the Project Structure.
Then select the module TheAppIWorkOn and press the plus sign in the bottom and choose Module Dependency....
And there you can select all modules that you want to have as dependency.
Press Ok and then Ok again.
Now you will be able to navigate between the different classes in the project.
If app1, app2 and app3 also have dependencies between each other then you will have to do the same for them.
But the simplest way is definitely to have a pom file in the root project directory with all inter module dependencies there.

Maven Systempath not working as expected

I have specified following dependencies(For example mentioned one here) in pom.xml which will look for saaj.jar under the specified sytempath and Maven used to pick it from same path and working fine.
<dependency>
<groupId>saaj</groupId>
<artifactId>saaj</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/saaj.jar</systemPath>
</dependency>
Now I have moved to windows 7 and Spring Tool suite 2.7.1 version(Previously Win XP and Spring older vesion). In this new setup am getting below error.
Missing artifact saaj:saaj:jar:1.0:system
Now, It is looking for saaj-1.0.jar instead of saaj.jar and under the folder ${basedir}/src/main/webapp/WEB-INF/lib/saaj/saaj/1.0/ instead of ${basedir}/src/main/webapp/WEB-INF/lib/.
Why is it so? Please provide the solution where my previous setup should work fine.
Avoid systemPath, you must create a local repository like :
this is you pom file :
<repositories>
<repository>
<id>local-repo</id>
<url>file://${basedir}/lib</url>
</repository>
</repositories>
<dependency>
<groupId>tiago.medici</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1</version>
</dependency>
on project you create a lib folder to put your jar and maven pom file generated from
mvn install:install-file -Dfile=c:\tiago.medici-0.0.1.jar -DgroupId=tiago.medici -DartifactId=eureka -Dversion=0.0.1 -Dpackaging=jar
tiago.medici-0.0.1.pom
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>tiago.medici</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1</version>
<description>POM was created from install:install-file</description>
</project>
Don't use system scope. It was meant for system provided libraries. Given the path you gave for it, you are obviously creating a web application.
Use a war project and specify your dependencies with provided scope if they're already available (e.g. because they are provided by your application server) or without a scope specification otherwise. Maven will take care of packaging your project dependency in a correct way, both for Eclipse development and for deployment in your application server.

Resources