How to compile specific dependencies using maven - maven

I have a situation where in i need to clean and install couple of dependencies of my maven project. While I am working on this project i am making changes in these dependencies and have to manually clean and install for every small change i am making. I am trying to find a maven command which will make my life easy.
project-bpm-process <-- parent project
project-odata-service - < dependency >
project-core-service - < dependency >
I cannot put them as sub modules as they are not really modules of my this project, they are simply dependencies. So, literally group-id does not match in complete sense (there is a partial match but does not help in any way).
Update 1:
Tried the option 2 suggested by Mark. I see below error which indicates that the sub modules (aggregated projects) are not found under the parent project's folder.
[ERROR] [ERROR] Some problems were encountered while processing the
POMs: [ERROR] Child module
E:\STS-Workspaces\default-workspace\project-bpm-process-artificial\project-core-service
of
E:\STS-Workspaces\default-workspace\project-bpm-process-artificial\pom.xml
does not exist #
[ERROR] Child module
E:\STS-Workspaces\default-workspace\project-bpm-process-artificial\project-odata-service
of
E:\STS-Workspaces\default-workspace\project-bpm-process-artificial\pom.xml
does not exist #
[ERROR] Child module
E:\STS-Workspaces\default-workspace\project-bpm-process-artificial\project-bpm-process
of
E:\STS-Workspaces\default-workspace\project-bpm-process-artificial\pom.xml
does not exist #
I just created a new maven project with packaging "pom" type and added other projects as modules. Now, "project-bpm-process-artificial" has become artificial parent of all the three projects I was talking about.
From maven documentation, i see that the path is relative.
Update 2:
Location of actual pom is located at: *E:\STS-Workspaces\default-workspace\project-bpm-process-artificial*
But other referenced projects are in *C:\Users\ramgo\git* and *E:\git-repos*. These projects are imported into eclipse for development.
The pom.xml is here:
<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>com.mycompany</groupId>
<artifactId>project-bpm-process-artificial</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>project-bpm-process-artificial</name>
<url>http://maven.apache.org</url>
<modules>
<module>project-core-service</module>
<module>project-odata-service</module>
<module>project-bpm-process</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Solution: For all practical reasons I found option 1 is easy to implement (option 1 provided by Marks). It hardly took 5 minutes to write a batch script. Here is the one for handy reference.
set core=<directory_path_of_core_project>
set module_one=<<directory_path_of_module_one>>
set module_two=<<directory_path_of_module_two>>
cd %core%
call mvn clean install
cd %module_one%
call mvn clean install
cd %module_two%
call mvn clean install
Option 2 seems interesting but not feasible in my case. Links don't work and no way to refer absolute path for sub modules.
.....

The notion of Maven dependency assumes that the artifact is build externally (not even necessarily with maven) and available to your project as a third-party jar.
So, the terminology in the question is misleading to me.
If you have some third-parties (I assume having their own pom.xml) but are external to your project, then obviously in your project you can't manage them. Maven can't build external stuff.
So, based on these assumptions, the choices are:
Option 1
Create a script that will:
enter the dependency directory
run mvn install on that directory
enter your project's directory
run mvn whatever on your project
Option 2
Create an "artificial" pom.xml that will have packaging type "pom" and will list both your project and the dependencies as submodules (your project and dependencies will be peers):
|__some_folder
|__pom.xml
|__dependency1
| |__pom.xml
|__dependency2
| |__pom.xml
|__your-project
|__pom.xml
In this case you will be able to operate with both your project sources like one project and you'll be able to use the following:
cd some_folder
mvn clean install --projects <your-project> --also-make
So that if your project has dependencies in other modules, they'll also be built
I would probably go with the second option, but its your choice really
Update 1
Based on the information you've provided:
Don't really count on eclipse, its not really relevant at this point. You should try to get to the point where running maven from command line should work. The eclipse will follow your poms once you've done everything right.
If you place the "artificial" pom into E:\STS-Workspaces\default-workspace\project-bpm-process-artificial then all the modules should be in sub-folders:
E:\
|_ STS-Workspaces
|_ default-workspace
|_ project-bpm-processes-artificial
|_ project-core-service
| |_pom.xml of that module
| |_.git // it can be a root of git repo
| |_src
|_ project-odata-service
| ...
|_ project-bpm-process
After that you can do the following to check yourself:
cd E:\STS-Workspaces\default-workspace\project-bpm-process-artificial
mvn clean install
It should compile all the libraries and your project
Then if you want to build your project (assuming its called project-bpm-process) then you can do from the same folder:
mvn clean install --projects project-bpm-process --also-make
If it has a dependency on project-core-service but, say, not on project-data-service then only the project-core-service will be rebuilt
Now when the maven if sorted out, you can add eclipse workspace in any other folder. I can't comment much on eclipse since I'm an IntelliJ user. In intelliJ you can just import this artificial pom and it will automatically recognize all the projects. In eclipse I think it should work similarly

Related

Maven multiple parent-child hierarchy

I have a project that is built in the next manner:
parent module named Production, it holds two modules named apps and libs, each of them holds various projects.
Production
apps
common
utils
libs
api
dev
Production pom
<groupId>com.prod</groupId>
<packaging>pom</packaging>
<modules>
<module>libs</module>
<module>apps</module>
</modules>
Apps pom
<parent>
<groupId>com.prod</groupId>
<artifactId>apps</artifactId>
</parent>
<modules>
<module>common</module>
<module>utild</module>
</modules>
Where packaging of Production, apps and libs is pom.
While the packaging for the rest is war/jar.
When I try to run mvn install on Production (or any other module/project) I get Non-resolvable parent POM: Failure to find
Only when I run mvn install -N on Production, apps and libs, I can finally start working with the projects.
Is there a better way to accomplish successful modules and projects alignment without running mvn install -N? some pom definition or some other solution?
Without seeing your POMs, I am guessing that you are missing <module> elements naming the children in Production, apps and libs POMs.
Once you have that, if everything else is in order, you can build from the Production folder with mvn install and have the reactor figure out what the right order to build the various modules are, subject to inter-module dependencies. Note that the <module> elements are relative paths to the child projects, not anything to do with the GAV of the project.
See http://books.sonatype.com/mvnex-book/reference/multimodule.html for more information about proper setup for multi-module projects.

How to resolve the parent POM of a dependency that uses the dynamic version

I am building a multiple modules project. The project structure likes:
-Build
-Local
-POM.xml (Master)
-Main Project
-Module A
-Libs Project
-Libs Project A
The Libs Project A has the POM has the dynamic version from it's parent's POM
<parent>
<groupId>com.myproject</groupId>
<artifactId>libs</artifactId>
<version>${release.version}</version>
</parent>
<!-- this POM -->
<groupId>com.myproject.libs</groupId>
<artifactId>http</artifactId>
<packaging>bundle</packaging>
<version>1.0.0</version>
When I run maven build and pass the version parameter to build "module A", the maven can not find the POM of the libs project.
Reason: Cannot find parent: com.myproject:libs for project:
com.myproject.libs:http:bundle:1.0.0 for project
com.myproject.libs:http:bundle:1.0.0
STOP NOW
There are a number of XPath locations within the POM where property substitution is never going to work in any way that is useable.
/project/parent/groupId
/project/parent/artifactId
/project/parent/version
/project/groupId
/project/artifactId
/project/version
/project/packaging
The reason for this is that the reactor build must be deterministic.
When you try to use properties in these locations it will appear to work, in other words Maven will not shoot your foot off immediately.... but when you try to do anything further on Maven will kindly shoot your foot off.
Perhaps we should change Maven to shoot your foot off initially... perhaps that would stop people thinking that putting property expansion in those elements is supported.

about generate maven dependency

I am pretty new to maven.
Now I have a maven project developed. My another project needs to depend on this one.
Does anyone know how can I generate my own dependency? So that my second project can add the first one as a dependency in pom.
thank you very much
Since your first project is already a maven-project, just install it in your local repository by running mvn install in the first project's root directory.
Then you can include a dependency in your second project by simply referencing the groupId, artifactId and version you defined in the first project.
So if your first project had the following in its pom:
<project>
<groupId>com.yourdomain</groupId>
<artifactId>yourcomponent</artifactId>
<version>1.0</version>
... <!-- more here -->
you can include this in your second project:
<dependencies>
<dependency>
<groupId>com.yourdomain</groupId>
<artifactId>yourcomponent</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
Unless you deploy your project 1 jar to a central maven repository, this will only work if your jar is in your local repository (via mvn install).
Maven projects are identified by the "Maven coordinates", that is, the ArtifactID, GroupID and version.
Say you create your first project and run maven install. Your local repository (in $HOME/.m2/) will now contain the compiled project plus whatever coordinates you put in there.
Your second project must now only depend on the said coordinates.
I would suggest googling a bit on maven. I made a tutorial a long time ago that might help you, even if the examples are a little simple. Here you go and good luck!

Maven: Selecting Parent Project Based On Profile

I have a maven project - it is a plugin for jenkins. It's parent should be a:
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.414</version>
</parent>
But at the same time this plugin can be also used for hudson, without changing any line of code. But the parent project for it should be:
<parent>
<groupId>org.jvnet.hudson.plugins</groupId>
<artifactId>hudson-plugin-parent</artifactId>
<version>2.0.1</version>
</parent>
Can I specify 2 different profiles for that and use them to build plugin for jenkins or hudson accordingly? So that I call something like that:
mvn package -P jenkins
or
mvn package -P hudson
I have tried to specify properties in profiles, but those are not replaced by their values inside the <parent> tag. So is there any other possibility to build plugin for both, but with as much as possible common code and files?
Added: So, if I cannot do that, what should I do then? How to refactor? What the new structure should be?
As already mentioned, this is not possible.
Also, it is not possible to set a property for the parent's version as the interpolation for that happens a lot earlier than the handling of the profiles.
I would suggest that you create a masterbuild project as follows:
master
|-plugin-jenkins
|-plugin-hudson
|-plugin-assembly
The master should build all three as usual. However, in the assembly, you could add each of the two plugins as dependencies in separate profiles. And... each of these plugins can have the parent you like.
This is obviously somewhat a deviation from the Maven convention, but I believe it is a solution to your problem.
It's not possible because the tag "parent" is not available in the profiles section of the pom.
Currently we decided to stick with 1 repository and 2 separate pom.xml files, giving maven key which pom.xml use to build the project.
mvn package -f pom-jenkins.xml
mvn package -f pom-hudson.xml
No you cannot do that. you will have to refactor somehow to avoid the necessity.
As mentioned already not possible. I would suggest to make separate projects for jenkins plugin and hudson plugin. I assume that in not that far future that will not work anymore cause Hudons and Jenkins will diverge.
In general, you should be able to set the {group,artifact}Id and version of the parent POM via Java System Properties or Environment Variables, but it seems there is a Bug in Maven which will only be fixed in 4.x:
https://issues.apache.org/jira/browse/MNG-624
Another solution is to delegate the inclusion of the parent POM to your own parent POMs which you reference in the relativePath element, and change the content of the target e.g. via a symlink or cp command.
So in the main POM you would write:
<parent>
<groupId>org.mycompany.project</groupId>
<artifactId>foo-artifact</artifactId>
<version>1.0.0</version>
<relativePath>./my-parent.pom</relativePath>
</parent>
And in my-parent-jenkins you would just put:
<groupId>org.mycompany.project</groupId>
<artifactId>foo-artifact</artifactId>
<version>1.0.0</version>
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.414</version>
</parent>
The same project information with the block for hudson you put in my-parent-hudson.pom.
No you can either use
ln -s my-parent-jenkins.pom my-parent.pom
or
ln -s my-parent-hudson.pom my-parent.pom
to include the respective parent POM without the need to maintain two different main POM files for your project.
In case POM does not exist at the place referenced in relativePath, Maven will look up the POM in the remote repository[1], which is also an easy way to overwrite a parent POM locally.
[1] http://maven.apache.org/components/ref/3.3.9/maven-model/maven.html#class_parent

hudson incremental maven build always fail, while full maven build succeeds

Upon each change commited to our svn, hudson initiates a maven build with the -amd -pl flags, to make only the changed projects. However, the project it compiles "a" is dependent on another project "b", and it fails while looking for "b" in maven repositories across the web. Half an hour later it does a full build and succeeds...
Maybe we've set up our maven dependencies wrong? We have several projects a,b,c and one "maven-parent" project who has only a pom.xml with this in it:
<project>
<artifactId>maven-parent</artifactId>
<packaging>pom</packaging>
<modules>
<module>../a</module>
<module>../b</module>
<module>../c</module>
</modules>
</project>
and the "a" project references "b" like so:
<project>
<artifactId>a</artifactId>
<packaging>jar</packaging>
...
<dependency>
<groupId>com.pursway</groupId>
<artifactId>plummet</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</project>
Thanks!
Set up each project as a separate project in Hudson and use the Hudson configuration for downstream dependant projects to build whatever is necessary depending on the scm changes.
Perhaps you should try -am -pl. From mvn --help
-am,--also-make If project list is specified, also
build projects required by the
list
-amd,--also-make-dependents If project list is specified, also
build projects that depend on
projects on the list
You can specify what Raguram has pointed out in hudson project configuration. Under the build
option you can specify Maven Goals and options.
See that in image below
http://imageshack.us/photo/my-images/696/hudsonmaven.jpg/

Resources