Search code examples
eclipsemavenm2eclipseworkspace

M2Eclipse & workspace project


In Eclipse Helios, the m2eclipse plugin doesn't include projects in my local workspace in any run configuration.

I've set up this test scenario:

ProjectA
+ src/main/java/a/TestInA.java
+ pom.xml

ProjectB
+ src/main/java/b/TestInB.java ("main()" calls "a.TestInA.main()")
+ pom.xml (includes reference to ProjectA)

The flag "Resolve dependencies from Workspace projects" is set on both projects. This works beautifully while compiling, i.e. compiler finds reference to "a.TestInA" in "b.TestInB", and the "Maven dependencies" list includes a reference to "ProjectA". But when I try to actually run "b.TestInB", I get a NoClassDefFoundError:

Exception in thread "main" java.lang.NoClassDefFoundError: a/TestInA
at b.TestInB.main(TestInB.java:13)
Caused by: java.lang.ClassNotFoundException: a.TestInA
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
... 1 more

Indeed, the system property "java.class.path" doesn't include ProjectA's "target/classes" folder (or any other folder for that matter).

These are my installed versions:

  • Eclipse: Helios Service Release 2 (build id: 20110301-1815)
  • m2eclipse: 0.12.1 (build id: 20110112-1712)

Solution

  • I finally found the error in my configuration. It had to do with the "archiverClassifier" in the workspace dependency. My POMs are set up to generate differently named artifacts depending on the running compiler.

    This is done using profiles for "jdk1.5" and "jdk1.6", setting the "archiverClassifier" variable:

    <profiles>
        <profile>
            <id>jdk1.5</id>
            <activation>
                <jdk>1.5</jdk>
            </activation>
            <properties>
                <compilerTarget>1.5</compilerTarget>
                <archiverClassifier>jdk1.5</archiverClassifier>
            </properties>
        </profile>
        <profile>
            <id>jdk1.6</id>
            <activation>
                <jdk>1.6</jdk>
            </activation>
            <properties>
                <compilerTarget>1.6</compilerTarget>
                <archiverClassifier>jdk1.6</archiverClassifier>
            </properties>
        </profile>
    </profiles>
    

    Then, in the dependency, I refer to the correct classifier using the "classifier" child, giving it the "archiverClassifier" variable previously set in the corresponding profile:

    <dependencies>
        <dependency>
            <groupId>com.brain2</groupId>
            <artifactId>ProjectA</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <classifier>${archiverClassifier}</classifier>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    

    If I remove the "classifier" child, m2eclipse's workspace dependency resolution works like a charm.

    Once I figured this out, a quick Google-search for "m2eclipse workspace resolution classifiers" landed me square on Sonatype's JIRA page for bug MNGECLIPSE-680. So I guess this is a bug, and I just answered my own question :)

    (On a side note, this issue doesn't arise for unit tests, where the dependency's "test-classes" directory is properly added to the classpath.)