Workspace 2.0 Eclipse Maven Settings

Table of Contents

How to create an Eclipse project for a new Maven module

  1. File → Import... → Maven, Existing Maven Projects
  2. Root Directory: top dir of head repo clone (same as when you first set up Workspace 2.0)
    (Eclipse actually doesn't let you do that mistake, as existing modules are greyed anyway, remove?# make sure only your new module is checked)
  3. disable Maven Project Builder in Project > Properties > Builders
  4. create targetEclipse/.gitignore based on one from another Mifos module
  5. src/main/resources and src/test/resources shouldn't be listed as Source Folders on the Source tab in the Java Build Path, remove them from there
  6. add src/main/resources and src/test/resources via Add Class Folder in the Libraries tab of the Java Build Path project properties

If you have any doubt about the set-up of a new project, look at the Eclipse project configuration of other existing Mifos modules.

Someone else created a project for a new module. How do I add it into my workspace?

  1. File → Import... → General, Existing Projects into Workspace
  2. Root Directory: top dir of head repo clone (same as when you first set up Workspace 2.0)
  3. check new project

Other Details

MIFOS-4099 sub-tasks has some information which may be of "historical interest" re. how it all came about.

Maven settings for acceptance tests to avoid downloading Jetty by cargo

http://mifosforge.jira.com/wiki/display/MIFOS/Maven+Settings+Xml

Eclipse Workspace with individual projects for Maven modules (instead of current one big project)

The new workspace uses individual Eclipse projects for each Mifos Maven module. This became necessary because with the old workspace layout and the new m2e v0.12.0 (after an Update Dependencies), the Maven Dependencies Classpath Container (in Eclipse) remains empty (no JARs), or not shown, and all classes from JARs were (logically) "not found".

This configuration is also more common (AFAIK), and more suitable for future modularization. One particular advantage is that this permits "binary dependencies" to a Mifos module JAR in the local repository instead of Workspace Resolution - you can close some of the Eclipse projects, and M2E will simply switch other projects that depend from using the source project in the workspace to adding the module's binary JAR from the local repository to the classpath!

Root directory (mifos-parent pom.xml) and Eclipse

Eclipse doesn't support the Maven project layout convention of having a pom.xml in the root directory (e.g. mifos-parent) and its modules in respective sub-directories very well.

Some people & projects address this by physically putting the root pom.xml into a folder along-side the module directories. This solution is (was?) known to cause issues with some Maven plug-ins. Another approach is to open the root directory as a separate Maven project (this is what e.g. m2e proposes when using its Import Existing Maven Projects Wizard). That solution can confuse Eclipse though, leads to duplicate resources (validation/build/etc. issues), and e.g. on individual project imports (e.g. after a git clone; unless the right import Wizard is used?) leads to that " ... overlaps the location of another project: ..." issue.

Mifos instead keeps the mifos-parent pom.xml in the physical root directory, but still nicely integrates it (and other files in the root directory) in the workspace, by:

  • Having a physical folder named mifos-parent (under Source Control)
  • in that Project > Properties > Resource > Linked Resources, having added a new Path Variable ROOT_LOC = ${PROJECT_LOC}/..
  • create a number of Linked Resources, via File > New > File, Advanced, Link to file in the file system, Variables, ROOT_LOC, Extend...

This allows changes to the root mifos-parent pom.xml to be made from within Eclipse. Changes made to the root pom.xml in the ('virtual') mifos-parent are "live", because mifos-parent - even though not a Java project - is M2E-enabled, and thus participates in the 'Workspace resolution'. (So normally there is no need to do a mvn -N install and Maven > Update Dependencies on the other mifos projects to have them pick up changes made to the root pom.xml.)

PS: There is a very minor issue with eGit with this approach, watch https://bugs.eclipse.org/bugs/show_bug.cgi?id=333338

Eclipse Settings for Maven optimization

In the set-up created in MIFOS-4099   , the Maven Builder is not needed (we only want m2e's classpath container). In order to avoid useless Maven Builder spinning during Eclipse (re)builds, all Java projects should have:

  • Maven Project Builder disabled, in Project > Properties > Builders
  • No Excluded ** on Source Folders, in Project > Properties > Java Build Path
  • Empty (no) "Goals to invoke after project clean" & "Goals to invoke on resource changes", and checked/selected Skip Maven compiler plugin when processing resources, in Project > Properties > Maven > Lifecycle Mapping (just to be sure). You must NOT update project configuration, so answer No to "Maven settings have changed. Do you want to update project configuration?"

In order to further "lock out" any unnecessary interference of M2E in Eclipse' build, the root pom.xml also defines a custom minimalist M2E "Lifecycle Mapping". This is further outlined in a pom.xml.readme.txt accompanying the root mifos-parent pom.xml, and is based on https://docs.sonatype.org/pages/viewpage.action?pageId=2949459 / https://docs.sonatype.org/display/M2ECLIPSE/Maven+build+lifecycle / https://docs.sonatype.org/display/M2ECLIPSE/Customizable+build+lifecycle+mapping+for+m2e+extensions+developers. Also note https://bugs.eclipse.org/bugs/show_bug.cgi?id=351092.

(This should also make sure that, even if some of the settings above are lost, it still works as intended.)

Separate Eclipse and Maven build folders

It is best to completely separate the Eclipse Java Build Path output folder/s and the Maven CLI output folder (target/ directory). This avoids refresh problems and allows the two logically distinct use cases (in-IDE development and testing and CLI build & packaging operations) not to step onto each other's toes.

It turns out that it is actually possible to set things up to work just like this - through some hoops that are configured in Mifos, and described here as background documentation about this Maven set-up and for future reference:

  • varying.target.dir property, set to target by default
  • <build><directory>${basedir}/${varying.target.dir}
  • profile specific to m2e which overrides the varying.target.dir by e.g. targetEclipse
  • made sure (removed!) unnecessary hard-coded <outputDirectory>target/classes</outputDirectory> etc. in several Mifos pom.xml files
  • adapted all Projects Java Build Path output folders to use targetEclipse (.classpath), WITH the Maven standard classes/ respectively test-classes/ suffix!
  • verify that all is as expected by making sure that all modules Effective POM (open pom.xml files in Eclipse, use Effective POM tab by m2e) shows the expected <build> <outputDirectory> & <testOutputDirectory>

Note, again, that the Eclipse .classpath (Project > Properties > Java Build Path Output Folders) MUST match the value of the varying.target.dir property in in the m2e-specific profile in the pom.xml. Also the Eclipse Java Build Path Output Folders MUST still use classes/ & test-classes/ (unless you further override <outputDirectory> & <testOutputDirectory> appropriately).

This is also outlined in a pom.xml.readme.txt accompanying the root mifos-parent pom.xml. This is based on http://m2eclipse.sonatype.org/m2eclipse-faq.html#8 / https://docs.sonatype.org/display/M2ECLIPSE/Project+FAQ#ProjectFAQ-HowtoconfigureMavenprojecttouseseparateoutputfoldersinEclipse

Git configuration for targetEclipse

It's convenient if the targetEclipse directory already exists after a clone, because Eclipse does not create it by itself, unlike Maven for the target/ directory.

The targetEclipse directory is thus commited into the Git source control management repository, via a .gitignore containing two lines (classes & test-classes). targetEclipse should NOT be added into the top-level / root .gitignore.

Hiding the Maven build folder from Eclipse

Eclipse can normally Eclipse hide e.g. .class files it generated (which are now in targetEclipse), if you in e.g. Open Resource UNCHECK the Show Derived Resources option, available in the drop-down from the little arrow.

When you have separate Eclipse and Maven build folders, it is a bit annoying to see resource and .class files built by Maven (which are now in target) show up in Eclipse's e.g. Open Resource (Shift-Ctrl-R), or even in the Package Explorer view. Here is how to address that: Project > Properties, Resource > Resource Filters, Add.. Filter Type: Exclude All, Applies to: Folders, Name matches target.

Resources in Eclipse Class Folders instead of in Source Folders

To avoid "Copying Resources to the Output Folder" and make the workspace faster, src/main/resources & src/test/resources does actually not need to be a classical Project Source Folder. Instead, making them a Project > Properties > Java Build Path, Libraries tab, Add Class Folder.

The src/main/resources (but normally not src/test/resources) Class Folders should also by checked in the Java Build Path, Order and Export tab, so that they are exported to dependent projects, when m2e does dependency workspace resolution.

In the Package Explorer Eclipse view, Resources now show up under "References Libraries" (folder with a '010' icon).