Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFred Bricon2017-09-13 18:28:49 +0000
committerFred Bricon2017-10-02 13:46:02 +0000
commit5e965ef130ea6f8810620eec56bf3d5491ac0874 (patch)
tree87fb1b7d294b80e788d9a1580d435c19020788c7
parent5031cd262b0c0bfd16a209dd57f7e3604d1652bb (diff)
downloadm2e-core-5e965ef130ea6f8810620eec56bf3d5491ac0874.tar.gz
m2e-core-5e965ef130ea6f8810620eec56bf3d5491ac0874.tar.xz
m2e-core-5e965ef130ea6f8810620eec56bf3d5491ac0874.zip
525251 : add Java 9 module flag to classpath dependencies
Changes the Java configurator so that, if a Java project is a JPMS module, all classpath dependencies which match required modules in module-info.java will have the module flage set to true. One caveat is that, you currently need to call Maven Update project configuration after updating the required modules in module-info.java, so the module flag can be added to the dependencies. See [2]. This change requires APIs from unreleased JDT (install from [1]) to compile, but m2e can still be installed and run on older JDT versions. [1] http://download.eclipse.org/eclipse/updates/4.8-I-builds [2] https://dev.eclipse.org/mhonarc/lists/m2e-dev/msg02068.html Change-Id: I639f08ff7c32ea7b59b361935886204720942ee8 Signed-off-by: Fred Bricon <fbricon@gmail.com>
-rw-r--r--org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/AbstractJavaProjectConfigurator.java13
-rw-r--r--org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ModuleSupport.java173
-rw-r--r--org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java6
3 files changed, 191 insertions, 1 deletions
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 645d695f..1acdf1a6 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
@@ -61,7 +61,8 @@ import org.eclipse.m2e.jdt.MavenJdtPlugin;
*
* @author igor
*/
-public abstract class AbstractJavaProjectConfigurator extends AbstractProjectConfigurator {
+public abstract class AbstractJavaProjectConfigurator extends AbstractProjectConfigurator
+ implements IJavaProjectConfigurator {
private static final IPath[] DEFAULT_INCLUSIONS = new IPath[0];
@@ -650,4 +651,14 @@ public abstract class AbstractJavaProjectConfigurator extends AbstractProjectCon
}
return new Path(relative.replace('\\', '/')); //$NON-NLS-1$ //$NON-NLS-2$
}
+
+ @SuppressWarnings("restriction")
+ public void configureClasspath(IMavenProjectFacade facade, IClasspathDescriptor classpath, IProgressMonitor monitor)
+ throws CoreException {
+ ModuleSupport.configureClasspath(facade, classpath, monitor);
+ }
+
+ public void configureRawClasspath(ProjectConfigurationRequest request, IClasspathDescriptor classpath,
+ IProgressMonitor monitor) throws CoreException {
+ }
}
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
new file mode 100644
index 00000000..6f591c56
--- /dev/null
+++ b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/ModuleSupport.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.m2e.jdt.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.zip.ZipFile;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.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.core.AbstractModule;
+
+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
+ *
+ * @author Fred Bricon
+ * @since 1.8.2
+ */
+@SuppressWarnings("restriction")
+public class ModuleSupport {
+
+ static final boolean IS_MODULE_SUPPORT_AVAILABLE;
+
+ private static final Logger log = LoggerFactory.getLogger(ModuleSupport.class);
+
+ static {
+ boolean isModuleSupportAvailable = false;
+ try {
+ Class.forName("org.eclipse.jdt.core.IModuleDescription");
+ isModuleSupportAvailable = true;
+ } catch(ClassNotFoundException ignored) {
+ }
+ IS_MODULE_SUPPORT_AVAILABLE = isModuleSupportAvailable;
+ }
+
+ /**
+ * 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) throws CoreException {
+ if(!IS_MODULE_SUPPORT_AVAILABLE) {
+ return;
+ }
+ IJavaProject javaProject = JavaCore.create(facade.getProject());
+ IModuleDescription moduleDescription = javaProject.getModuleDescription();
+ if(!(moduleDescription instanceof AbstractModule)) {
+ return;
+ }
+ AbstractModule module = (AbstractModule) moduleDescription;
+ Set<String> requiredModules = Stream.of(module.getRequiredModules()).map(m -> new String(m.name()))
+ .collect(Collectors.toSet());
+ for(IClasspathEntryDescriptor entry : classpath.getEntryDescriptors()) {
+ String moduleName = getModuleName(entry, monitor);
+ if(requiredModules.contains(moduleName)) {
+ entry.setClasspathAttribute(IClasspathAttribute.MODULE, Boolean.TRUE.toString());
+ }
+ }
+ }
+
+ private static String getModuleName(IClasspathEntryDescriptor entry, IProgressMonitor monitor) {
+ String module = null;
+ if(IClasspathEntry.CPE_LIBRARY == entry.getEntryKind()) {
+ module = getModuleNameFromJar(entry.getPath().toFile());
+ } else if(IClasspathEntry.CPE_PROJECT == entry.getEntryKind()) {
+ module = getModuleNameFromProject(entry.getPath(), monitor);
+ }
+ return module;
+ }
+
+ private static String getModuleNameFromProject(IPath projectPath, IProgressMonitor monitor) {
+ IJavaProject project = getJavaProject(projectPath);
+ String module = null;
+ if(project != null) {
+ try {
+ if(project.getModuleDescription() == null) {
+ 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();
+ }
+ module = new String(AutomaticModuleNaming.determineAutomaticModuleName(buildName, false, null));
+ } else {
+ module = project.getModuleDescription().getElementName();
+ }
+ } catch(CoreException ex) {
+ log.error(ex.getMessage(), ex);
+ }
+ }
+ return module;
+ }
+
+ 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;
+ }
+
+ private static String getModuleNameFromJar(File file) {
+ if(!file.isFile()) {
+ return null;
+ }
+ char[] moduleName = null;
+ try (ZipFile zipFile = new ZipFile(file)) {
+ IModule module = null;
+ ClassFileReader reader = ClassFileReader.read(zipFile, IModule.MODULE_INFO_CLASS);
+ if(reader != null) {
+ module = reader.getModuleDeclaration();
+ if(module != null) {
+ moduleName = module.name();
+ }
+ }
+ } catch(ClassFormatException | IOException ex) {
+ log.error(ex.getMessage(), ex);
+ }
+ if(moduleName == null) {
+ moduleName = AutomaticModuleNaming.determineAutomaticModuleName(file.getAbsolutePath());
+ }
+ return new String(moduleName);
+ }
+
+}
diff --git a/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java b/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java
index 6bc660db..c1ba2640 100644
--- a/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java
+++ b/org.eclipse.m2e.launching/src/org/eclipse/m2e/internal/launch/MavenLaunchDelegate.java
@@ -113,6 +113,12 @@ public class MavenLaunchDelegate extends JavaLaunchDelegate implements MavenLaun
return cp.toArray(new String[cp.size()]);
}
+ public String[][] getClasspathAndModulepath(ILaunchConfiguration configuration) throws CoreException {
+ String[][] paths = new String[2][];
+ paths[0] = getClasspath(configuration);
+ return paths;
+ }
+
public String getProgramArguments(ILaunchConfiguration configuration) throws CoreException {
if(programArguments == null) {
String goals = getGoals(configuration);

Back to the top