Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keep external annotations paths when updating the project configuration (fixes #391) #1635

Merged
merged 1 commit into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,18 @@
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IClasspathAttribute;
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.jdt.launching.JavaRuntime;
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.jdt.IClasspathManager;
import org.eclipse.m2e.jdt.internal.ClasspathDescriptor;
import org.eclipse.m2e.jdt.internal.MavenClasspathHelpers;
import org.eclipse.m2e.tests.common.AbstractMavenProjectTestCase;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -57,13 +62,33 @@ public void setUp() throws Exception {
@Test
public void testFileChangeUpdatesJDTSettings() throws CoreException, IOException, InterruptedException {
IJavaProject project = importResourceProject("/projects/compilerSettings/pom.xml");

// set external annotation path to JRE and Maven classpaths
var classpath = new ClasspathDescriptor(project);
var containerPath = classpath.getEntryDescriptors().stream().filter(e -> JavaRuntime.JRE_CONTAINER.equals(e.getPath().segment(0)))
.findFirst().get().getPath();
classpath.addEntry(MavenClasspathHelpers.newContainerEntry(containerPath, JavaCore.newClasspathAttribute(
IClasspathAttribute.EXTERNAL_ANNOTATION_PATH, "/jre_external_anno_path")));
classpath.addEntry(MavenClasspathHelpers.getDefaultContainerEntry(
JavaCore.newClasspathAttribute(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH, "/maven_external_anno_path")));
project.setRawClasspath(classpath.getEntries(), project.getOutputLocation(), monitor);

assertEquals("1.8", project.getOption(JavaCore.COMPILER_SOURCE, false));
IFile pomFileWS = project.getProject().getFile("pom.xml");
String pomContent = Files.readString(Path.of(pomFileWS.getLocationURI()));
pomContent = pomContent.replace("1.8", "11");
pomFileWS.setContents(new ByteArrayInputStream(pomContent.getBytes()), true, false, null);
waitForJobsToComplete();
assertEquals("11", project.getOption(JavaCore.COMPILER_SOURCE, false));

// ensure external annotation paths are still present after update
classpath = new ClasspathDescriptor(project);
var jreCpe = classpath.getEntryDescriptors().stream().filter(e -> JavaRuntime.JRE_CONTAINER.equals(e.getPath().segment(0)))
.findFirst().get();
assertEquals("/jre_external_anno_path", jreCpe.getClasspathAttributes().get(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH));
var mavenCpePath = IPath.fromOSString(IClasspathManager.CONTAINER_ID);
var mavenCpe = classpath.getEntryDescriptors().stream().filter(e -> mavenCpePath.equals(e.getPath())).findFirst().get();
assertEquals("/maven_external_anno_path", mavenCpe.getClasspathAttributes().get(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;

import org.osgi.framework.Version;
import org.slf4j.Logger;
Expand Down Expand Up @@ -221,14 +224,15 @@ protected void invokeJavaProjectConfigurators(IClasspathDescriptor classpath, Pr

protected void addJREClasspathContainer(IClasspathDescriptor classpath, String environmentId) {

IClasspathEntry cpe;
IExecutionEnvironment executionEnvironment = getExecutionEnvironment(environmentId);
if(executionEnvironment == null) {
cpe = JavaRuntime.getDefaultJREContainerEntry();
} else {
IPath containerPath = JavaRuntime.newJREContainerPath(executionEnvironment);
cpe = JavaCore.newContainerEntry(containerPath);
}
IPath containerPath = executionEnvironment == null //
? JavaRuntime.newDefaultJREContainerPath() //
: JavaRuntime.newJREContainerPath(executionEnvironment);

// ensure the external annotation path is kept
IClasspathAttribute[] externalAnnotations = readExternalAnnotationAttributes(classpath,
p -> JavaRuntime.JRE_CONTAINER.equals(p.getPath().segment(0)));
IClasspathEntry cpe = MavenClasspathHelpers.newContainerEntry(containerPath, externalAnnotations);

IClasspathEntryDescriptor cped = classpath
.replaceEntry(descriptor -> JavaRuntime.JRE_CONTAINER.equals(descriptor.getPath().segment(0)), cpe);
Expand Down Expand Up @@ -268,7 +272,11 @@ protected void addMavenClasspathContainer(IClasspathDescriptor classpath) {
}
}

IClasspathEntry cpe = MavenClasspathHelpers.getDefaultContainerEntry();
// ensure the external annotation path is kept
IClasspathAttribute[] externalAnnotations = readExternalAnnotationAttributes(classpath,
p -> MavenClasspathHelpers.MAVEN_CLASSPATH_CONTAINER_PATH.equals(p.getPath()));
IClasspathEntry cpe = MavenClasspathHelpers.getDefaultContainerEntry(externalAnnotations);

// add new entry without removing existing entries first, see bug398121
IClasspathEntryDescriptor entryDescriptor = classpath.addEntry(cpe);
entryDescriptor.setExported(isExported);
Expand All @@ -277,6 +285,15 @@ protected void addMavenClasspathContainer(IClasspathDescriptor classpath) {
}
}

private static IClasspathAttribute[] readExternalAnnotationAttributes(IClasspathDescriptor classpath,
Predicate<IClasspathEntryDescriptor> annotationSourceEntry) {
Optional<String> annotationPath = classpath.getEntryDescriptors().stream().filter(annotationSourceEntry)
.map(descr -> descr.getClasspathAttributes().get(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH))
.filter(Objects::nonNull).filter(p -> !p.isBlank()).findFirst();
return annotationPath.map(p -> JavaCore.newClasspathAttribute(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH, p))
.map(a -> new IClasspathAttribute[] {a}).orElseGet(() -> new IClasspathAttribute[] {});
}

protected void addProjectSourceFolders(IClasspathDescriptor classpath, ProjectConfigurationRequest request,
IProgressMonitor monitor) throws CoreException {
addProjectSourceFolders(classpath, new HashMap<>(), request, monitor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,4 +384,9 @@ public void setPomDerived(boolean derived) {
attributes.remove(IClasspathManager.POMDERIVED_ATTRIBUTE);
}
}

@Override
public String toString() {
return getClass().getSimpleName() + "@" + System.identityHashCode(this) + "{path=" + path + "}";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,8 @@ public IPath getPath() {
return path;
}

@Override
public String toString() {
return getClass().getSimpleName() + "@" + System.identityHashCode(this) + "{path=" + path + "}";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

public class MavenClasspathHelpers {

public static final IPath MAVEN_CLASSPATH_CONTAINER_PATH = IPath.fromOSString(IClasspathManager.CONTAINER_ID);

public static IClasspathEntry getJREContainerEntry(IJavaProject javaProject) {
if(javaProject != null) {
try {
Expand All @@ -55,12 +57,16 @@ public static boolean isJREClasspathContainer(IPath containerPath) {
&& JavaRuntime.JRE_CONTAINER.equals(containerPath.segment(0));
}

public static IClasspathEntry getDefaultContainerEntry() {
return JavaCore.newContainerEntry(IPath.fromOSString(IClasspathManager.CONTAINER_ID));
public static IClasspathEntry getDefaultContainerEntry(boolean isExported) {
return JavaCore.newContainerEntry(MAVEN_CLASSPATH_CONTAINER_PATH, isExported);
}

public static IClasspathEntry getDefaultContainerEntry(boolean isExported) {
return JavaCore.newContainerEntry(IPath.fromOSString(IClasspathManager.CONTAINER_ID), isExported);
public static IClasspathEntry getDefaultContainerEntry(IClasspathAttribute... attributes) {
return JavaCore.newContainerEntry(MAVEN_CLASSPATH_CONTAINER_PATH, null, attributes, false/*not exported*/);
}

public static IClasspathEntry newContainerEntry(IPath path, IClasspathAttribute... attributes) {
return JavaCore.newContainerEntry(path, null, attributes, false/*not exported*/);
}

public static boolean isTestSource(IClasspathEntry entry) {
Expand Down
Loading