Hello Everyone,
I have discovered a problem with the treatment of classifiers by m2e.
As we are all aware, Eclipse has only a single classpath concept, and to work around this, m2e merges both test and compile classpaths into one big classpath so that eclipse can compile everything in src/main and src/test successfully. (Otherwise we would get lovely red X's in tests that depend on "test" scoped dependencies.) Classifiers are also ignored here for projects in the workspace, and all classes from a classified workspace dependency are added to this classpath.
To the point, this is not the case when launching JUnit test configurations "Run As -> JUnit Test"
In this case, m2e actually sets the JUnit classpath to omit any classified dependency projects that in the case of non-classified dependencies, are resolved normally via workspace resolution.
I can provide simple steps to reproduce if you would like to see the problem first-hand.
In effect:
- Eclipse compile time: Classified workspace dependencies are on the classpath.
- Eclipse JUnit launch: Classified workspace dependencies are *not* on the classpath.
Summary:
- Eclipse compilation succeeds. Everything looks good, no problems reported in workspace.
- JUnit run fails to launch. Caused by: java.lang.ClassNotFoundException for classes that should be provided by the classified workspace project dependency.
Problems:
While I understand that it is actually difficult to determine the actual classes that should be on the classpath, without having access to the final classified JAR, this introduces an extremely odd and difficult to debug situation for the user. A Maven CLI build is the ultimate source of truth, and since m2e has already "cheated" and merged classpaths to work around the eclipse compile classpath issue, I find it is far more confusing to add yet another level of inconsistency. In this case, m2e is inconsistent with its own inconsistency with Maven. And that's starting to be exponential inconsistency, which isn't good ;)
To add additional frustration, unlike the eclipse "Maven Dependencies" classpath entry, the test-classpath is only visible when editing the launch configuration; therefore, even finding the problem is difficult - who would think to edit the junit launch config for your project to solve: "Caused by: java.lang.ClassNotFoundException" ?
Most of the time, when depending on a classified artifact, you want something out of that artifact, otherwise you would not depend on it at all. Because m2e basically says, "It's classified, and I don't know what's in it so I'm not going to include it," it basically breaks 100% of all classifiers on the test classpath, instead of breaking 1%, which would be caught by the mvn CLI build anyway, and letting the 99% succeed.
Recommendation:
Anyway, I'm not sure if this was intentional or just an oversight, but my recommendation would simply be to make the m2e test classpath behave like the compile classpath already does. It does not make sense to do otherwise IMO - it's feels inconsistent and weird..