diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/M2EUtils.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/M2EUtils.java
index 98a006473e..5f6530ac55 100644
--- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/M2EUtils.java
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/M2EUtils.java
@@ -25,7 +25,6 @@
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@@ -47,13 +46,17 @@ public class M2EUtils {
* @param monitor the progress monitor
* @throws CoreException if creating the given folder
or any of its parents fails.
*/
- public static void createFolder(IFolder folder, boolean derived, IProgressMonitor monitor) throws CoreException {
+ public static void createFolder(IContainer container, boolean derived, IProgressMonitor monitor)
+ throws CoreException {
+ if(!(container instanceof IFolder folder)) {
+ return; // don't create projects
+ }
// Recurse until we find a parent folder which already exists.
if(!folder.exists()) {
IContainer parent = folder.getParent();
// First, make sure that all parent folders exist.
if(parent != null && !parent.exists()) {
- createFolder((IFolder) parent, false, monitor);
+ createFolder(parent, false, monitor);
}
try {
if(!folder.exists()) {
diff --git a/org.eclipse.m2e.jdt.tests/projects/add-source-resource/parent/src/main/java/A.java b/org.eclipse.m2e.jdt.tests/projects/add-source-resource/parent/src/main/java/A.java
new file mode 100644
index 0000000000..83b86122f3
--- /dev/null
+++ b/org.eclipse.m2e.jdt.tests/projects/add-source-resource/parent/src/main/java/A.java
@@ -0,0 +1,5 @@
+import java.io.Serializable;
+
+class A implements Serializable {
+
+}
diff --git a/org.eclipse.m2e.jdt.tests/projects/add-source-resource/parent/src/main/resources/res.txt b/org.eclipse.m2e.jdt.tests/projects/add-source-resource/parent/src/main/resources/res.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/org.eclipse.m2e.jdt.tests/projects/add-source-resource/parent/src/test/java/ATest.java b/org.eclipse.m2e.jdt.tests/projects/add-source-resource/parent/src/test/java/ATest.java
new file mode 100644
index 0000000000..396f5b59a4
--- /dev/null
+++ b/org.eclipse.m2e.jdt.tests/projects/add-source-resource/parent/src/test/java/ATest.java
@@ -0,0 +1,5 @@
+import java.io.Serializable;
+
+class ATest implements Serializable {
+
+}
diff --git a/org.eclipse.m2e.jdt.tests/projects/add-source-resource/parent/src/test/resources/test.txt b/org.eclipse.m2e.jdt.tests/projects/add-source-resource/parent/src/test/resources/test.txt
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/org.eclipse.m2e.jdt.tests/projects/add-source-resource/pom.xml b/org.eclipse.m2e.jdt.tests/projects/add-source-resource/pom.xml
new file mode 100644
index 0000000000..b77a70ef1c
--- /dev/null
+++ b/org.eclipse.m2e.jdt.tests/projects/add-source-resource/pom.xml
@@ -0,0 +1,13 @@
+
+
+ 4.0.0
+ foo.bar
+ add-source-resource
+ 0.0.1-SNAPSHOT
+ pom
+
+ submoduleA
+
+
diff --git a/org.eclipse.m2e.jdt.tests/projects/add-source-resource/submoduleA/pom.xml b/org.eclipse.m2e.jdt.tests/projects/add-source-resource/submoduleA/pom.xml
new file mode 100644
index 0000000000..1424093bf6
--- /dev/null
+++ b/org.eclipse.m2e.jdt.tests/projects/add-source-resource/submoduleA/pom.xml
@@ -0,0 +1,80 @@
+
+
+ 4.0.0
+ foo.bar
+ submoduleA
+ 0.0.1-SNAPSHOT
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.10.1
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+
+
+ java
+ generate-sources
+
+ add-source
+
+
+
+ ../parent/src/main/java
+
+
+
+
+ test
+ generate-sources
+
+ add-test-source
+
+
+
+ ../parent/src/test/java
+
+
+
+
+ resources
+ generate-resources
+
+ add-resource
+
+
+
+
+ ../parent/src/main/resources
+
+
+
+
+
+ test-resources
+ generate-resources
+
+ add-test-resource
+
+
+
+
+ ../parent/src/test/resources
+
+
+
+
+
+
+
+
+
diff --git a/org.eclipse.m2e.jdt.tests/src/org/eclipse/m2e/jdt/tests/JavaConfigurationTest.java b/org.eclipse.m2e.jdt.tests/src/org/eclipse/m2e/jdt/tests/JavaConfigurationTest.java
index e56ccb6798..f447a1120d 100644
--- a/org.eclipse.m2e.jdt.tests/src/org/eclipse/m2e/jdt/tests/JavaConfigurationTest.java
+++ b/org.eclipse.m2e.jdt.tests/src/org/eclipse/m2e/jdt/tests/JavaConfigurationTest.java
@@ -20,6 +20,8 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
import java.util.function.Predicate;
import org.eclipse.core.resources.IFile;
@@ -29,12 +31,14 @@
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.internal.preferences.MavenConfigurationImpl;
+import org.eclipse.m2e.core.project.ResolverConfiguration;
import org.eclipse.m2e.tests.common.AbstractMavenProjectTestCase;
import org.junit.Before;
import org.junit.Test;
@@ -124,7 +128,6 @@ public void testSkipNone() throws CoreException, IOException, InterruptedExcepti
assertEquals(1, classpathEntriesCount(project, TEST_RESOURCES));
}
-
@Test
public void testComplianceVsEnablePreviewSettings() throws CoreException, IOException, InterruptedException {
IJavaProject project = importResourceProject("/projects/compilerEnablePreviewSettings/pom.xml");
@@ -132,6 +135,32 @@ public void testComplianceVsEnablePreviewSettings() throws CoreException, IOExce
assertEquals(JavaCore.ENABLED, project.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, false));
assertEquals(JavaCore.IGNORE, project.getOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, false));
}
+
+ @Test
+ public void testAddSourceResource() throws CoreException, IOException, InterruptedException {
+ File baseDir = new File(FileLocator
+ .toFileURL(JavaConfigurationTest.class.getResource("/projects/add-source-resource/submoduleA/pom.xml"))
+ .getFile()).getParentFile().getParentFile();
+ waitForJobsToComplete();
+ IProject project = importProjects(baseDir.getAbsolutePath(), new String[] { "submoduleA/pom.xml" },
+ new ResolverConfiguration())[0];
+ waitForJobsToComplete();
+ IJavaProject javaProject = JavaCore.create(project);
+
+ List srcEntryPaths = Arrays.stream(javaProject.getRawClasspath())
+ .filter(cp -> IClasspathEntry.CPE_SOURCE == cp.getEntryKind()).filter(cp -> !cp.isTest())
+ .map(IClasspathEntry::getPath).map(IPath::toString).toList();
+ assertEquals(Set.of("/submoduleA/src/main/java", "/submoduleA/src/main/resources", //
+ "/submoduleA/.._parent_src_main_java", "/submoduleA/.._parent_src_main_resources"),
+ Set.copyOf(srcEntryPaths));
+ List testEntryPaths = Arrays.stream(javaProject.getRawClasspath())
+ .filter(cp -> IClasspathEntry.CPE_SOURCE == cp.getEntryKind()).filter(cp -> cp.isTest())
+ .map(IClasspathEntry::getPath).map(IPath::toString).toList();
+ assertEquals(Set.of("/submoduleA/src/test/java", "/submoduleA/src/test/resources", //
+ "/submoduleA/.._parent_src_test_java", "/submoduleA/.._parent_src_test_resources"),
+ Set.copyOf(testEntryPaths));
+ }
+
// --- utility methods ---
private static final Predicate TEST_SOURCES = cp -> cp.isTest()
diff --git a/org.eclipse.m2e.jdt/META-INF/MANIFEST.MF b/org.eclipse.m2e.jdt/META-INF/MANIFEST.MF
index d44e80dc90..32e3bdcc06 100644
--- a/org.eclipse.m2e.jdt/META-INF/MANIFEST.MF
+++ b/org.eclipse.m2e.jdt/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: org.eclipse.m2e.jdt;singleton:=true
-Bundle-Version: 2.3.3.qualifier
+Bundle-Version: 2.3.400.qualifier
Bundle-Localization: plugin
Export-Package: org.eclipse.m2e.jdt,
org.eclipse.m2e.jdt.internal;x-friends:="org.eclipse.m2e.jdt.ui",
diff --git a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/AbstractJavaProjectConfigurator.java b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/AbstractJavaProjectConfigurator.java
index 593febb513..a793c999d2 100644
--- a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/AbstractJavaProjectConfigurator.java
+++ b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/AbstractJavaProjectConfigurator.java
@@ -14,6 +14,9 @@
package org.eclipse.m2e.jdt.internal;
import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -30,9 +33,11 @@
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
@@ -134,6 +139,9 @@ public abstract class AbstractJavaProjectConfigurator extends AbstractProjectCon
protected static final String DEFAULT_COMPILER_LEVEL = "1.5"; //$NON-NLS-1$
+ private static final QualifiedName LINKED_MAVEN_RESOURCE = new QualifiedName(MavenJdtPlugin.PLUGIN_ID,
+ "linkedSource");
+
@Override
public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException {
IProject project = request.mavenProjectFacade().getProject();
@@ -282,8 +290,8 @@ protected void addProjectSourceFolders(IClasspathDescriptor classpath, Map