I have some related legacy projects that are a mess and I would like to mavenize them as a multi-module project shared on subversion (first multi-module project, we've always had them separate). There are a few key parts 1) webservice, 2) various swing clients, 3) model (w/ persistence from hibernate), 4) core JSE tasks.
I've been messing around for a few days trying to correctly set it up using Eclipse (Helios), Maven (2.2.1), m2eclipse (0.10.0) and Subversion (1.6) for our team. I keep stumping myself or having random errors that force me to backtrack. I'm hoping someone can help me out with some best practices.
Here are some of the questions:
m2eclipse requires a "flat" eclipse project structure. Does that mean I should create a subversion repository for each module? If I do one repository and try to check in from the parent project I'm having a difficult time setting the svn:ignore property on the nested project target (and other) directories.
If I do a module per repository, I seem to be able to check them in ok. The question then is what is the best way to check out via subclipse? Is there a best order? Parent or child project(s) first? Do I need to checkout the parent project and modify the checkout path of the children project to be nested in the file directory that will allow me to then "clean install" from the parent project?
Or, should I abandon subclipse and m2eclipse and checkout and run my maven goals from the command line.
Or, should I just be using the SCM integration with Maven. Or, maybe just not even try to get a multi-module project setup.
What do others do? Does anyone have some documentation (I missed) or some links (Google didn't recommend)?
Thanks in advance for your feedback.
m2eclipse requires a "flat" eclipse project structure.
Hmm, m2eclipse supports nested projects AFAIK (or at least importing a nested project structure). I don't use Eclipse wizards to create my projects though so maybe I'm not aware of something.
Does that mean I should create a subversion repository for each module?
No, no, absolutely not and I wouldn't do that (this will be hard to maintain). However, depending on your projects release cycles, you might have to think about the layout of your repository (single vs multiple trunk/tags/branches), especially if you plan to use the maven release plugin. If some pieces have independent release cycles, then I'd go for several trunk/tags/branches. If you always release them all together (as a single product), then a single trunk/tags/branches should do it. I wrote several answers on the topic that may be of interest:
Migrating to maven from an unusual svn directory structure?
Maven parent pom vs modules pom
How to handle maven versions in a multi module project?
If I do one repository and try to check in from the parent project I'm having a difficult time setting the svn:ignore property on the nested project target (and other) directories.
What is the particular problem?
If I do a module per repository, I seem to be able to check them in ok. The question then is what is the best way to check out via subclipse? Is there a best order? Parent or child project(s) first? Do I need to checkout the parent project and modify the checkout path of the children project to be nested in the file directory that will allow me to then "clean install" from the parent project?
Whatever choice you'll make (multiple repositories or not, multiple trunk/tags/branches or not), it should be possible to checkout the whole project structure in one time (using svn:externals if required). At least, you should try to make it possible (and it is, see the links posted above).
But I repeat, I do not recommend using multiple repositories (unless you want independent revision numbers) and nothing forces you to do that.
Or, should I abandon subclipse and m2eclipse and checkout and run my maven goals from the command line.
I use Eclipse, m2eclipse, subclipse successfully, all well integrated (at least for the build and "check in" part). But I do the initial import and the initial checkout on the command line and then imported
Or, should I just being using the SCM integration with Maven.
I don't use it, I don't have the need for it.
Or, maybe just not even try to get a multi-module project setup.
There is no reason to forbid the use of a multi-modules project setup, multi-modules builds are one of the key part of Maven.
What do others do? Does anyone have some documentation (I missed) or some links (Google didn't recommend)?
Have a look at the links I posted :)
It is a bit tricky at first. The way I've typically seen it setup is like so:
In subversion:
- Parent Project
-- Module A
--- pom.xml (module A)
-- Module B
--- pom.xml (module B)
-- Module c
--- pom.xml (module C)
-- pom.xml (parent project)
Some things to note (you already know):
You have to have the child projects
listed as modules in your parent
project
You have to list the parent project
in your child pom's (as the parent
group, artifact, version)
When you check out the project from
svn, you need to do 'check out as
maven project' instead of the
standard 'check out' (this one can be
a gotcha)
I hope this helps.
Related
We have some Maven modules shared between several teams, with the mandate to share the source code even though our projects use different dependencies and resources. To accomplish this, we have our modules set up as recommended in Using Maven When You Can't Use the Conventions under "Producing Multiple Unique JARs from a Single Source Directory." Specifically, we have a shared parent module containing the src directory but whose pom declares <packaging>pom</packaging> and only builds the two submodules. Each submodule inherits from this parent and refers to the shared src directory using this:
<build>
<sourceDirectory>../src/main/java</sourceDirectory>
</build>
The two submodules have different artifact ids, allowing dependent modules and projects to specify which version and dependency set they need. It also upholds the Maven principle of "one module, one output."
This all works great in Maven-land: compilation, installation, deployments, etc. What doesn't work well is Eclipse integration. Some things work fine: building the modules, deploying to our Maven repo, pulling in dependencies to build our project. But things such as code completion and jumping to class/method definitions do not work at all. It's as though Eclipse doesn't recognize the source at all.
If we just check out a module from SVN, Eclipse doesn't know about the classes but instead uses jars from the repo. If we then import the modules as Maven modules, they show up in package explorer and the project build path. However, all references to those classes and methods are now flagged as errors by Eclipse. And we still do not have code completion or navigation.
So my questions are these: How can we get Eclipse to recognize the code and do its normal code navigation while still satisfying our varying project requirements? Am I missing some simple Eclipse configuration? Do we need to rework our Maven module structure, and if so, how?
Some additional context: The different dependencies for the projects are rather large, including different major versions for things such as Weblogic and Spring. The Weblogic versions will converge some time next year, but the other dependencies will be slower (and some resource files will likely always remain distinct). So for the near- to mid-future, we have to account for different dependencies between the projects.
We are using profiles to allow our Jenkins server to build both submodules while allowing individual developers to build only the submodule their project needs. Using profiles to manage the dependencies is problematic because we lose transitivity of dependencies.
Update (12/8/15)
I was eventually able to make Eclipse recognize the source directory by using "Link Source..." on the "Configure Build Path..." dialog. Adding a source folder would not let me reference the module's parent directory, but Link Source let me assign an arbitrary directory to use. It's not ideal, but it seems to be working.
I was eventually able to make Eclipse recognize the source directory by using "Link Source..." on the "Configure Build Path..." dialog. Adding a source folder would not let me reference the module's parent directory, which derailed me for a while. However,Link Source let me assign an arbitrary directory to use.
It's not ideal, but it seems to be working. We can now jump to definitions with F3, and errors are now highlighted correctly. It's good enough that I don't feel bad recommending it to the other team. I wish Eclipse would automatically allow a parent source directory to be referenced, but at least the manual intervention worked right.
When I commit a web appliction to source control should I also include the .project & .classpath files ? I don't think it should make any difference either way as other users who use the project should have the same project settings ?
This is the sort of question that gets people bent out of shape in a debate that never ends. You basically have two camps:
Only put source code into the source control system. Each developer chooses their own IDE and manages their own project configuration. Setting up your IDE after getting source code from the repository will be tricky. If one dev changes project dependencies, they have to explicitly communicate that so that all other devs update their project configurations. There are some tools that try to address this problem, like a Maven plugin that will attempt to generate Eclipse project metadata from pom.xml, but all have their limitations. Groups that go this way favor the purity of not restricting developer choice in IDE over the convenience of having Eclipse projects across the team that just work.
Standardize on Eclipse. Put all Eclipse project metadata into source control. This includes .project, .classpath and the entire contents of .settings. Basically, the only thing that you don't want in your source control repository is content marked as derived in Eclipse. You can check that in right-click->properties. Taking this approach ensures that developers can get started coding immediately after getting the project from source control. No additional configuration required. Also, when one dev changes project configuration, the rest of the team will see the same change on next sync.
Choose the approach that makes the most sense for your team.
For ClearCase, including the .project and .classpath can make a difference when you are using the IBM ClearCase plugin for Eclipse.
That plugin will work better if it can rely on those (versioned) files being there, right next to the sources (as opposed as being in the Eclipse workspace, which doesn't necessarily contains said sources).
In general, nothing generated should go into repository. Those files are generally generated by IDE or maven. However, sometimes you may need to click a button or execute a command to get those generated.
i would include them.
The .project file have plugin info (e.g. maven, ant, pdt, wst, aspectj, findbug..). It is essential if it is not a plain java project.
.classpath contain the classpath. it is needed if you use jar files.
I would say that all files - including .project and .classpath - should go to source control, to ensure that everyone in the team has the exact same setup.
Yet another multiple projects question, I know. I've seen (conflicting) answers to subsets of my goals but nothing that covers it all. I'm new to eclipse and don't know the dirty details of hg.
Given a common library jar, two apps and some common ant scripts...
I would set this up
/top/
build-common/
lib1/
app1/
app2/
I've read that eclipse doesn't do sub-projects so I think this would be 4 eclipse projects and "top" is nothing to eclipse.
I've read how to use ant for the eclipse builds including the auto build.
Is it good practice for the 3 java projects to reference ../build-common/{scripts} in their build.xmls? (when that's a different eclipse project)
Should app1 and app2 reference ../lib1/target/lib.jar? How?
If ant is doing the eclipse builds, do I still maintain .classpath (via whatever gui that was)?
I assume that eclipse users would not expect auto-build to propagate projects. Correct?
I'm unclear if having 4 eclipse projects forces 4 mercurial projects. IF the mercurialeclipse plugin supports it, I could make it one hg project ("top"). But I'm not sure of the pros and cons. Team->Commit might affect other eclipse projects -- would that be seem wrong to an eclipse user?
So, 4 or 1 hg projects?
Pre-eclipse, I would typically have a top level build.xml that builds the sub projects. Even if it's not needed for the eclipse builds, I want to support a full command-line build.
Where would a top level build.xml go?
Also, I suspect there are some nuances between having your code actually under the workspace/ directory or not. Can anyone explain what this means for my layout?
Thanks very much!
tlc
I've done this type of thing with CVS, but I'm not sure how with Mercurial. (I'm looking to switch to Mercurial too)
I can answer part of your questions.
With CVS, I would create one Eclipse project for /top/ and pull different modules into it as sub-directories. I don't know if MercurialEclipse support sub-repos or not, but that would be my first choice (1 Eclipse project, pull in sub-repos)
I think it is OK for each ant script to reference build-common if there is a lot of dependencies between /app1 and /app2. The other option is to have a build.xml in /app1, /app2, then a master build.xml in /build-common that just calls out to /app1 & /app2 and then wraps everything up in the end.
If you use an Ant script, you will also have to manually manage the Eclipse classpath. It isn't that difficult in my experience. If the classpath is setup in Eclipse, auto-build will just work.
I would prefer to have this structure:
/top/
/top/build.xml (references /app1/build.xml, /app2/build.xml)
/lib1
/app1/
/app1/build.xml (references ../lib1)
/app2
/app2/build.xml (references ../lib1)
The biggest question is MercurialEclipse and sub-repos. However, if it doesn't support sub-repos, just use Hg from the command-line until it catches up.
I used Maven before in quite a few projects but they we already configured by someone else. I quickly understood the main concepts (groups, artifacts and versions for jars, local and remote repositories) so I assumed that if I'm asked I'll be able to set up a new project from scratch easily.
That turned out not to be the case when I deal with multiple modules which depend on one another. I poked around maven docs but they are either way too concise or way too technical (sometimes I get a feeling that Maven people wrote it for themselves and not for Maven users). So I'm asking for community help.
Here's a typical scenario:
Three repositories:
My local repo at <User>/.m2
My company repo at http://maven.mycompany.com/repository
Maven Central at http://repo1.maven.org/maven2/
I'm building a normal Java EE project consisting of one EJB jar with a corresponding client jar, a web module and a JPA module (I like keeping my entities and all db-connectivity separated from business logic). That gives me 5 project in my IDE:
myapp-ear
myapp-ejb
myapp-ejb-client
myapp-jpa
myapp-web
myapp-jpa is used by myapp-ejb and myapp-web. myapp-ejb-client contains business interfaces for my EJBs.
How should I set all that up? I suspect that I need some kind of parent project but I'm not sure how should I organize inter-project dependency resolution. For example: currently when I specify
<dependency>
<groupId>com.mycompany.myapp</groupId>
<artifactId>myapp-jpa</artifactId>
<version>0.1-SNAPSHOT</version>
</dependency>
in myapp-ejb's pom.xml maven tries to search for it in my repository and tells me that the .jar can't be found. Even if I build and install all app components into my local repository one by one Maven always fails to build the ear file itself :(
I'd love to get it working under Eclipse or NetBeans.
I think you're on the right path. You need a parent project to pull it all together. In the parent project (and here is the important part) you need your dependencies laid out NOT in the dependency section of your parent pom, rather, you need them in your dependencyManagement section. Then, in your child pom's you can declare dependencies that are in the parent.
The only other gotcha (that I can think of) is that when you check the project using a version control system in Eclipse you need to remember to check the parent project out "as Maven project" otherwise the m2Eclipse plugin tends to freak out and not resolve things properly.
I hope this helps.
I have a Helpdesk application that contains modules that can be downloaded and installed separately as required / preferred by the users. The structure is very similar to many software such as Drupal, which modules can be loaded/unloaded easily.
I'm using a single SVN repository for this Helpdesk application and create different tags for each module. And on my Eclipse I have everything as a single project.
My question is, can a single Subversion repository managed as multiple projects in Eclipse?
Can I create one Eclipse project for the whole application and at the same time for each module?
Another requirement is that by splitting each module as a different project would make Eclipse builds faster.
The reason is, I want to delegate programming work of each module to another person without the need to expose everything. The person would only see & work on the module only but commit to the main repository.
I know that Eclipse will have configuration files for every project, would there be any conflict.
I've had good look storing multiple Eclipse projects in one repository. Each of the projects is stored in a separate folder under the repository's root. Then, I use Subclipse to check out each of those folders as a separate Eclipse project.
I do not think that you should nest Eclipse projects (so that a master project contains many sub-projects).
Instead of the master project, you could group the individual projects into what Eclipse calls a Team Project Set (found in the Export/Import menus). This is an XML file that defines where all the projects are. You can put that file into Subversion as well.
So, you would have all the module's projects, and that XML file (which is not a project itself), all in Subversion (could be the same repository, could be spread over several).
I don't believe this is strictly possible. Personally, I would split the modules up into different projects entirely, and I would probably use Eclipse's plugin structure to resolve dependencies between them and the main project. If you ship the plugins as jars, they're still modular. Then, you can control each plugin as a separate project in Eclipse, and a separate folder in SVN.
That is no problem at all! Just create your trunk/tags/branches structure on your svn repo. Create your differen projects and then check thos projects into your trunc folder on your svn system. Finished!