Closed Tiller closed 10 months ago
Your projectB/.classpath
file seems not be created by Buildship. There should not exists a classpath entry with path /projectA
:
<classpathentry kind="src" path="/projectA">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
In Buildship, references to other projects and external dependencies are handled with the Gradle Classpath Container which is automatically added to the .classpath
file when importing or refreshing the Gradle project.
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
There should be no direct entry for projectA
in the file projectB/.classpath
.
The actual entries of the classpath container can be inspected in the Package or Project Explorer under the folder Project and External Dependencies:
With theses steps you can ensure that the projects will be correctly imported:
.classpath
and .project
files and all .settings
foldersHello, Indeed you're right, it works fine when importing the project as a gradle project.
However, it does not when using gradlew eclipse
+ Import existing project
. Do you know who we might reach for such issue? Is it an issue on gradle that generates a wrong classpath? Is it an issue on eclipse, not interpreting the without_test
correctly? Is it an issue on buildship because, even if the project is not imported as gradle project, my understanding was that buildship was still doing some magic?
For the last option, I've had this understanding because I had to tweak some classpath attributes to make other things work, such as gradle_used_by_scope
. And I mean, I don't think eclipse natively supports this attribute, does it? I've always believed that it was buildship that read these attributes and tweaked the run conf accordingly?
projectA/build.gradle
plugins {
id 'java-library'
id 'eclipse'
}
projectB/build.gradle
plugins {
id 'java-library'
id 'eclipse'
}
dependencies {
implementation project(':projectA')
}
After invoking ./gradlew eclipse
these files are created:
projectA/.classpath
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="output" path="bin/default"/>
<classpathentry output="bin/test" kind="src" path="src/test/java">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
</classpath>
projectB/.classpath
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="output" path="bin/default"/>
<classpathentry output="bin/test" kind="src" path="src/test/java">
<attributes>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
<classpathentry kind="src" path="/projectA">
<attributes>
<attribute name="without_test_code" value="true"/>
</attributes>
</classpathentry>
</classpath>
That looks correct and also importing these as normal projects (and not via Buildship) shows the expected behavior, e.g. the properties for projectB:
MyClass
from projectA
cannot be imported from MyOtherClass
in projectB
.
Could you provide a minimal reproducible example for your concrete case?
Thanks for checking this out.
The best way to reproduce the issue would be to clone https://github.com/sebkur/test-gradle-eclipse
You can tweak the gradle version in gradle-wrapper.properties
if you want, but I tested with both 7.4.2, 7.6.2 and 8.2.1. (with a more recent version of gradle, you'll need to remove the task sourcesJar and artifacts in build.gradle)
Then you run ./gradlew eclipse
and import project in eclipse as a regular project. In the properties of project "util", you'll see that it depends on core
without test code
.
But then, if you try to run test TestResources
in util
, it will fail at :
List<URL> testing = Resources.getAll("testing.txt");
Assert.assertEquals(1, testing.size());
Because it'll find both util/src/test/resources/testing.txt
and core/src/test/resources/testing.txt
. Where it should not have the second one in its classpath.
If you look at the generated command line, you can see the test classpath of core
:
Thank you for the detailed explanations.
The problem is independent of Gradle or Buildship and has to be solved in JDT Debug. I have created Issue #327 and provided pull request #328. I hope it will be accepted.
Since Buildship already handles the attribute Without test code correctly, this issue should be closed.
Thanks again for checking this out and for dispatching it (and fixing it!) to the correct project!
@Tiller The pull request #328 has been integrated and will be part of the upcoming Eclipse 2024-03 (release date 2024-03-13). Integration builds with this fix are already available.
Expected Behavior
Given the following project structure:
With projectB containing:
MyClass
andmyResource.txt
should not be in the test classpath ofprojectB
.MyOtherClass
shouldn't be able to accessMyClass
ormyResource.txt
Current Behavior
projectA/bin/test
is in the classpath ofprojectB
when running tests contained inMyOtherClass
.Eclipse's generated command line is :
even though .classpath contains:
Context
I'm having issues with some tests in projectB that does some reflection / classpath scanning that ends-up with test classes of projectA
Steps to Reproduce
User sebkur opened a strictly identical issue years ago (#1009) and provided a perfectly good example of the issue : https://github.com/sebkur/test-gradle-eclipse
In eclipse, test
TestResources.test()
fails because it sees a resource that is in the test classpath of a dependency.Your Environment
OS: Ubuntu 22.04 Gradle: tested with 7.4.2, 7.6.2 and 8.2.1 Eclipse: tested with 2023-03 and 2023-09, with buildship 3.1.7 (and the version that was shipped with 2023-03)