Parent POM with Multiple - Multiple Modules having dependency - maven-3

We had a relative flat project structure in CVS and post migration to Git we encountered a issue due to how Git repository were checkout. A CVS repository was never checkout, but with Git on Eclipse we see a repository folder under which projects are checkout. This has caused issue with our Maven script.
The new structure is:
I added the pom.xml file under idml and leancore that refer to parent pom.xml. the project below idml refers the intermediate idml parent pom.xml and leancore refer intermediate leancore parent pom.xml.
How do I define the dependency between 2 Multiple Modules project?
What will go into the parent POM to support this kind of structure?
How can AdjHubCore refer to a dependency in idml - idmlj2eert?
We would like to build all the module and war file from the root parent pom.xml file.

Your idmlj2eert POM looks like:
...
<groupId>idml</groupId>
<artifactId>idmlj2eert<artifactId>
<version>0.0.1-SNAPSHOT<>version>
...
Then your AdjHubCore looks like:
...
<dependency>
<groupId>idml</groupId>
<artifactId>idmlj2eert<artifactId>
<version>0.0.1-SNAPSHOT<>version>
</dependency>
...
An alternative is to use <dependencyManagement> in your root POM, such avoiding having to declare a dependency's version in child POMs. Your root POM has to be a <parent> POM, direct or transitive across multiple levels, of such a child POM then.
So, that's not different to any other dependency. The Maven Reactor takes care of the proper build order according to (intra-)dependencies inside a multi-module project at the beginning of the build.
Remember, aggregation (multi-module) and inheritance (parent/child relationships) are different things. A project can use either of them and it can use both, too. See POM Reference, Inheritance v. Aggregation and Maven: The Complete Reference, 3.6.2. Multi-module vs. Inheritance.

Related

Jenkins build failure due to use of custom jars in maven project

I am having a trouble while building my java maven project in jenkins.
In my project, there are few custom jars which I included in pom like this
<dependency>
<groupId>SMSGatewayClient</groupId>
<artifactId>SMSGatewayClient</artifactId>
<scope>system</scope>
<version>1.0</version>
<systemPath>${basedir}\lib\SMSGatewayClient.jar</systemPath>
</dependency>
But jenkins throwing exception
"Could not find artifact SMSGatewayClient:SMSGatewayClient:jar:1.0 at
specified path
/var/lib/jenkins/workspace/DEV-metal-auc/MetalBusiness_mvn\lib\SMSGatewayClient.jar"
and build is stopped.
How can I use that custom jar so that jenkins builds successfully?
Have you tried using ”/" path separators (or ${file.separator} ) in the path?
Your error shows a mix and /var/lib/ suggests you are on unix.
That assumes the ${basedir} resolved correctly.
You can also use relative notation ( ../ ) and is probably preferred if inside your workspace. You may wish to review Maven complaining about parent relative path and Maven: add a dependency to a jar by relative path
In maven, "${basedir} represents the directory containing pom.xml", so
<relativePath>./lib</relativePath>. If you had to fo up,and down, ../ for each level up, then path down.

Copy maven plugin from dependency with type pom

I have project A which contains following dependency:
<dependency>
<groupId>vo.cjm.modules.shared</groupId>
<artifactId>basic</artifactId>
<version>1.0.0</version>
<type>pom</type>
</dependency>
In the pom of this dependency I have a plugin configured. However, this plugin is never executed when installing the project in the maven local repo. When moving the plugin to the pom of project A, it is executed.
In contrast to parent-child maven projects where plugins are inherited, here I find myself in the situation where only dependencies are inherited. Is it true that when using pom type, only dependencies are inherited and no plugins? If yes, how can I achieve to inherit plugins in maven without parent-child structure?
What I also tried, was using a parent project. In this project I define the child module, project A. In project A, I reference the parent project. When doing this, maven generates 'duplicate version' errors/warnings. The only way to eliminate this behavior is removing the version of project A. Now, projects A version is inherited from the parent project. I want to be able to manage the version of project A independently, so this is not an option.
I also tried to use a parent project, and define a module (project A) in there. However, this only works with the assumption you will always call maven on the parent project. Running maven on project A, will not inherit anything that is in the parent project.
You have to distinguish the parent-child mechanism and the dependency mechanism.
When specifying a parent for a pom (thus becoming a child pom), you will inherit every dependencies and plugins declared in <dependencies> and <plugins> elements, among other things
When referencing dependencies in your pom with <dependencies>, you're telling Maven "I need this artifact (jar, pom, other) in my project, and any other dependency this artifact is also depending on", but nothing related to plugins used by this dependency. Plugins are only used when building something with Maven. Once the artifact is built and available, there is no reason to include the plugins used by this artifact when it was built - imagine if for every dependency you used, you had tons of plugins you probably don't want suddenly added to your build !
Is it true that when using pom type, only dependencies are inherited and no plugins?
Yes. When your dependency is of type pom, you're simply telling Maven to add all the dependencies of this pom to the current pom.
If yes, how can I achieve to inherit plugins in maven without parent-child structure?
To the best of my knowledge, you can't. You have to use a parent pom if you want to inherit plugins.
I'd say that dependencies are not part of the Maven project object model, so I'd say no.
We're using parent-child architectures to reuse plugins from parents.
We omit using them as Snapshots
parent with plugins +
|
+ another parent with plugins +
| |
| + child artifact uses plugins
+ child artifact uses plugins
and so on.
So parents can for example define a Java version, or they can contain profiles that child projects can use.
These are no reactor projects (no "modules"), just plain POM projects for this exact reason: To provide plugins, profiles and dependencyManagement for children.

How do I add a project as a dependency of another project?

There are two independent projects (myWarProject and MyEjbProject). So when I build the myWarProject I need to install the MyEjbProject in to the local repository, so then I can define in the myWarProject as dependency and package the myWarProject successfully.
Is there a way to handle this without install the MyEjbProject separately and also without defining as parent modules.
I know this can be achieved through ant build, but wonder whether there is a way to handle through maven?
We can create the parent project with "pom" and move the other two under the parent project. However, unfortunately I cannot do this as currently we already have those two as separate projects in the CVS which I cannot change the structure. If I can handle this through pom file, this is what Im looking for.
Assuming the MyEjbProject is not another Maven Project you own or want to build with maven, you could use system dependencies to link to the existing jar file of the project like so
<project>
...
<dependencies>
<dependency>
<groupId>yourgroup</groupId>
<artifactId>myejbproject</artifactId>
<version>2.0</version>
<scope>system</scope>
<systemPath>path/to/myejbproject.jar</systemPath>
</dependency>
</dependencies>
...
</project>
That said it is usually the better (and preferred way) to install the package to the repository either by making it a maven project and building it or installing it the way you already seem to do.
If they are, however, dependent on each other, you can always create a separate parent project (has to be a "pom" project) declaring the two other projects as its "modules". (The child projects would not have to declare the third project as their parent). As a consequence you'd get a new directory for the new parent project, where you'd also quite probably put the two independent projects like this:
parent
|- pom.xml
|- MyEJBProject
| `- pom.xml
`- MyWarProject
`- pom.xml
The parent project would get a "modules" section to name all the child modules. The aggregator would then use the dependencies in the child modules to actually find out the order in which the projects are to be built)
<project>
...
<artifactId>myparentproject</artifactId>
<groupId>...</groupId>
<version>...</version>
<packaging>pom</packaging>
...
<modules>
<module>MyEJBModule</module>
<module>MyWarModule</module>
</modules>
...
</project>
That way the projects can relate to each other but (once they are installed in the local repository) still be used independently as artifacts in other projects
Finally, if your projects are not in related directories, you might try to give them as relative modules:
filesystem
|- mywarproject
| `pom.xml
|- myejbproject
| `pom.xml
`- parent
`pom.xml
now you could just do this (worked in maven 2, just tried it):
<!--parent-->
<project>
<modules>
<module>../mywarproject</module>
<module>../myejbproject</module>
</modules>
</project>

Using profiles in multimodule project

I have a multimodule maven project. Project layout is described below:
PARENT
|-CHILD1
|-CHILD2
Parent project has pom packaging type and declares CHILD1 and CHILD2 projects as modules. Also PARENT project declares profile dev which declares some property.
CHILD1 project has jar packaging type and "overrides" PARENT dev profile by adding some dependency(dependency on commons-collections for example).
CHILD2 project has war packaging type and has dependency on CHILD1 project. Also CHILD2 "overrides" parent dev profile by adding another dependency(dependency on commons-io for example, I mean dependency that is not related with that one in project CHILD1).
Then when I run mvn clean install -Pdev maven doesn't put commons-collections.jar(dependency that is declared in CHILD1 project) to WEB-INF/lib of CHILD2 project, but commons-io.jar is there.
So, the question is: Why does not maven put dependencies from profiles that are declared in dependent projects of target project if target project declares another set of dependencies in that profile?
Actually I have much more projects and much more dependencies that varies in different profiles. And I want to declare project specific dependencies in that project pom.xml(supposing that declaring profile in project will "override" parent profile declaration)
I am assuming that you want to be able to test locally when developing, test your changes against a staging environment and finally deploy to production.
The critical thing that you need to keep in mind is that when an artifact gets deployed to the local/remote repository, the active profiles is not part of what gets deployed, so when you add dependencies via profiles things become very dangerous as you have no way of knowing if the webapp was built with the DEV profile active or the PROD profile active, and then when that built artifact gets deployed into production you could be royally screwed over.
So the short of this is that you ensure that your artifacts are independent of deployment environment.
This means that, for example, you will pick up configuration from:
files on the classpath
system properties
jndi entries
So for example, if deploying to Tomcat, you might put a configuration.properties into $CATALINA_HOME/lib
Your webapp on startup will use getClass().getResource('/configuration.properties') to resolve the properties file and fail to start-up if the file is missing (fail-fast)
you can let your unit/integration tests use a different config by putting a test version of configuration.properties in src/test/resources.
You use the same principle for the <scope>provided</scope> style dependencies of your application. In otherwords a dependency that the container is contracted with providing should be provided by the container. So you might build the production version of tomcat/jetty for yourself using Maven also and add in the required dependencies into that assembly. This would be things like the production version uses a MySQL database, so you need to add the mysql-jdbc driver into to $CATALINA_HOME/lib. It is relatively easy to do this with the assembly plugin as you are really just repacking a zip with some bits included and others excluded.
When testing locally you will want to make use of the helper plugins' run goals such as jetty:run and tomcat:run. The solution here is that there is nothing wrong with giving these plugins dependencies via profiles because you are not affecting the dependencies of the artifact you are only affecting the plugin's classpath.
e.g.
<project>
<!-- ... some stuff .. -->
<profiles>
<profile>
<id>DEV</id>
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
You can also configure system properties or classpath additions to pull in the required configuration file.
The net result of all this is that the artifact remains environment independent and you can test easily against the various environments
Hope this answers your question (even if sideways)

Why is Grails taking the jar dependencies instead of the existing maven project dependencies?

I'm using IntelliJ IDEA 10.0.2 (with groovy/grails support), maven 2.2.1 and grails 1.3.6.
We have a big maven project, which depends on many other maven projects. Let's say the workspace structure looks as follows:
backend-project (Java project, without further project dependencies)
output-project (Java project, without further project dependencies)
frontend-project (Grails project, which dependes on both, backend and output)
That means, within my frontend-project's pom.xml I have defined 2 Project Dependencies:
e.g.
<dependency>
<groupId>com.company.project</groupId>
<artifactId>backend-project</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.company.project</groupId>
<artifactId>output-project</artifactId>
<version>${project.version}</version>
</dependency>
Let's assume that I change some Java Source within the output or backend project. When I
run the grails application now, then it won't consider the changes. I have to publish the changed artifact locally and then resolve it again by the grails project before running the application in order to take effect.
This tells me that the grails project just depends on the project dependency jars within the maven repository and does not care about any existing project dependency "sources" within the workspace.
Does it have to be that complicated and if so, why?
Note that if my frontend project was a spring web project, the changes will be seen in IDEA and tomcat will even reload the change dynamically.
Note that when IDEA recognizes a mavenized grails project, it won't run the grails project with: "grail run-app" anymore but with a more complicated version of: "mvn grails:exec -Dcommand=run-app". Don't know if this is of any relevance..
Thanks!
Mr. Slash
Maven always picks up the jar files from the repositories (local and then remote etc depending on your pom.xml config).
Think about it: How would your main project know where the backend-project or the output-project files are located?
If you want a direct dependency then remove it from pom.xml and modify the project build path to directly add the projects' outputs to your main projects. In Eclipse open the properties page of the main project => build path => projects => add.

Resources