We have a setup of Maven module like this:
Parent
common
webapp
Where webapp has declared a dependency to common.
In our Eclipse environment, using m2e, we made a change in common. Then ran maven package on webapp, deployed and tested the webservice. There was now a fault that indicated that the package we had done did not include the latest changes in common.
We are trying to figure out the best way to use Maven in our day-to-day development. So whats the best practice to handle situations like this?
The way to solve this issue would have been to; Make changes in common, save them, run maven install, make changes in webapp, run maven package, and use the war file for tests. But this contains a lot manual steps.
I guess another way would be to run maven package on the parent, but as the parent grows with more modules this will take longer.
How do you expect changes to common to be available unless you package and deploy it separately? Maven is not magic and it cannot make magic things happen. The solution in this case is to either manually deploy common or do as you suggest package and deploy the parent.
Parent 1.0-SNAPSHOT
+common 1.0-SNAPSHOT
+webapp 1.0-SNAPSHOT
You must use a snapshot version in the parent and reuse the same version in both module.
You must import every module in eclipse
You must run mvn clean install from the parent
If you do all this, Eclipse will recognize when there's a dependency 'webapp' project to 'common' project. Eclipse takes the 'common' project in the build-path of the 'webapp' project. Any change in 'common' is seen by 'webapp'.
Related
So we a re considering Gradle instead of Maven. What I cant figure out is how to EASILY share built dependencies between completely seperate projects at a local level that will work anywhere.
So imagine I have 2 projects DBService and Middleware. Middleware depends on DBService but they are completely seperate (not sub projects nor multi modules etc...).
I make changes to the DBService and then in Maven I could have changes go to local Maven Repo (not global as i need to test them first) using:
mvn clean install
I then start coding on Middleware and import the changes by running the same command as normal (Nice!). The maven POM requires nothing special at all (besides standard ). No path to local directory containing the jar in a lib folder (nasty IMHO) or anything else. it just works (out of the box).
How can I achieve this very simple and very common scenario in Gradle. I know I can use a local Maven repo but this is this a first class citizen in Gradle? Does it not need special/ad-hoc, or even worse, environment specific setup (UGHH) in Gradle?.
The problem is, in our company we have a project with multiple sub-modules, however one of the sub-modules is just a collection of API declarations and is meant for other (3rd praty) projects to use. I want to keep it as a sub-module because is easier to maintain and build (dependency and property inheritance). Other sub-modules in this project are also dependant on it.
The question I have is, if there exist a good practice or a nice way to execute a deploy phase that will upload just this sub-module to a different repository (can be duplicated too) without it having a dependency to parent pom.
What I have already tried:
I have already checked the deploy:deploy-file, but the problem is when it comes to SNAPSHOT builds. We wish to be able to publish SNAPSHOTS and release builds, and snapshots have different repository than release ones, but deploy-file goal can only have one url parameter. I do not wish to use different profile for snapshot deploy. Than I tried to use maven build-helper and its regex-property to be able to change the repository url if the version is a SNAPSHOT, but was unable to do so because of the plugin and regex limitations.
The last option is I can make a plugin for this, but I wish to know if there is a more elegant way to solve this the "maven way".
You can deploy this module separately but only for SNAPSHOT's for a release it does not make sense. The deployment of a module can be done via:
mvn -pl TheModuleYouWouldLikeToDeploy deploy
may be you need to add the option -am (also make dependencies) like:
mvn -am -pl TheModuleYouWouldLikeToDeploy deploy
Apart from that your approach sounds wrong cause if you are using a multi-module build why not deploying the whole build via mvn deploy ? May be it would be better to let do the job via a CI tool like Jenkins.
Yes, this is a real question.
I want to cater for the following workflow in a multi module Maven based project:
Make a change in module X
Run a Java application in module Y
Module Y may directly or indirectly depend on module X, I need all modules affected by a change to another to be compiled, recursively. I do not want tests to be run.
How, in Maven, do I do this without having to compile and install everything every time?
Why do you have to make and install everytime? The easiest solution I've found is mvn install one time. Then you can go into individual projects and build them whenever you want. If you need to ensure the chain is picked up just do the build from the top and use mvn -amd -pl projectname
This says to build a specific project and it's dependencies.
Development stage
I don't think you could do it easily with the maven only. During development however you could skip tests adding -DskipTests.
The maven cannot do incremental compilation properly. The right way to do it is to use IDE which will import maven projects into IDE's projects and then you could have fast and easy development. IntelliJ IDEA works quite well with the maven.
Production stage
For release build you could use explicit versions in the target artifact. So after changes in module X if you building the final release artifact module Y you could add explicit dependency in it. In this case all modules between X and Y will have older version (but you should assume they will work with the new X which is always not true).
Like in most spring+hibernate enterprise cases, I want to separate Dao, Service, Web layers into different modules, so that I can reuse Dao layer simultaneously in front-end and admin web site. The issue is I found m2eclipse does not support this multi-module project very well, any solutions?
I'm using eclipse 3.7 and Sonatype m2eclipse, I have a typical multiple-module structure project, one abstract parent, 2 children modules(A and B). I can run "package" from the parent, but I can not get hint when I input a "dot" after any object like system.out, and it says "This compilation unit is not on the build path of a Java project." Moreover, I can not invoke methods in A from B after I set dependencies in A's pom.xml.
I found a very similar issue here Issues with maven project running in eclipse, not recognized as Java project, but which does not solve my problem. I heard m2eclipse has removed this support for multiple-module project, but the need is so common that I'm 100% sure that there must be some kind of solution.
Thanks.
I got it working by importing the whole project and sub-module as individual projects as well. I find in individual projects I can get prompt hint methods and debug, but I'm using the whole project's pom to build.
Multi-module is still supported in m2e, I don't know where you heard that was removed but that's utterly wrong.
You simply need to import your sub modules as existing maven projects.
Also take a look at http://www.sonatype.com/books/m2eclipse-book/reference/creating-sect-importing-projects.html#fig-creating-import-multi
I'm in the process of learning maven (and java packaging & distribution) with a new oss project I'm making as practice. Here's my situation, all java of course:
My main project is ProjectA, maven-based in a github repository. I have also created one utility project, maven-based, in github: ProjectB. ProjectA depends on a project I have heavily modified that originally was from a google-code ant-based repository, ProjectC.
So, how do I set up the build for ProjectA such that someone can download ProjectA.jar and use it without needing to install jars for ProjectB and ProjectC, and also how do I set up the build such that someone could check out ProjectA and run only 'mvn package' for a full compile?
(Additionally, what should I do with my modified version of ProjectC? include the class files directly into ProjectA, or fork the project into something that could then be used by as a maven dependency?)
I've been reading around, links such as this SO question and this SO question, but I'm unclear how those relate to my particular circumstance. So, any help would be appreciated. Thanks!
So, how do I set up the build for ProjectA such that someone can download ProjectA.jar and use it without needing to install jars for ProjectB and ProjectC
Assuming ProjectA is a JAR, you can create an executable JAR that bundles the dependencies with the Maven Assembly Plugin (and the predefined jar-with-dependencies descriptor) or with the Maven Shade Plugin.
how do I set up the build such that someone could check out ProjectA and run only 'mvn package' for a full compile?
You have to deploy the dependencies to a repository that can be read over HTTP and to declare this repository in your pom.xml. AFAIK, git-hub doesn't offer any facility for that. But any web hosting service with FTP access (or better, scp) should do the trick. If your project is open source, another option would be to use Sonatype's OSS Repository Hosting service.
Just in case, you might want to read this blog post but you won't learn much more things.
The easiest would still be to organize the 3 projects as a multi-modules maven project and to build all modules.
Additionally, what should I do with my modified version of ProjectC?
From a modularization point of view (assuming you found a solution for the above part about repository), it would certainly make sense to have it as a separate module, especially if there is an opportunity someone can use ProjectC outside your project.
You have to publish the code from the additional dependencies. Two options:
Use the maven-shade-plugin to create a maven artifact containing all the content of the B and C jars, and publish that under your own G/A/V coordinates.
Publish copies of B and C under your own G/A/V coordinates using the maven-deploy-plugin to your forge just as you will publish your own code. Different forges have different policies; but if you abide by the licenses of B and C you should be OK.