Maven how to automate installation of dependencies? - java

I have 3 projects, A->B->C in that dependency order. Currently everytime I make a change to B or C I have to go to the directory and do a mvn clean install in order to install it into the local repository. It is troublesome if I have to do this every time the projects updates.
How can I do it such that every time I do a mvn clean package on A, it will automatically build and install my dependent projects B and C into the local repository?

Create a parent project for all your projects A,B,C and then add all your child project on the parent pom.xml file something like this
<modules>
<module>A</module>
<module>B</module>
<module>C</module>
</modules>
Its called maven multi module project mentioned by #khmarbaise
Here are some example for this
How do I create a multi-module project in Eclipse?
Maven Multi module tutorial
Guide to Working with Multiple Modules
By use of multi module project you will get plenty of benefits like
Anytime you can add any new project with all of the current project
Separation of project is good for code cleanup
You can build Single project or You can build all project in one go.
Duplicacy of jar can be easily ignore .
Maven take care of the build order for you.
One single Jenkins job to build everything.
Plenty of other benefits.But remember if there will some pros then cons also there,its totally now what you want to use .

You can follow the solution I provided to the question Maven 2 Projects, since it is the pattern I usually use when building project with a certain complexity.
Summarizing you would have to create a main Maven project which has three submodules, say master, platform and parent.
The main project has simply the order in which the other projects will be evaluated by Maven
The master pom contains the list of project to be built and their order (aka Reactor order)
The platform pom contains all information about your platform, like JDK version, maven plugin versions, encoding and so on.
The parent pom has the platform pom as a parent and contains all global GAV information about the dependencies you are going to use in your project (Spring, CXF, junit, log4j etc.)

Related

Rebuild dependent projects automatically when building locally

I have several Maven projects which share a common parent as following:
project-parent
project-1
project-2: includes project-1
project-3: includes project-2
Here, project-3 has project-2 in its dependencies and project-2 has project-1 in its dependencies, as an example.
When I push a project to git, Jenkins automatically rebuilds to dependent projects. For example, when I push project-3, project-2 will be rebuilt. Because of that, project-1 will be rebuilt as well. This happens because Jenkins has knowledge about the dependency graph.
However, when I build project-3 locally on my development machine, I have to remember to rebuild project-2 (and project-1) as well.
I could add a <modules>...</modules> section to the parent project and simply rebuild the parent project. This will rebuild the whole project, all child projects included. However, I would rather not do that, as there are a lot of projects and some of them require a lot of time to build.
So I want to build one project (the one I'm working on) and somehow automatically (or conveniently) rebuild all dependent projects, similar to the Jenkins behavior. Basically, I want to achieve the Jenkins behavior locally on my development machine. Is this possible?
You can execute the following command from your parent project (assuming you have the my-child-module in the <module>...</module>:
mvn clean install -pl my-child-module -am
This command will build the project my-child-module and its dependencies.
-pl, --projects
Build specified reactor projects instead of all projects
-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
Source
You can also create an aggregator completely independent of the rest: each <module> point to a path of a folder containing a pom.xml (it may also directly target a pom.xml).
<project>
...
<modules>
<module>project-parent</module>
<module>project-1</module>
<module>project-2</module>
<module>project-3</module>
</modules>
...
</project>
In this scenario, building from that aggregator will allow maven to take full knowledge of your dependency graph and build in order. You will only have to take care to update properly the version to ensure it match (if project-2 depends of version 2 of project-1 and project-1 is in version 3, then this won't work).
You need not put module you don't want, however be aware that if a module have children <module>, it will also build them.

Managing project dependencies

I've got a couple of java projects that depend on the same piece of code. Lets call them:
Project A
Project B
ComponentX.java
The projects are set up like this:
Project A > ComponentX.java
Project B > ComponentX.JAR
This set up where Project B contains ComponentX's jar file is inconvenient. Any time I make a change to ComponentX.java, I need to remember to export the Jar to Project B. It also makes debugging Project B difficult. There has to be a better way, I just don't know what to google. I'm using Eclipse. I use Maven so any solution using that would be Ok, although I'm hoping that there is a simple Eclipse based solution.
I'm guessing I'll need to move componentX into its own project and somehow make the other two depend on it.
You most likely want to create a new library project that will be used by both Project A and Project B as a standard Maven <dependency>.
There are few guides available online. If your projects are all part of the same multi-module Maven build you can take a look at Creating a Multi Module Project guide on spring.io.
So I had a lightbulb moment. Any maven project can be imported into any other maven project the exact same way you'd import any other dependency. Seems obvious now but I've only ever imported libraries other people wrote.
So if you've got three projects:
WebApp
DesktopApp
Dependency
Where both WebApp and Desktop need to reference Dependency. This could also apply in a case where there is repeated code in two projects, just pull that out into it's own project and remove it from both.
Simply make Dependency project a Maven project by right clicking > Configure > Convert to Maven Project. You'll get a .pom file with something like this at the top:
<groupId>Dependency</groupId>
<artifactId>Dependency</artifactId>
<version>0.0.1-SNAPSHOT</version>
Then all you have to do is add that as a dependency to any other project's .pom that needs access to it:
<dependency>
<groupId>Dependency</groupId>
<artifactId>Dependency</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
That's it

Maven release using multi-module pom

We have many, many different modules that make up different builds. I thought it may be a good idea to create a multi-module pom listing all the modules that would make up a specifc ear.
This post describes reasonably well what I am trying to achieve:
Maven 3 Multi Module build tries to run targets on the Multi Module POM itself
Essentially we have a master pom that defines all the common modules, spring etc.
I have created a separate multi module pom that creates all the modules for a specific build. I want to release all the modules in the modules section but dont want to release the actual multi-module pom itself.
I'm using a command line like:
mvn release:clean release:prepare -DdryRun=true release:update-versions -f My-Multi-Module-1.pom
but this is failing rtrying to release the My-Multi-Module-1.pom.
Can this be done?
Use this
-pl,--projects <arg> Comma-delimited list of specified
reactor projects to build instead
of all projects. A project can be
specified by [groupId]:artifactId
or by its relative path.

How do I implement maven source dependency among sibling projects?

I have a java project that is composed of 3 sub projects that generate a .jar artifact each (and have sub-dependencies among them).
In addition there is a web projects that depends on the first 3 projects and generate a war file. The war file is my final artifact, i.e. what I ship my customers.
Additionally I have a parent module that encompasses all the other projects:
<modules>
<module>../core</module>
<module>../commons</module>
<module>../api</module>
<module>../web</module>
</modules>
I generate eclipse files (mvn eclipse:eclipse) and work with eclipse. The problem is if I modify one of the non-web projects I must manually install it before deploying the web project to my web container. How can I make that the web project depends directly on the source code of the others and not on the version installed in the repository.
In your web application properties (right clic on the project in the Package explorer, then "properties"), add the three modules (core, commons and api) in the "J2EE Module Dependencies" (the others modules must be opened in the Eclipse workspace).
Do you want to add a dependency on the source jars deployed to the repository?
If so you can do it by adding the sources classifier to the dependency. See this answer for more details.
If not, can you clarify further please.
I think your problem is that you are just building just the war project. If you are building it from the command line, then what you have to build is the parent module. "mvn package" in the directory that contains the parent module should be enough. Of course this means that you have to build all the packages every time, but that is the way maven works.
The dependency:tree goal by itself will look things up in the repository rather than the reactor. You can work around this by mvn installing, as previously suggested, or doing something less onerous that invokes the reactor, such as
mvn compile dependency:tree
Works for me.
Edit: D'oh! Posted this answer to the wrong question. Was meant to be answering this

Migrating from ant to maven in Netbeans

Our software is written in Java and comprise many (7) projects.
These projects are Netbeans ant projects.
I'm considering to converting them to maven2.
Where can I find some hints for doing such thing?
Don't read that book. It will only make you confused. Read this book instead: "Maven - The definitive guide" http://www.sonatype.com/books/maven-book/reference/ .
Also, the maven site has a lot of information, but the structure is terrible so you'll need to use google to navigate in it.
Here is my suggestion:
Do this by hand, not with "automagic" "help" from the IDE. Maven integration doesn't work that good yet, not in any IDE.
Make sure you program project is divided into modules under a common umbrella module, so that each module produces a single binary artifact (jar, war,...) possibly accompanied by the javadoc of the source code behind that artifact, a zip with the source code etc. The basic principle is that each module produces a single artifact, containing all the non-test-code under that module. You can do this while the project is still built by ant.
Each module should conform to the standard maven directory layout. The build destination is under [module]/target/[output-type, e.g. "classes"]. The source code is under [module]/src/main/[src-type e.g. "java"] and [module]/test/[src-type]. The artifact consists of all the code under src/main, and none of the code under src/test, as it built to the target directories. You can do this while the is still built by ant.
Start by transforming the sub-module that has no dependencies on other modules in the project.
Now you can create the parent maven module pom.xml with artifact type "pom", consisting of one of the modules below. Make a child module for the first submodule (the one with only external dependencies), using the umbrella module as "parent". Remember that you need to specify version for the parent. Remember to add the child module as a "module" in the parent too. Always use ${project.version} as version in the child modules when you create multi-module projects like this. All modules under a parent must be released simultaneously in a single operation, and if you use this setting maven will make sure the version fields stay the same across all modules and gets updated everywhere during the release. This may make it difficult to re-use the existing numbering scheme, but that doesn't matter. You are never going to run out of version numbers anyway.
Add the necessary dependencies, and make sure you can build the parent and the child module together using the command "mvn clean install" from the parent module.
Proceed with the rest of the modules the same way. Dependencies to other modules under the same parent project should also use ${project.version} as the "version" they are depending on, meaning "the same version as this". NOTE THAT in order to build, the module you are depending on must be built using "mvn install", so that it gets deployed to you local (computer) repository. Otherwise the depending module will not be able to find the classes. There are NO source-code dependencies between modules in maven, only dependencies to built and packed versions installed in local and remote repositories. This can be very confusing if you come from ant-projects. Build from the root module until you get comfortable with this. It takes two days.
Don't use maven integration in IDEs. It is a bad idea. Use "mvn idea:idea" or "mvn eclipse:eclipse" to set up your workspace as a non-maven ordinary IDE project. The inter-module dependencies mechanisms in maven and the IDE aren't identical and will never be. Also, if you have several mavenized projects with dependencies in between, you want to have several of these in your workspace with dependencies set up between. You can do this with mvn idea:idea / eclipse:eclipse if you create a separate maven project file called "workspace.xml" (or whatever) in the same directory as parent module, set up as a multi-module project containing modules "." and "../otherproject" (only one-way reference here, no parent ref back). If you run "mvn idea:idea / eclipse:eclipse -f workspace.xml" you get a workspace with all these modules linked together. No IDE integration lets you do that. This sound like a lot of extra work, but the workspace.xml-file is really small. It doesn't have to contain all that dependency stuff and all that, only the reference to the modules you want to bind together in your IDE.
I did a succeful migration of NetBeans Ant project to Maven project using the instruccions by Joseph Mocker here: http://forums.netbeans.org/ptopic55953.html
I cite the important part:
close the project
rename the build.xml, nbproject files/folders to something so NB won't recognize them.
close and restart NB (so any memory cache knowledge of the project is gone)
copy in an empty pom from some other project.
open the project back up in NB (NB should now identify it as a maven project)
rearrange the files to follow the maven way (™)
This won't be an easy task since Maven2 expects the files to be organized in a specific way. Anyway Better Builds with Maven is a free book that should get you started. It will help you understand Maven and it also has a chapter on migration.
I discovered that the migration is not necessary. The real requirements that I need was automatic download of dependencies (libraries).
This is also achieved by Ivy which nonetheless uses maven repositories.
I solved converting project from ant to ant+ivy with IvyBeans.
I have built a script to migrate Ant builds to Maven. You can find more information here:
https://github.com/ewhauser/ant2maven
It won't help you with fixing your directory structure and or any additional Ant tasks, but it removes a lot of the tedious steps to get started.

Categories

Resources