Extensible project configuration framework

Use cases

  • Initial import "as Maven project" or from New Maven project wizard
  • Project (re)configuration (Maven -> Update Project Configuration)
  • Enable Maven Dependency management (create pom.xml if not present)
  • Project Open

Open issues

  • Resolving conflicting/incompatible configurators (e.g. WTP vs. sysdedo)
  • support updating/generating pom.xml based on Eclipse project configuration (needed for enabling Maven support when pom.xml is missing)
  • UI to enable/disable individual configurators

Extension points

As of version 0.9.4 it is now possible to extend m2eclipse to support integration between Maven and other Eclipse-based tools, like WTP or AJDT. At high level, integration works by reading maven plugin configuration from pom.xml and applying it to Eclipse project.

projectConfigurators extension point - AbstractProjectConfigurator

The projectConfigurators extension point allows to register project configurator for specific Eclipse tools, that will participate in project import, configuration and reconfiguration.

Configurator implementation should extend AbstractProjectConfigurator, which provides the following callback methods:

#configure - called while configuring project during import or by user request (Maven -> Update Project Configuration). This callback can be used to add project natures and perform other "static" project configuration.

#mavenProjectChanged - called whenever there is a change in pom.xml, including changes to the set of transitive project dependencies. This callback can be used for "dynamic" changes that need to be applied automatically. For example, "Maven Dependencies" container can be reimplemented using this callback.

Configurators are invoked according to their "priority" attribute, configurations with smaller priority are invoked before configurators with bigger priority. Configurators without priority are invoked after all others.

classpathConfiguratorFactories extension point - AbstractClasspathConfigurator

The classpathConfiguratorFactories extension point allows to register configurator that can customize content of Maven Dependencies classpath container.

Configurator implementation should extend AbstractClasspathConfigurator:

#getAttributes - called for each container entry and allows integration plugins to add classpath attributes to the entry.

#configureClasspath - called after all container entries have been created can be used to add, remove and reorder the container entries.

Factory #createConfigurator method is called for Maven project when content of its Maven Dedepenencies classpath container is re/calculated.

Similar to projectConfigurators, classpathConfiguratorFactories and classpathConfigurators are invoked according to the value of the priority attribute.

AJDT integration

AJDT integration plugin (org.maven.ide.eclipse.ajdt) is reading aspectj-maven-plugin configuration from pom.xml file and applying it to AJDT project. See AjdtProjectConfigurator and AjdtClasspathConfigurator classes.

AjdtProjectConfigurator

AjdtProjectConfigurator adds AJDT nature to the project and sets most of AJDT configuration parameters for the project (as of 0.9.4, only adding nature is implemented). This class extends AbstractProjectConfigurator and is registered with m2eclipse using projectConfigurators extension point.

<extension point="org.maven.ide.eclipse.projectConfigurators">
    <configurator id="org.maven.ide.eclipse.ajdt"
        class="org.maven.ide.eclipse.ajdt.AjdtProjectConfigurator"
        name="AJDT"/>
  </extension>

Implementation of #configure method is quite simple

public void configure(MavenEmbedder embedder, ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException {
    if (PluginConfiguration.isAspectJProject(request.getMavenProject())) {
      addAjdtNature(request.getProject());
      // XXX confgiure other AJDT project parameters
    }
  }

AjdtClasspathConfigurator

AjdtClasspathConfigurator uses classpath attributes to mark Maven Dependencies classpath entries for inclusion in inpath/aspectpath (as of 0.9.4, only aspectpath is implemented). Implementation of #getAttributes is straightforward

public Set getAttributes(Artifact artifact, int kind) {
    String key = artifact.getGroupId() + ":" + artifact.getArtifactId();
    Set aspectLibraries = config.getAspectLibraries(); // from pom.xml
    if(aspectLibraries != null && aspectLibraries.contains(key)) {
      return ASPECTPATH_ATTRIBUTES;
    }
    return null;
  }

AJDT integration plugin registers AjdtClasspathConfiguratorFactory with m2eclipse using classpathConfiguratorFactories extension point. Factory #createConfigurator method is called for Maven project when content of its Maven Dedepenencies classpath container is re/calculated.

<extension point="org.maven.ide.eclipse.classpathConfiguratorFactories">
    <classpathConfiguratorFactory id="org.maven.ide.eclipse.ajdt.classpathConfiguratorFactory"
        class="org.maven.ide.eclipse.ajdt.AjdtClasspathConfiguratorFactory"
        priority="1000"/>
 </extension>

WTP integration

The WTP integration plugin (org.maven.ide.eclipse.wtp) is using the same idea as AJDT integration - take maven-war/ejb/ear-plugin configuration from pom.xml and apply it to WTP project (as of 0.9.4, only WAR is supported). See mini howto.

WTP 2.0 supports several has several special classpath configuration requirements:

Maven Dependencies container requires classpath attribute to be considered by WTP
Test/runtime/provided dependencies have to be specifically excluded using classpath attribute
Workspace dependencies have to be configured as WTP module dependencies

WTPProjectConfigurator

WTPProjectConfigurator overrides #configure method to configure WTP "facets" and other parameters of WTP projects, including dependencies between different workspace projects.

public void configure(MavenEmbedder embedder, ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException {
    MavenProject mavenProject = request.getMavenProject();
    if(WarPluginConfiguration.isWarProject(mavenProject)) {
      IProject project = request.getProject();
      configureWtpWar(project, monitor);
      setModuleDependencies(project, mavenProject, monitor);
    }
  }

It also overrides #mavenProjectChanged method that is invoked each time maven project or any of its transitive dependencies changes. This allows WTP integration plugin keep J2EE module dependencies in sync with pom.xml

protected void mavenProjectChanged(MavenProjectChangedEvent event, IProgressMonitor monitor) throws CoreException {
    MavenProjectFacade facade = event.getMavenProject();
    IProject project = facade.getProject();
    if (isWTPProject(project)) {
      setModuleDependencies(project, facade.getMavenProject(), monitor);
    }
  }

WTPClasspathConfigurator

WTPClasspathConfigurator overrides the following methods:

#getAttributes marks test/system/provided attributes to be ignored by WTP.

public Set getAttributes(Artifact artifact, int kind) {
    String scope = artifact.getScope();
    // Check the scope & set WTP non-dependency as appropriate
    if(Artifact.SCOPE_PROVIDED.equals(scope) 
        || Artifact.SCOPE_TEST.equals(scope)
        || Artifact.SCOPE_SYSTEM.equals(scope)) 
    {
      return NONDEPENDENCY_ATTRIBUTES;
    }
    return null;
  }

#configureClasspath removes workspace dependencies (i.e. other Eclipse projects) from Maven Dependencies container. This method is called after container entries have been collected and classpath configurator "final word" on what gets in and what does not.

public void configureClasspath(Map entries) {
    // WTP 2.0 does not support workspace dependencies in thirdparty classpath containers
    for(Iterator<IClasspathEntry> it = entries.values().iterator(); it.hasNext();) {
      IClasspathEntry entry = it.next();
      if(IClasspathEntry.CPE_PROJECT == entry.getEntryKind()) {
        it.remove();
      }
    }
  }

MavenProjectConfigurator

Generic project configurator that runs maven goal to generate Eclipse metadata based on pom.xml

<extension point="org.maven.ide.eclipse.projectConfigurators">
  <configurator id="org.maven.ide.eclipse.configurator.sysdeo"
     class="org.maven.ide.eclipse.project.configurators.MavenConfigurator:org.codehaus.mojo:sysdeo-tomcat-maven-plugin:1.0|sysdeo-tomcat:generate"
     name="SysdeoTomcat" priority="20"/>
</extension>
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.