The Eclipse + Maven problem
In contemporary Java development, there is a trilogy of unfortunate truths:
- Eclipse is the most predominant IDE
- Maven is the most predominant build system
- Eclipse and Maven don’t work very well together
The main problem is that both of these tools are very opinionated about how projects should be built. Maven has a steep learning curve, and can really dish out punishment should you stray too far from “The Maven Way”.
Meanwhile, unlike NetBeans (which integrates tightly with Maven or Ant), Eclipse is very much entrenched with its own internal build system. An external build tool such as Maven must be translated into “The Eclipse Way”.
Basic approaches
There are two main strategies for handling this. The original approach uses the eclipse:eclipse Maven plugin, which pushes your POM settings into Eclipse project config files. A newer approach flows the other way, using an Eclipse plugin such as m2eclipse to pull in your POM settings.
Either way, the basic idea is the same. Eclipse only understands Eclipse, so your Maven build configuration must be translated. For most “straight down the middle” project builds, this works fine. However, as you apply customizations to your build, things can get lost in translation.
More advanced problems
I ran into such a problem earlier today. The full discussion is posted here at StackOverflow, but the basic gist is that my application uses an include file having different versions for each environment (i.e. one for production, one for the test server, etc).
I configured Maven to build a WAR with the appropriate include file for each build profile. Maven handles this beautifully… copying the correct file to the exploded “target” directory, and then bundling it up into a WAR from there.
However, when I test my application through an Eclipse-managed Tomcat instance, the include file is not there. As it turns out, Eclipse does not load files into Tomcat from the Maven “target” directory. Eclipse does its own thing instead, and was oblivious to the Maven kung-fu I had configured.
Using Web Deployment Assembly settings to help
Fortunately, someone on Stack Overflow pointed out an Eclipse feature that I had never noticed before. If you right-click on your web application project, and select “Properties”, one of the numerous sections available is “Deployment Assembly”:
Through this section, you can give Eclipse custom information about which files should be deployed to Tomcat (or bundled into a WAR, if for some reason you had Eclipse do that rather than simply the Maven-generated one). Therefore, if you are doing some funky assembly in Maven, you can tell Eclipse to pick that up. Just add a new row here, with the “source” path looking something like this:
/target/MyApp/my-path-to-include-file
Of course, it would be better if this step weren’t necessary, and Eclipse pointed toward Maven output by default. I can see the reasons why they don’t, though:
- 99% percent of the time Maven is simply copying files from “
/src
” to “/target
” anyway, so Eclipse can get away with looking at “/src
” by default. - For the “
/target
” directory to always be up-to-date automatically, Maven would have to run in the background every time a file changed. Maven is way too slow and memory-hungry for that to be feasible. - Without Maven running in the background, you would have to remember to run Maven manually or else your Eclipse-driven deployments won’t be valid. Eclipse will look for a “
/target
” directory that could be outdated, or might not exist at all.
However, in those cases where you have Maven doing some manipulation on the files, such that “/src
” will not be the same as “/target
“… then it’s good to have the ability to point Eclipse toward “/target
” on a per-project module basis. Just remember to run your Maven build prior to having Eclipse republish your application on Tomcat.