Bug 562310 - Get rid of pre-JDT 3.14 logic in ModuleSupport
Change-Id: I32481b2caa354e2d63c7fd600662e5c72b7bbfac
Signed-off-by: Mickael Istria <mistria@redhat.com>
diff --git a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/InternalModuleSupport.java b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/InternalModuleSupport.java
deleted file mode 100644
index a2505ff..0000000
--- a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/InternalModuleSupport.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2017 Red Hat, Inc.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- * Metron, Inc. - support for provides/uses directives
- *******************************************************************************/
-
-package org.eclipse.m2e.jdt.internal;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspaceRoot;
-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.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.debug.core.ILaunchConfiguration;
-import org.eclipse.jdt.core.IClasspathAttribute;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IModuleDescription;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
-import org.eclipse.jdt.internal.compiler.env.AutomaticModuleNaming;
-import org.eclipse.jdt.internal.compiler.env.IModule;
-import org.eclipse.jdt.internal.launching.RuntimeClasspathEntry;
-import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
-import org.eclipse.jdt.launching.JavaRuntime;
-
-import org.apache.maven.project.MavenProject;
-
-import org.eclipse.m2e.core.MavenPlugin;
-import org.eclipse.m2e.core.project.IMavenProjectFacade;
-import org.eclipse.m2e.jdt.IClasspathDescriptor;
-import org.eclipse.m2e.jdt.IClasspathEntryDescriptor;
-
-
-/**
- * Helper for Java Module Support relying on new JDT classes
- *
- * @author Fred Bricon
- * @since 1.8.2
- */
-@Deprecated
-@SuppressWarnings("restriction")
-class InternalModuleSupport {
-
- private static final Logger log = LoggerFactory.getLogger(InternalModuleSupport.class);
-
- /**
- * This is a copy of the constant of org.eclipse.jdt.launching.IRuntimeClasspathEntry.PATCH_MODULE. Having this copy
- * allows to compile and run with 4.7.1a
- */
- private static final int PATCH_MODULE = 6;
-
- /**
- * Sets <code>module</code flag to <code>true</code> to classpath dependencies declared in module-info.java
- *
- * @param facade a Maven facade project
- * @param classpath a classpath descriptor
- * @param monitor a progress monitor
- */
- public static void configureClasspath(IMavenProjectFacade facade, IClasspathDescriptor classpath,
- IProgressMonitor monitor) {
- IJavaProject javaProject = JavaCore.create(facade.getProject());
- if(javaProject == null || !javaProject.exists()) {
- return;
- }
-
- int targetCompliance = 8;
- String option = javaProject.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true);
- if(option != null) {
- if(option.startsWith("1.")) {
- option = option.substring("1.".length());
- }
- try {
- targetCompliance = Integer.parseInt(option);
- } catch(NumberFormatException ex) {
- log.error(ex.getMessage(), ex);
- }
- }
- if(targetCompliance < 9) {
- return;
- }
-
- if(monitor == null) {
- monitor = new NullProgressMonitor();
- }
-
- InternalModuleInfo moduleInfo = getModuleInfo(javaProject, monitor);
- if(moduleInfo == null) {
- return;
- }
-
- Map<String, InternalModuleInfo> entryModuleInfos = new LinkedHashMap<>();
- Map<String, IClasspathEntryDescriptor> entryDescriptors = new LinkedHashMap<>();
- for(IClasspathEntryDescriptor entryDescriptor : classpath.getEntryDescriptors()) {
- if(monitor.isCanceled()) {
- return;
- }
- InternalModuleInfo entryModuleInfo = getModuleInfo(entryDescriptor, monitor, targetCompliance);
- if(entryModuleInfo != null) {
- entryModuleInfos.put(entryModuleInfo.name, entryModuleInfo);//potentially suppresses duplicate entries from the same workspace project, with different classifiers
- entryDescriptors.put(entryModuleInfo.name, entryDescriptor);
- }
- }
-
- Set<String> neededModuleNames = collectModulesNeededTransitively(moduleInfo, entryModuleInfos);
- if(monitor.isCanceled()) {
- return;
- }
-
- entryDescriptors.forEach((entryModuleName, entry) ->
- {
- if(neededModuleNames.contains(entryModuleName)) {
- entry.setClasspathAttribute(IClasspathAttribute.MODULE, Boolean.TRUE.toString());
- }
- });
- }
-
- private static Set<String> collectModulesNeededTransitively(InternalModuleInfo module,
- Map<String, InternalModuleInfo> classpathModules) {
- Set<String> result = new LinkedHashSet<>();
- Function<InternalModuleInfo, Set<String>> neededModulesLookup = createNeededModulesLookup(classpathModules);
- Set<String> todo = neededModulesLookup.apply(module);
- while(!todo.isEmpty()) {
- Set<String> todoNext = new LinkedHashSet<>();
- for(String neededModuleName : todo) {
- if(result.add(neededModuleName)) {
- InternalModuleInfo neededModule = classpathModules.get(neededModuleName);
- todoNext.addAll(neededModulesLookup.apply(neededModule));
- } else {
- //already checked that module
- }
- }
- todo = todoNext;
- }
- return result;
- }
-
- /**
- * Returns a function that takes a {@link ModuleInfo}, and looks up the names of the modules needed by the given
- * module -- including modules it requires, and also modules that provide services it uses.
- */
- private static Function<InternalModuleInfo, Set<String>> createNeededModulesLookup(
- Map<String, InternalModuleInfo> classpathModules) {
- Map<String, Set<String>> providersByServiceName = new LinkedHashMap<>();
- for(InternalModuleInfo classpathModule : classpathModules.values()) {
- for(String serviceName : classpathModule.providedServiceNames) {
- providersByServiceName.computeIfAbsent(serviceName, k -> new LinkedHashSet<>()).add(classpathModule.name);
- }
- }
- return (module) ->
- {
- if(module != null) {
- Set<String> result = new LinkedHashSet<>();
- result.addAll(module.requiredModuleNames);
- for(String serviceName : module.usedServiceNames) {
- Set<String> providerNames = providersByServiceName.getOrDefault(serviceName, Collections.emptySet());
- result.addAll(providerNames);
- }
- return result;
- }
- return Collections.emptySet();
- };
- }
-
- private static InternalModuleInfo getModuleInfo(IClasspathEntryDescriptor entry, IProgressMonitor monitor,
- int targetCompliance) {
- if(entry != null && !monitor.isCanceled()) {
- if(IClasspathEntry.CPE_LIBRARY == entry.getEntryKind()) {
- return getModuleInfo(entry.getPath().toFile(), targetCompliance);
- } else if(IClasspathEntry.CPE_PROJECT == entry.getEntryKind()) {
- return getModuleInfo(getJavaProject(entry.getPath()), monitor);
- }
- }
- return null;
- }
-
- static InternalModuleInfo getModuleInfo(IJavaProject project, IProgressMonitor monitor) {
- if(project != null) {
- try {
- IModuleDescription moduleDescription = project.getModuleDescription();
- if(moduleDescription != null) {
- return InternalModuleInfo.fromDescription(moduleDescription);
- }
-
- String buildName = null;
- IMavenProjectFacade facade = MavenPlugin.getMavenProjectRegistry().getProject(project.getProject());
- if(facade != null) {
- MavenProject mavenProject = facade.getMavenProject(monitor);
- if(mavenProject != null) {
- buildName = mavenProject.getBuild().getFinalName();
- }
- }
- if(buildName == null || buildName.isEmpty()) {
- buildName = project.getElementName();
- }
- String moduleName = new String(AutomaticModuleNaming.determineAutomaticModuleName(buildName, false, null));
- return InternalModuleInfo.withAutomaticName(moduleName);
-
- } catch(CoreException ex) {
- log.error(ex.getMessage(), ex);
- }
- }
- return null;
- }
-
- private static InternalModuleInfo getModuleInfo(File file, int targetCompliance) {
- if(!file.isFile()) {
- return null;
- }
- try (JarFile jar = new JarFile(file, false)) {
- Manifest manifest = jar.getManifest();
- boolean isMultiRelease = false;
- if(manifest != null) {
- isMultiRelease = "true".equalsIgnoreCase(manifest.getMainAttributes().getValue("Multi-Release"));
- }
- int compliance = isMultiRelease ? targetCompliance : 8;
- for(int i = compliance; i >= 8; i-- ) {
- String filename;
- if(i == 8) {
- // 8 represents unversioned module-info.class
- filename = IModule.MODULE_INFO_CLASS;
- } else {
- filename = "META-INF/versions/" + i + "/" + IModule.MODULE_INFO_CLASS;
- }
- ClassFileReader reader = ClassFileReader.read(jar, filename);
- if(reader != null) {
- IModule module = reader.getModuleDeclaration();
- if(module != null) {
- return InternalModuleInfo.fromDeclaration(module);
- }
- }
- }
- if(manifest != null) {
- // optimization: we already have the manifest, so directly check for Automatic-Module-Name
- // rather than using AutomaticModuleNaming.determineAutomaticModuleName(String)
- String automaticModuleName = manifest.getMainAttributes().getValue("Automatic-Module-Name");
- if(automaticModuleName != null) {
- return InternalModuleInfo.withAutomaticName(automaticModuleName);
- }
- }
- } catch(ClassFormatException | IOException ex) {
- log.error(ex.getMessage(), ex);
- }
- return InternalModuleInfo.withAutomaticNameFromFile(file);
- }
-
- private static IJavaProject getJavaProject(IPath projectPath) {
- if(projectPath == null || projectPath.isEmpty()) {
- return null;
- }
- IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
- IProject project = root.getProject(projectPath.lastSegment());
- if(project.isAccessible()) {
- return JavaCore.create(project);
- }
- return null;
- }
-
- public static boolean isModuleEntry(IClasspathEntry entry) {
- return Arrays.stream(entry.getExtraAttributes())
- .anyMatch(p -> IClasspathAttribute.MODULE.equals(p.getName()) && "true".equals(p.getValue()));
- }
-
- public static int determineModularClasspathProperty(IClasspathEntry entry) {
- return isModuleEntry(entry) ? IRuntimeClasspathEntry.MODULE_PATH : IRuntimeClasspathEntry.CLASS_PATH;
- }
-
- public static IRuntimeClasspathEntry createRuntimeClasspathEntry(IFolder folder, int classpathProperty,
- IProject project) {
- if(classpathProperty == IRuntimeClasspathEntry.MODULE_PATH && !folder.exists(new Path("module-info.class"))) {
- classpathProperty = PATCH_MODULE;
- }
- IRuntimeClasspathEntry newArchiveRuntimeClasspathEntry = JavaRuntime
- .newArchiveRuntimeClasspathEntry(folder.getFullPath(), classpathProperty);
- if(classpathProperty == PATCH_MODULE) {
- ((RuntimeClasspathEntry) newArchiveRuntimeClasspathEntry).setJavaProject(JavaCore.create(project));
- }
- return newArchiveRuntimeClasspathEntry;
- }
-
- public static int determineClasspathPropertyForMainProject(boolean isModularConfiguration, IJavaProject javaProject) {
- if(!isModularConfiguration) {
- return IRuntimeClasspathEntry.USER_CLASSES;
- } else if(!JavaRuntime.isModularProject(javaProject)) {
- return IRuntimeClasspathEntry.CLASS_PATH;
- } else {
- return IRuntimeClasspathEntry.MODULE_PATH;
- }
- }
-
- public static boolean isModularConfiguration(ILaunchConfiguration configuration) {
- return JavaRuntime.isModularConfiguration(configuration);
- }
-
- public static IRuntimeClasspathEntry newModularProjectRuntimeClasspathEntry(IJavaProject javaProject) {
- return JavaRuntime.newProjectRuntimeClasspathEntry(javaProject,
- JavaRuntime.isModularProject(javaProject) ? IRuntimeClasspathEntry.MODULE_PATH
- : IRuntimeClasspathEntry.CLASS_PATH);
- }
-
-}
diff --git a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ModuleSupport.java b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ModuleSupport.java
index dd956ad..d804d75 100644
--- a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ModuleSupport.java
+++ b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ModuleSupport.java
@@ -14,24 +14,50 @@
package org.eclipse.m2e.jdt.internal;
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+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.debug.core.ILaunchConfiguration;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IModuleDescription;
import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.AutomaticModuleNaming;
+import org.eclipse.jdt.internal.compiler.env.IModule;
+import org.eclipse.jdt.internal.launching.RuntimeClasspathEntry;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.JavaRuntime;
+import org.apache.maven.project.MavenProject;
+
+import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.internal.IMavenConstants;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.jdt.IClasspathDescriptor;
+import org.eclipse.m2e.jdt.IClasspathEntryDescriptor;
/**
@@ -40,34 +66,13 @@
* @author Fred Bricon
* @since 1.8.2
*/
+@SuppressWarnings("restriction")
public class ModuleSupport {
public static final String MODULE_INFO_JAVA = "module-info.java";
- static final boolean IS_MODULE_SUPPORT_AVAILABLE;
-
- static final boolean IS_PATCH_MODULE_SUPPORT_AVAILABLE;
-
private static final Logger log = LoggerFactory.getLogger(ModuleSupport.class);
- static {
- boolean isModuleSupportAvailable = false;
- boolean isPatchModuleSupportAvailable = false;
- try {
- Class.forName("org.eclipse.jdt.core.IModuleDescription");
- isModuleSupportAvailable = true;
- try {
- IRuntimeClasspathEntry.class.getDeclaredField("PATCH_MODULE");
- isPatchModuleSupportAvailable = true;
- } catch(NoSuchFieldException | SecurityException ignored) {
- }
- } catch(ClassNotFoundException ignored) {
- }
-
- IS_MODULE_SUPPORT_AVAILABLE = isModuleSupportAvailable;
- IS_PATCH_MODULE_SUPPORT_AVAILABLE = isPatchModuleSupportAvailable;
- }
-
/**
* Sets <code>module</code> flag to <code>true</code> to classpath dependencies declared in module-info.java
*
@@ -76,47 +81,238 @@
* @param monitor a progress monitor
*/
public static void configureClasspath(IMavenProjectFacade facade, IClasspathDescriptor classpath,
- IProgressMonitor monitor) throws CoreException {
- if(!IS_MODULE_SUPPORT_AVAILABLE || classpath == null) {
+ IProgressMonitor monitor) {
+ IJavaProject javaProject = JavaCore.create(facade.getProject());
+ if(javaProject == null || !javaProject.exists() || classpath == null) {
return;
}
- InternalModuleSupport.configureClasspath(facade, classpath, monitor);
+
+ int targetCompliance = 8;
+ String option = javaProject.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true);
+ if(option != null) {
+ if(option.startsWith("1.")) {
+ option = option.substring("1.".length());
+ }
+ try {
+ targetCompliance = Integer.parseInt(option);
+ } catch(NumberFormatException ex) {
+ log.error(ex.getMessage(), ex);
+ }
+ }
+ if(targetCompliance < 9) {
+ return;
+ }
+
+ if(monitor == null) {
+ monitor = new NullProgressMonitor();
+ }
+
+ InternalModuleInfo moduleInfo = getModuleInfo(javaProject, monitor);
+ if(moduleInfo == null) {
+ return;
+ }
+
+ Map<String, InternalModuleInfo> entryModuleInfos = new LinkedHashMap<>();
+ Map<String, IClasspathEntryDescriptor> entryDescriptors = new LinkedHashMap<>();
+ for(IClasspathEntryDescriptor entryDescriptor : classpath.getEntryDescriptors()) {
+ if(monitor.isCanceled()) {
+ return;
+ }
+ InternalModuleInfo entryModuleInfo = getModuleInfo(entryDescriptor, monitor, targetCompliance);
+ if(entryModuleInfo != null) {
+ entryModuleInfos.put(entryModuleInfo.name, entryModuleInfo);//potentially suppresses duplicate entries from the same workspace project, with different classifiers
+ entryDescriptors.put(entryModuleInfo.name, entryDescriptor);
+ }
+ }
+
+ Set<String> neededModuleNames = collectModulesNeededTransitively(moduleInfo, entryModuleInfos);
+ if(monitor.isCanceled()) {
+ return;
+ }
+
+ entryDescriptors.forEach((entryModuleName, entry) -> {
+ if(neededModuleNames.contains(entryModuleName)) {
+ entry.setClasspathAttribute(IClasspathAttribute.MODULE, Boolean.TRUE.toString());
+ }
+ });
+ }
+
+ private static Set<String> collectModulesNeededTransitively(InternalModuleInfo module,
+ Map<String, InternalModuleInfo> classpathModules) {
+ Set<String> result = new LinkedHashSet<>();
+ Function<InternalModuleInfo, Set<String>> neededModulesLookup = createNeededModulesLookup(classpathModules);
+ Set<String> todo = neededModulesLookup.apply(module);
+ while(!todo.isEmpty()) {
+ Set<String> todoNext = new LinkedHashSet<>();
+ for(String neededModuleName : todo) {
+ if(result.add(neededModuleName)) {
+ InternalModuleInfo neededModule = classpathModules.get(neededModuleName);
+ todoNext.addAll(neededModulesLookup.apply(neededModule));
+ } else {
+ //already checked that module
+ }
+ }
+ todo = todoNext;
+ }
+ return result;
+ }
+
+ /**
+ * Returns a function that takes a {@link ModuleInfo}, and looks up the names of the modules needed by the given
+ * module -- including modules it requires, and also modules that provide services it uses.
+ */
+ private static Function<InternalModuleInfo, Set<String>> createNeededModulesLookup(
+ Map<String, InternalModuleInfo> classpathModules) {
+ Map<String, Set<String>> providersByServiceName = new LinkedHashMap<>();
+ for(InternalModuleInfo classpathModule : classpathModules.values()) {
+ for(String serviceName : classpathModule.providedServiceNames) {
+ providersByServiceName.computeIfAbsent(serviceName, k -> new LinkedHashSet<>()).add(classpathModule.name);
+ }
+ }
+ return (module) -> {
+ if(module != null) {
+ Set<String> result = new LinkedHashSet<>();
+ result.addAll(module.requiredModuleNames);
+ for(String serviceName : module.usedServiceNames) {
+ Set<String> providerNames = providersByServiceName.getOrDefault(serviceName, Collections.emptySet());
+ result.addAll(providerNames);
+ }
+ return result;
+ }
+ return Collections.emptySet();
+ };
+ }
+
+ private static InternalModuleInfo getModuleInfo(IClasspathEntryDescriptor entry, IProgressMonitor monitor,
+ int targetCompliance) {
+ if(entry != null && !monitor.isCanceled()) {
+ if(IClasspathEntry.CPE_LIBRARY == entry.getEntryKind()) {
+ return getModuleInfo(entry.getPath().toFile(), targetCompliance);
+ } else if(IClasspathEntry.CPE_PROJECT == entry.getEntryKind()) {
+ return getModuleInfo(getJavaProject(entry.getPath()), monitor);
+ }
+ }
+ return null;
+ }
+
+ static InternalModuleInfo getModuleInfo(IJavaProject project, IProgressMonitor monitor) {
+ if(project != null) {
+ try {
+ IModuleDescription moduleDescription = project.getModuleDescription();
+ if(moduleDescription != null) {
+ return InternalModuleInfo.fromDescription(moduleDescription);
+ }
+
+ String buildName = null;
+ IMavenProjectFacade facade = MavenPlugin.getMavenProjectRegistry().getProject(project.getProject());
+ if(facade != null) {
+ MavenProject mavenProject = facade.getMavenProject(monitor);
+ if(mavenProject != null) {
+ buildName = mavenProject.getBuild().getFinalName();
+ }
+ }
+ if(buildName == null || buildName.isEmpty()) {
+ buildName = project.getElementName();
+ }
+ String moduleName = new String(AutomaticModuleNaming.determineAutomaticModuleName(buildName, false, null));
+ return InternalModuleInfo.withAutomaticName(moduleName);
+
+ } catch(CoreException ex) {
+ log.error(ex.getMessage(), ex);
+ }
+ }
+ return null;
+ }
+
+ private static InternalModuleInfo getModuleInfo(File file, int targetCompliance) {
+ if(!file.isFile()) {
+ return null;
+ }
+ try (JarFile jar = new JarFile(file, false)) {
+ Manifest manifest = jar.getManifest();
+ boolean isMultiRelease = false;
+ if(manifest != null) {
+ isMultiRelease = "true".equalsIgnoreCase(manifest.getMainAttributes().getValue("Multi-Release"));
+ }
+ int compliance = isMultiRelease ? targetCompliance : 8;
+ for(int i = compliance; i >= 8; i-- ) {
+ String filename;
+ if(i == 8) {
+ // 8 represents unversioned module-info.class
+ filename = IModule.MODULE_INFO_CLASS;
+ } else {
+ filename = "META-INF/versions/" + i + "/" + IModule.MODULE_INFO_CLASS;
+ }
+ ClassFileReader reader = ClassFileReader.read(jar, filename);
+ if(reader != null) {
+ IModule module = reader.getModuleDeclaration();
+ if(module != null) {
+ return InternalModuleInfo.fromDeclaration(module);
+ }
+ }
+ }
+ if(manifest != null) {
+ // optimization: we already have the manifest, so directly check for Automatic-Module-Name
+ // rather than using AutomaticModuleNaming.determineAutomaticModuleName(String)
+ String automaticModuleName = manifest.getMainAttributes().getValue("Automatic-Module-Name");
+ if(automaticModuleName != null) {
+ return InternalModuleInfo.withAutomaticName(automaticModuleName);
+ }
+ }
+ } catch(ClassFormatException | IOException ex) {
+ log.error(ex.getMessage(), ex);
+ }
+ return InternalModuleInfo.withAutomaticNameFromFile(file);
+ }
+
+ private static IJavaProject getJavaProject(IPath projectPath) {
+ if(projectPath == null || projectPath.isEmpty()) {
+ return null;
+ }
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IProject project = root.getProject(projectPath.lastSegment());
+ if(project.isAccessible()) {
+ return JavaCore.create(project);
+ }
+ return null;
+ }
+
+ public static boolean isModuleEntry(IClasspathEntry entry) {
+ return Arrays.stream(entry.getExtraAttributes())
+ .anyMatch(p -> IClasspathAttribute.MODULE.equals(p.getName()) && "true".equals(p.getValue()));
}
public static int determineModularClasspathProperty(IClasspathEntry entry) {
- if(!IS_PATCH_MODULE_SUPPORT_AVAILABLE) {
- return IRuntimeClasspathEntry.USER_CLASSES;
- }
- return InternalModuleSupport.determineModularClasspathProperty(entry);
+ return isModuleEntry(entry) ? IRuntimeClasspathEntry.MODULE_PATH : IRuntimeClasspathEntry.CLASS_PATH;
}
public static IRuntimeClasspathEntry createRuntimeClasspathEntry(IFolder folder, int classpathProperty,
IProject project) {
- if(!IS_PATCH_MODULE_SUPPORT_AVAILABLE) {
- return JavaRuntime.newArchiveRuntimeClasspathEntry(folder.getFullPath());
+ if(classpathProperty == IRuntimeClasspathEntry.MODULE_PATH && !folder.exists(new Path("module-info.class"))) {
+ classpathProperty = IRuntimeClasspathEntry.PATCH_MODULE;
}
- return InternalModuleSupport.createRuntimeClasspathEntry(folder, classpathProperty, project);
+ IRuntimeClasspathEntry newArchiveRuntimeClasspathEntry = JavaRuntime
+ .newArchiveRuntimeClasspathEntry(folder.getFullPath(), classpathProperty);
+ if(classpathProperty == IRuntimeClasspathEntry.PATCH_MODULE) {
+ ((RuntimeClasspathEntry) newArchiveRuntimeClasspathEntry).setJavaProject(JavaCore.create(project));
+ }
+ return newArchiveRuntimeClasspathEntry;
}
public static int determineClasspathPropertyForMainProject(boolean isModularConfiguration, IJavaProject javaProject) {
- if(!IS_PATCH_MODULE_SUPPORT_AVAILABLE) {
+ if(!isModularConfiguration) {
return IRuntimeClasspathEntry.USER_CLASSES;
+ } else if(!JavaRuntime.isModularProject(javaProject)) {
+ return IRuntimeClasspathEntry.CLASS_PATH;
+ } else {
+ return IRuntimeClasspathEntry.MODULE_PATH;
}
- return InternalModuleSupport.determineClasspathPropertyForMainProject(isModularConfiguration, javaProject);
- }
-
- public static boolean isModularConfiguration(ILaunchConfiguration configuration) {
- if(!IS_PATCH_MODULE_SUPPORT_AVAILABLE) {
- return false;
- }
- return InternalModuleSupport.isModularConfiguration(configuration);
}
public static IRuntimeClasspathEntry newModularProjectRuntimeClasspathEntry(IJavaProject javaProject) {
- if(!IS_PATCH_MODULE_SUPPORT_AVAILABLE) {
- return JavaRuntime.newProjectRuntimeClasspathEntry(javaProject);
- }
- return InternalModuleSupport.newModularProjectRuntimeClasspathEntry(javaProject);
+ return JavaRuntime.newProjectRuntimeClasspathEntry(javaProject,
+ JavaRuntime.isModularProject(javaProject) ? IRuntimeClasspathEntry.MODULE_PATH
+ : IRuntimeClasspathEntry.CLASS_PATH);
}
public static boolean isMavenJavaProject(IProject project) {
@@ -128,8 +324,4 @@
}
return false;
}
-
- static InternalModuleInfo getModuleInfo(IJavaProject jp, IProgressMonitor monitor) throws JavaModelException {
- return InternalModuleSupport.getModuleInfo(jp, monitor);
- }
}
diff --git a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/launch/MavenRuntimeClasspathProvider.java b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/launch/MavenRuntimeClasspathProvider.java
index 7d719a3..c58d828 100644
--- a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/launch/MavenRuntimeClasspathProvider.java
+++ b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/launch/MavenRuntimeClasspathProvider.java
@@ -110,7 +110,7 @@
public IRuntimeClasspathEntry[] computeUnresolvedClasspath(final ILaunchConfiguration configuration)
throws CoreException {
- boolean isModular = ModuleSupport.isModularConfiguration(configuration);
+ boolean isModular = JavaRuntime.isModularConfiguration(configuration);
boolean useDefault = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, true);
if(useDefault) {
IJavaProject javaProject = JavaRuntime.getJavaProject(configuration);