Showing posts with label m2eclipse. Show all posts
Showing posts with label m2eclipse. Show all posts

29 August 2011

Eclipse Maven Integration Extensions

For me, the most important new feature in Eclipse 3.7.0 (Indigo) is the improved Maven Integration, formerly developed by Sonatype under the name of m2eclipse, now an official Eclipse subproject under the name of m2e.

m2eclipse and Eclipse sometimes used to have different opinions on what was going on in the workspace, and so we had to go through series of refresh/update dependencies/update configuration/rebuild voodoo (or "m2eclipse dance" as some called it) to get projects in a good state. (Quote from the m2e Wiki).

m2e has a different approach. First of all, it complains when detecting a Maven plugin in one of your POMs that it cannot handle out of the box. m2e flags your POM with an error marker that will not go away until you tell m2e what do to about the unknown plugin. The easy way out is a Quick Fix to ignore the plugin, which means you'll have to run the corresponding Maven goal manually when you need it.

However, when the Maven plugin in question generates source code or post-processes byte code, this is usually not sufficient - ideally, Eclipse and m2e should pick up the required build steps from your POM automatically.

This issue is addressed by m2e extensions, which provide the missing link between Eclipse project builders and Maven plugins. An m2e extension for a given Maven plugin not only invokes the required mojos but also informs Eclipse about new source or binary folders created by the mojos, so that Eclipse and Maven can stay in sync.

My projects use a number of Maven plugins that are not supported by m2e out of the box, e.g. for JAXB and OpenJPA, so I started creating some custom extensions for these plugins, based on a GitHub fork of the official m2e extensions from Sonatype.

See the wiki page at GitHub for more details. The GitHub project also contains an Eclipse update site (aka p2 repository) for installing the plugins. Time permitting, I'll try to make these extensions available via the Eclipse marketplace.

For any fixes, additions or new extensions, feel free to send my pull requests.

23 February 2010

Setting up Eclipse for Roller

There is an Eclipse plug-in for almost any task, and most of them do their job rather nicely. On the other hand, even some of the more or less official ones may give you a hard time if you try to use them in combination.

Recently, I've been playing around with Apache Roller, a Java blog engine, much like Blogger or Wordpress. This project is currently in beta for the next major release 5.0, so I checked out the sources from trunk, ran the Maven build, created a PostgreSQL database and got my own blog engine up and running within minutes.

Some minor things did not quite work as expected, so I thought I'd just create an Eclipse workspace for Roller and build and run it from there. As it turned out, the combination of Maven, Subversion, and a Web Application was a rather fatal mix, and it took me a day to figure out what was going wrong.

Most of this was not a Roller issue at all: Eclipse Web application tooling (WTP) and Maven Integration (m2eclipse) just make too many implicit and conflicting assumptions which make it hard to set things up correctly, so this article is really about working with a mavenized web application in Eclipse, and Roller is just an example.

There are a couple of threads on the Roller developer mailing list dealing with Eclipse setups, but none of them really provides a working solution, so maybe this post can fill gap.

Step 1: Get Eclipse and all required plug-ins


To avoid any conflicts with other plug-ins or features not required for this project, I used a separate Eclipse installation consisting of
  • Eclipse for Java EE Developers 3.5.1
  • Subversive SVN Team Provider 0.7.8
  • Subversive SVN Connectors 2.2.1
  • Maven Integration for Eclipse 0.10.0
  • Maven Integration for WTP 0.10.0
Even if you do not intend to commit any changes from Eclipse, you will need the Subversion integration to deploy your web application from a Subversion working copy, otherwise Eclipse will try to pack the hidden .svn directories into the JARs and WARs and complain about duplicate paths.

Step 2: Set up m2eclipse

m2eclipse has a built-in pre-release version of Maven 3.0.0 which is not compatible with most existing projects based on Maven 2.x. Get a local installation of Maven 2.1.0 and define it as default for m2eclipse in Window | Preferences | Maven | Installations.

Step 3: Set up Tomcat

Download and install Tomcat 6.0.24 to a local directory. Create a Tomcat server instance for Eclipse via Window | Preferences | Server | Runtime Environments pointing to your Tomcat installation directory.

Install the additional prerequisites of Roller in the Tomcat lib directory:
  • mail.jar
  • activation.jar
  • your JDBC driver

Step 4: Get Roller into your Eclipse workspace

Create a new empty workspace and switch to the SVN Repository Exploring perspective. There is supposed to be an integration of m2eclipse and Subversive, which I never managed to get to work, so this is why I use the following somewhat clumsy procedure to populate my workspace:
  • Switch to the SVN Repository Exploring perspective and define a new repository location for https://svn.apache.org/repos/asf.
  • Check out Roller from roller/trunk. This will create a new project roller-project in your workspace.
  • Unfortunately, the Maven modules of this project do not yet appear as separate Eclipse projects. To change this, delete the project from your workspace and use File | Import | Maven | Existing Maven Projects. Select the workspace folder from your initial checkout.
  • After this, you should have six Maven projects in your workspace, all shared via Subversive.

Step 5: Apply some fixes in the workspace

  • Go to roller-weblogger-business and delete src/test/resources/org/apache/roller/weblogger/business/package.html, since this file would cause a clash with another copy from src/main/resources.
  • Open /roller-weblogger-web/src/main/webapp/WEB-INF/security.xml and replace spring-security-2.0.1-openidfix.xsd by spring-security-2.0.4.xsd.
  • Copy your roller-custom.properties to /roller-weblogger-web/src/main/resources.

Step 6: Configure your web application

  • Open the project properties of roller-weblogger-web.
  • Select the Java EE Module Dependencies and activate roller-planet-business, roller-core and roller-weblogger-business.
  • Make sure that the resources from all dependent projects will get copied into the web application by modifying the build path settings of roller-planet-business, roller-weblogger-business and roller-weblogger-web. Select Java Build Path from the project properties and remove the Excluded: ** entry from src/main/resources for each of these projects.

Step 7: Run a Maven build

  • Select roller-project/pom.xml. From the context menu, select Run As | Maven build...
  • In the launcher dialog, fill in the goals clean install and (optionally) check Skip Tests to save some time during each build.
  • When the build has completed, select all projects and press F5 so that Eclipse will see all the resources created by Maven.
  • This step is required, since the Maven build generates some additional resources and runs the OpenJPA Enhancer. These two steps would not be handled by the Eclipse automatic build.

Step 8: Make sure that Eclipse picks up the generated resources

  • Create a folder /roller-weblogger-web/src/main/sql and turn it into a source folder.
  • Copy /roller-weblogger-business/target/dbscripts into this folder.

Step 9: Get Rolling!

  • Select roller-weblogger-web and invoke Run As | Run on Server from the context menu.
  • Select the Tomcat instance created in Step 3 and activate it as default if you like and click Finish.

Troubleshooting

  • If you get stuck, clean the Tomcat instance. Open the Servers view and select Tomcat. From the context menu, invoke Clean...
  • To check the web application assembled by Eclipse, have a look into <Eclipse workspace>/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/roller-weblogger-web/
All of this should have been a lot easier. m2eclipse will have to mature, and Eclipse should be more flexible about resource locations...