Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 352962

Summary: <type>test-jar</type> no longer resolves to proper dependent classpath
Product: z_Archived Reporter: Mark A. Ziesemer <bugs>
Component: m2eAssignee: Project Inbox <m2e.core-inbox>
Status: RESOLVED FIXED QA Contact:
Severity: major    
Priority: P3 CC: andreas, igor, miguel, rademacher, st.oehme
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
Minimal project demonstrating the issue.
none
m2e Debug Output version of Comment #4. none

Description Mark A. Ziesemer CLA 2011-07-24 21:54:06 EDT
Reference:  http://maven.apache.org/guides/mini/guide-attached-tests.html

I have 2 projects, and am trying to make both the source and test artifacts from one to the other in the test scope.  However, the test classes are not being found when using workspace resolution.  I can only get the tests to run when first doing a local install on the dependent projects and disabling workspace resolution.

This was working previously (maybe in 0.13?) when I had <classifier>tests</classifier> included in the dependency.  Following the above referenced Maven documentation, I tried updating this to <type>test-jar</type> - however, neither works properly under m2e 1.0.0 and Eclipse 3.7.

By running the build with "Debug Output", I can see that the \target\classes folder is being put on the classpath twice - once for the source, and another for the test-source.  However, per the m2e-controlled Eclipse configuration on all my projects, the sources have their output folder set to "target/classes", and the test sources have their output set to "target/test-classes".  Removing <type>test-jar</type> removes the duplicate classpath entry shown in the debug output.  As such, it seems pretty clear that m2e is not properly resolving the output folder of the test sources.

Versions:
* m2e - Maven Integration for Eclipse	1.0.0.20110607-2117	org.eclipse.m2e.feature.feature.group	Eclipse.org - m2e
* Indigo 20110615-0604
Comment 1 Mark A. Ziesemer CLA 2011-07-24 22:01:09 EDT
Appears to be related to one or more of the following:

* https://issues.sonatype.org/browse/MNGECLIPSE-2352 : test-jar dependency not available at runtime
* https://issues.sonatype.org/browse/MNGECLIPSE-2286 : Workspace resolution not working for test-jar dependency
* https://issues.sonatype.org/browse/MECLIPSEWTP-50 : test-jar resolution does not work when deploying with WTP
Comment 2 Igor Fedorenko CLA 2011-07-25 01:00:50 EDT
I am unable to reproduce the problem. I manually tested workspace compilepath resolution and it works as expected for type=test-jar dependencies. Runtime classpath is covered by unit test [1] and works during manual testing as well. 

Please reopen the bug if you can provide standalone sample project and steps to reproduce the problem.


[1] https://github.com/sonatype/m2e-core-tests/tree/master/org.eclipse.m2e.tests/projects/runtimeclasspath/testscope05
Comment 3 Igor Fedorenko CLA 2011-07-25 01:04:17 EDT
oops, wrong resolution, I really meant WORKSFORME
Comment 4 Mark A. Ziesemer CLA 2011-07-25 10:10:45 EDT
Created attachment 200281 [details]
Minimal project demonstrating the issue.

The attached project contains 2 projects - "MavenProjectA" and "MavenProjectB".  A's compile-time classpath depends on B's default classpath.  A's test-time classpath depends on B's test-jar.

After importing both projects into an Eclipse workspace, run AClassTest as a JUnit test, and observe that it successfully completes.

Then do a Maven build... on MavenProjectA, using goals "clean package", with "Resolve Workspace artifacts" checked, then observe the following failure:

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building mavenProjectA 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ mavenProjectA ---
[INFO] Deleting M:\Mark\Eclipse\mavenProjectA\target
[INFO] 
[INFO] --- maven-resources-plugin:2.4.3:resources (default-resources) @ mavenProjectA ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ mavenProjectA ---
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to M:\Mark\Eclipse\mavenProjectA\target\classes
[INFO] 
[INFO] --- maven-resources-plugin:2.4.3:testResources (default-testResources) @ mavenProjectA ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ mavenProjectA ---
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file to M:\Mark\Eclipse\mavenProjectA\target\test-classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] \Mark\Eclipse\mavenProjectA\src\test\java\com\ziesemer\test\a\AClassTest.java:[5,26] cannot find symbol
symbol  : class BClassTest
location: package com.ziesemer.test.b
[ERROR] \Mark\Eclipse\mavenProjectA\src\test\java\com\ziesemer\test\a\AClassTest.java:[7,32] cannot find symbol
symbol: class BClassTest
public class AClassTest extends BClassTest{
[INFO] 2 errors 
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.413s
[INFO] Finished at: Mon Jul 25 09:03:50 CDT 2011
[INFO] Final Memory: 12M/153M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:testCompile (default-testCompile) on project mavenProjectA: Compilation failure: Compilation failure:
[ERROR] \Mark\Eclipse\mavenProjectA\src\test\java\com\ziesemer\test\a\AClassTest.java:[5,26] cannot find symbol
[ERROR] symbol  : class BClassTest
[ERROR] location: package com.ziesemer.test.b
[ERROR] \Mark\Eclipse\mavenProjectA\src\test\java\com\ziesemer\test\a\AClassTest.java:[7,32] cannot find symbol
[ERROR] symbol: class BClassTest
[ERROR] public class AClassTest extends BClassTest{
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

A complete "Debug Output" version of the same will also be attached, but includes the following lines:

[DEBUG] Output directory: M:\Mark\Eclipse\mavenProjectA\target\test-classes
[DEBUG] Classpath:
[DEBUG]  M:\Mark\Eclipse\mavenProjectA\target\test-classes
[DEBUG]  M:\Mark\Eclipse\mavenProjectA\target\classes
[DEBUG]  M:\Mark\Eclipse\mavenProjectB\target\classes
[DEBUG]  M:\Downloads\Java\maven\junit\junit\4.8.2\junit-4.8.2.jar
[DEBUG]  M:\Mark\Eclipse\mavenProjectB\target\classes

Note how "mavenProjectB\target\classes" is included twice - where one of them should be "mavenProjectB\target\test-classes".

As a "minimal" test project, I did not make any additional project configurations, etc. - including adding the test-jar goal on mavenProjectB as per http://maven.apache.org/guides/mini/guide-attached-tests.html .  However, doing so does not currently provide any impact on these test results.

(Another thing to note is once the Maven build fails (at least due to using "clean package"), at least some of the *.class files no longer exist, and re-running the JUnit tests from Eclipse will fail - at least until doing an Eclipse Clean on the projects.)

I actually hope I'm just missing something simple here.  However, given that the other 3 referenced tickets were still in unresolved status, this sure seems like it is still an open issue.

Thanks!
Comment 5 Mark A. Ziesemer CLA 2011-07-25 10:12:46 EDT
Created attachment 200282 [details]
m2e Debug Output version of Comment #4.
Comment 6 Mark A. Ziesemer CLA 2011-07-25 10:13:35 EDT
Re-opening as per Comment #2.
Comment 7 Igor Fedorenko CLA 2011-07-26 01:34:14 EDT
I am able to reproduce the problem now, thank you. The problem only affects workspace resolution for maven builds executed in external jvm. There are currently no plans to fix this unless somebody provides a quality patch.
Comment 8 Mark A. Ziesemer CLA 2011-07-26 08:59:56 EDT
(In reply to comment #7)
> The problem only affects workspace resolution for maven builds executed in external jvm.

Is there a way to not run the maven builds in an external JVM, such that it would qualify as a work-around (other than disabling workspace resolution entirely, and doing local installs)?

By default, on the "Run Configuration" dialog, on the "JRE" tab, "Workspace default JRE" is already selected by default.  I know that doesn't seem to imply running internally or externally of the workspace JVM, but I don't see any other options to control this - at least not on the UI of this dialog, or the Maven preferences in Eclipse.

> There are currently no plans to fix this unless somebody provides a quality patch.

I would urge you to reconsider - especially given the interest shown by the unresolved tickets linked to from Comment #1, as well as their related tickets and forum posts.

Given my concern for this issue, I'll consider investigating a patch - but any details or guidance you could provide around this would be appreciated.  I.E., how did you find that this is related to internal/external JVM, and why would this have any impact?

Thanks!!
Comment 9 Igor Fedorenko CLA 2011-07-26 11:10:32 EDT
m2e maintains information about all workspace maven artifacts in a file on filesystem (.metadata/.plugins/org.eclipse.m2e.core/workspacestate.properties to be specific). 

This file is maintained by org.eclipse.m2e.core.internal.project.WorkspaceStateWriter and is basically a map from groupId:artifactId:type:version of workspace artifacts to their corresponding filesystem location. For type=pom the map points at the pom file itself, for type=jar it points to project's target/classes folder.

m2e injects one extra jar file into the maven classpath for builds executed in external jvm. For maven 2.x runtimes this jar is org.eclipse.m2e.launching/org.eclipse.m2e.cliresolver.jar and for maven 3.0.x runtimes it is org.eclipse.m2e.launching/org.eclipse.m2e.cliresolver30.jar. The jars are built from [1] and [2] respectively. 

These jars contribute additional components to maven runtime, which read workspacestate.properties and participate in dependency resolution logic.

Please ask any further questions you might have on m2e-dev mailing list.


[1] http://git.eclipse.org/c/m2e/m2e-core.git/tree/org.eclipse.m2e.cliresolver
[2] http://git.eclipse.org/c/m2e/m2e-core.git/tree/org.eclipse.m2e.cliresolver30
Comment 10 Andreas Bergander CLA 2012-04-16 06:05:48 EDT
Would it be enough to add the test-jar to workstate.properties by adding this code to mavenProjectChanged(...) in WorkspaceStateWriter.java:


IResource testOutputLocation = root.findMember(projectFacade.getTestOutputLocation());

if(!"pom".equals(artifact.getType()) && testOutputLocation != null && testOutputLocation.exists()) { //$NON-NLS-1$
          
    String testKey = artifact.getGroupId()
                + ":" + artifact.getArtifactId() + ":test-jar:" + artifact.getBaseVersion(); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

    state.put(testKey, testOutputLocation.getLocation().toFile().getCanonicalPath());
}
Comment 11 Igor Fedorenko CLA 2012-04-16 14:42:05 EDT
I am not sure, but I think that's only one half of the solution. The other half is to change org.eclipse.m2e.cliresolver and org.eclipse.m2e.cliresolver30 to actually use the new information.
Comment 12 Andreas Bergander CLA 2012-04-17 09:17:08 EDT
I might be wrong, but I think the resolvers are fine. They just resolves what is in the workspacestate.properties using the input arguments. Perhaps the input arguments are wrong?

I'm guessing there are two problems. First, the 'Maven Dependencies' classpath container uses the entire project as a dependency. It should only include the test classes if the test-jar type is specified.

In DefaultClasspathManagerDelegate.java in the method addClasspathEntries the project dependency is found without considering the artifact type. Perhaps this method should handle type jar and test-jar separately and use the outputLocation and testOutputLocation of the project instead of fullPath?

The second problem occurs when launching a maven configuration. For some reason that is unknown to me it only resolves the type jar artifact. The test-jar is only included in the classpath if workspace resolution is disabled. Also, if the dependency list only contains test-jar then it has the same effect as only having type jar, i.e. it resolves to the target/classes directory. Any ideas where in the code this happens? Why is the type jar used even though test-jar is specified? How can we make sure that test-jar is handled separately and resolves to target/test-classes instead?
Comment 13 Stefan Oehme CLA 2013-03-08 08:01:19 EST
Has there been any progress on this issue? This currently forces us to disable some plugin executions that would otherwise be good candidates for running on project import. 

For example, we generate a text file containing the project's classpath for the FitNesse testing tool. This classpath misses the test-classes folder of dependencies in the workspace and instead lists the classes folder twice.

Disabling workspace resolution fixes the missing artifacts, but also prevents us from hot-replacing the code that the testing system uses. Instead we need to run mvn install on the project under test.
Comment 14 Igor Fedorenko CLA 2013-03-08 09:16:39 EST
no, nobody provided a patch to address this problem yet
Comment 15 Igor Fedorenko CLA 2014-02-01 16:44:16 EST
Fixed. No tests so can easily break given that I didn't need this feature until last night and most likely won't need for as much longer either. 

http://git.eclipse.org/c/m2e/m2e-core.git/commit/?id=c932966a80b98d9c7aeb48e0341bb8ffcc2cad54
Comment 16 Mark A. Ziesemer CLA 2014-02-02 14:48:43 EST
Thanks, Igor!
Comment 17 Denis Roy CLA 2021-04-19 13:25:09 EDT
Moved to https://github.com/eclipse-m2e/m2e-core/issues/