I currently have about 16 projects that I build with maven that get deployed to the same application server that make up something like a "portal". I have built a parent pom to handle common dependencies and plugin configurations. Currently, my SVN structure looks similar to this:
portal_root
+project1
+tags
+branches
+trunk
+project2
.
.
.
+projectn
pom.xml
The individual projects are each separately deployed. That is, project1 doesn't have a dependency on project2 and each can be modified and deployed without having to modify anything else.
This presents a problem with SVN as if another developer wanted to check out the entire "portal" root (to also get the parent pom) they would also by default pull down copies of all the tags and branches! Not really ideal.
The only other thing I can think of is to use something like this:
portal_root
+tags
+branches
+trunk
+project1
+src
pom.xml
+project2
.
.
.
pom.xml
However, now all project changes will be tracked in the tags folder. This isn't a huge problem for me, but branching now seems to become a pain.
I am also currently working on hooking up Teamcity into this as well which would be a bit easier now, since I would only have to watch a single directory (e.g. tags) to catch everything that needs to be built. I am also deploying artifacts to a enterprise Nessus repository.
I'm hoping someone could give me some suggestions here as I have been unable to find any decent documentation that talks about the entire build lifecycle and best practices here.
I like the idea of being able to build and deploy all the projects with a single maven command. I also like having all the common dependencies, repository information and plugin information in one place.
You can use following layout:
+parent-project
pom.xml
+child-project-1
pom.xml
+child-project-2
pom.xml
In parent project pom add:
<modules>
<module>../child-project-1</module>
<module>../child-project-2</module>
</modules>
In children projects pom add:
<parent>
<artifactId><!-- parent artifactId --></artifactId>
<groupId><!-- parent groupdId --></groupId>
<version><!-- parent version --></version>
<relativePath>../parent-project</relativePath>
</parent>
Children Projects can optionally be dependent.
Following links may also help:
http://maven.apache.org/guides/introduction/introduction-to-the-pom.html
Maven parent pom vs modules pom
A variation to JohnS's approach would be to use svn:externals to hook appropriate trunk/tags/branches of your subprojects to the appropriate trunk/tag/branch of your parent project. In this way checking out one variant of your parent would pull out all the right version of the other projects.
This makes sense only if it's reasonable to checkout all your projects together.
Related
I am transitioning to Maven-Tycho and was dealing with many errors. I seem to have gotten rid of all the errors but when I look into the pom.xml file I see maven-install-plugin, maven-compiler, maven-release plugin, etc and no mentions of tycho like I see in my tutorial. Did I do something wrong how do I make sure that my project is using maven-tycho not maven only.
http://www.vogella.com/tutorials/EclipseTycho/article.html
Any changes can be made in the pom.xml tab. The Effective POM tab is read-only, it just shows what Maven constructs when it parses your project. It's composed of your POM and its (grand)parent POMs. The Effective POM does not exist on your filesystem per se, it's generated on-the-fly whenever your run a Maven build - hence why the view is "read-only". You can change to tycho-compiler by modifying the pom.xml file replace maven-compiler-plugin with tycho-compiler-plugin. Make sure you add tycho to your eclipse environment
Could somebody explain to me, what are are differences between the file pom.xml and the file effective pom.xml in an apache maven project?
The Super POM
All Maven project POMs extend the Super POM, which defines a set of defaults shared by all projects.
The Simplest POM
All Maven POMs inherit defaults from the Super POM. If you are just writing a simple project that produces a JAR from some source in src/main/java, want to run your JUnit tests in src/test/java, and want to build a project site using mvn site, you don’t have to customize anything. All you would need, in this case, is the simplest possible POM shown in The Simplest POM. This POM defines a groupId, artifactId, and version: the three required coordinates for every project.
The Effective POM
It is the merge between The Super POM and the POM from The Simplest POM.
NOTE: This info was extracted from the following link (in the link the explanation is very complete)
Maven: The Complete Reference - 3.2. The POM
You can see the difference of a pom.xml and the effective pom.xml using
mvn help:effective-pom
which is describe here.
In a multi module project you'll use a parent pom.xml for defining general settings for all modules and then in each module there will only be specific settings.
The above goal will help you analyze the resulting pom that you could of course actually use instead of the parent reference.
The whole idea is by using the generalization (super-pom) / specialization (module pom) approach there is a central place where you can specify the general configuration. This is much more efficient then having to cut&paste the general parts.
Please also note that the effective pom will add the default behavior e.g. for the jar plugin so that you can debug issues like
Maven JAR Plugin 3.0.2 Error: You have to use a classifier to attach supplemental artifacts to the project instead of replacing them
with this approach. See also Maven `help:effective-pom` only generating for a single project, not all projects
I have three separate projects I am working on (A, B, and C).
Project B and C rely on a jar that project A generates.
Does Maven have the ability to automatically build project A if the dependency is not found?
The answers I've found so far are indicative of making the other 2 projects modules (which I believe to mean repository layout and incorporate them into project A) and create a parent / child pom.
A just plain "no" was also one of my conclusions as well.
It seems as though if I make a module of project A in B and C, maven doesn't really like that. Can Maven see projects during build time that are outside of the scope of the current project? Sorry if that's a little wordy.
The scenario works fine if A, B and C are modules of a common container project.
From root pom.xml:
<modules>
<module>project-a</module>
<module>project-b</module>
<module>project-c</module>
</modules>
where "project-a" etc. are names of maven project folders inside the parent folder.
The parent project must have <packaging>pom</packaging> for this to work.
Then you can build the parent project and it will build all children in order, or you can use one of the advanced Maven reactor flags.
e.g. mvn clean install -pl project-b will only build project B.
For more info, execute mvn --help and read the multi modules chapter from the Maven By Example book.
But to this question:
Does Maven have the ability to automatically build project A if the
dependency is not found?
... the answer is always no. Maven fails if the dependency is not found, but it never decides which projects to build. You are in charge of which projects need building.
I've refactored all repository configuration out of my various projects into a parent pom that I've created for the specific purpose of having a single point of configuration for stuff like repo's and distribution management. This is supposed to be best practice as I understand it. In deployed my parent pom to the nexus server, and then tried to run my child projects. They can't find my parent pom . . . this kind of makes sense to me since, wihtout the parent pom they don't know about the nexus repo . . . seems like a chicken and egg kind of thing? Am I missing something obvious?
It's true that your project needs to know where to find the repositories to download its dependencies. But before going to external repositories, Maven will check your local repository to see if the artifacts it needs are in there. Does your local repository contain the parent pom? If not, you can add it by running
mvn install
on the parent pom. The problem may have been caused by deploying the parent pom directly to Nexus, bypassing your local one. You can avoid this in future by deploying using
mvn deploy
This will first install the artifact locally, and then deploy it to the external repository (Nexus, in your case). More details here: http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
If you're in a situation whereby your parent pom is built and deployed by others, this won't help. You can either specify the repositories in your project's pom, or in your local settings.xml. A common approach is to expect all developers to include a repository definition in their local settings.xml which points to your Nexus repository, using it as a mirror for all other repositories. You can then configure each external repository you need in Nexus, and let it retrieve any dependencies you need for you. I'm not familiar with Nexus, but more details on mirroring can be found here: http://maven.apache.org/guides/mini/guide-mirror-settings.html
You must maintain the repositories definitions for each child (maven module), this is main best practice in a build process: "Make the build portable".
Any developer/system should be able to build any module without source dependencies to the parent or other modules, only with the repository reference.
I've got a project with Maven in which one subproject (A) wants to depend on another subproject (B) which uses "pom" packaging.
If I do this the straightforward way, where A specifies a dependency on B with <type>pom</type>, things work perfectly if I do "mvn install", but if I run any phase earlier than install, such as mvn compile or mvn package, then it fails while trying to build A: it goes looking for B's pom in the repository, and doesn't find it.
I don't really want this pom in the repository, because it's part of our active source code and changes frequently.
For all the jar-packaged projects we build, it seems to work fine to keep them out of the repository, build with mvn package, and Maven knows how to find all the dependencies in the source and build trees it manages without resorting to the repository; however for the pom-packaged project it always wants to go to the repository.
A couple things I learned while trying to understand this:
Maven best practices encourage you to use pom-packaged projects to group dependencies, but with the added step of "mvn install" on the POM project
Maven lifecycle documentation says "a project that is purely metadata (packaging value is pom) only binds goals to the install and deploy phases"; maybe this is why the POM project is invisible as a dependency target unless I invoke the install phase? I tried binding the compiler plugin to the compile phase and this didn't seem to help.
Is there a way that I can specify the POM subproject as a dependency of another subproject in the same parent project, without installing the POM project to the repository?
It isn't purely a question of which goals are bound to which lifecycle phases for POM projects. If it were, then binding the "package" goal would solve the problem.
When building a multi-module project, Maven reads the POMs of all modules to determine dependencies between modules, so that it can build the depended-upon modules before the depending modules. It's able to achieve this even when running the "package" goal (such that the depended-upon modules are not yet in the local repository).
Therefore, the code that constructs the classpath for builds must be managing several cases, notably:
extra-project jar dependency, where it looks for the POM in the local repository, handles its dependencies, and adds the POM's jar to the classpath
extra-project pom dependency, where it looks for the POM in the local repository and handles its dependencies
intra-project jar dependency, where it looks for the POM within the project tree, handles its dependencies, and adds that module's target/classes folder to the classpath
intra-project pom dependency, where for some reason it doesn't look for the POM within the project tree, and therefore doesn't handle it's dependencies.
Notice the asymmetry in the last two cases, as compared to the first two.
I can see two solutions to your problem. One is to file a bug report, or rather a request to change the behaviour (since it's obviously intentional), perhaps only for the case of intra-project dependencies on multi-module projects. Or indeed propose a patch. But since the behaviour is intentional, you might meet a refusal. In the best of cases, you're in for a long wait. (I'd vote for your bug report though - I've been stung by that same behaviour, in a different context.)
The other solution is simply to run an install on your project. I don't really understand why you don't want the POM project in your repository: if needs be, you can use a snapshot repository, where it doesn't matter if things change frequently, to avoid polluting your main repository.
Configuring maven-install-plugin to run during the compile phase, and copy the relevant pom.xml to the repository, seems to accomplish what I wanted as far as Maven itself is concerned, though m2eclipse still is not happy (it throws "failed to read artifact descriptor" errors with no additional description for the pom.xml that has a dependency on the other POM project).