diff options
37 files changed, 476 insertions, 196 deletions
diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/TestingEnvironment.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/TestingEnvironment.java index 86a3ee2b17..5df235e95f 100644 --- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/TestingEnvironment.java +++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/TestingEnvironment.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2017 IBM Corporation and others. * 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 @@ -20,6 +20,7 @@ import org.eclipse.jdt.core.tests.util.Util; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.core.ClasspathEntry; +import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.core.JavaProject; import org.eclipse.jdt.internal.core.nd.indexer.Indexer; @@ -296,7 +297,11 @@ public void addClassFolder(IPath projectPath, IPath classFolderPath, boolean isE public void addExternalJars(IPath projectPath, String[] jars, boolean isExported) throws JavaModelException { for (int i = 0, max = jars.length; i < max; i++) { String jar = jars[i]; - addEntry(projectPath, JavaCore.newLibraryEntry(new Path(jar), null, null, isExported)); + if (JavaModelManager.isJrtInstallation(jar) || jar.endsWith("jrt-fs.jar")) { + addEntry(projectPath, JavaCore.newJrtEntry(new Path(jar), null, null, null, null, isExported)); + } else { + addEntry(projectPath, JavaCore.newLibraryEntry(new Path(jar), null, null, isExported)); + } } } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java index cc37982814..8a39b6c5a4 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java @@ -281,7 +281,7 @@ public class ASTConverter9Test extends ConverterTestSetup { element = element.getParent(); assertNotNull(element); assertEquals("Incorrect element type", IJavaElement.PACKAGE_FRAGMENT_ROOT, element.getElementType()); - assertTrue("incorrect root type", (element instanceof JrtPackageFragmentRoot)); + assertEquals("incorrect root type", element.getClass().toString(), JrtPackageFragmentRoot.class.toString()); JrtPackageFragmentRoot root = (JrtPackageFragmentRoot) element; assertEquals("incorrect module name", "java.base", root.getElementName()); } finally { diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java index fc1801e0b4..9af91dac31 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java @@ -1328,15 +1328,22 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { return createJava9ProjectWithJREAttributes(name, srcFolders, null); } protected IJavaProject createJava9ProjectWithJREAttributes(String name, String[] srcFolders, IClasspathAttribute[] attributes) throws CoreException { - String javaHome = System.getProperty("java.home") + File.separator; - Path bootModPath = new Path(javaHome +"/lib/jrt-fs.jar"); - Path sourceAttachment = new Path(javaHome +"/lib/src.zip"); - IClasspathEntry jrtEntry = JavaCore.newLibraryEntry(bootModPath, sourceAttachment, null, null, attributes, false); + String javaHome = System.getProperty("java.home"); + Path bootModPath = new Path(javaHome); + Path sourceAttachment = new Path(javaHome + File.separator + "lib" + File.separator + "src.zip"); + IClasspathEntry jrtEntry = JavaCore.newJrtEntry(bootModPath, sourceAttachment, null, null, attributes, false); IJavaProject project = this.createJavaProject(name, srcFolders, new String[0], new String[0], "bin", "9"); IClasspathEntry[] old = project.getRawClasspath(); - IClasspathEntry[] newPath = new IClasspathEntry[old.length +1]; - System.arraycopy(old, 0, newPath, 0, old.length); + List<IClasspathEntry> list = new ArrayList<>(); + for (IClasspathEntry iClasspathEntry : old) { + if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE + || iClasspathEntry.getContentKind() == ClasspathEntry.K_OUTPUT) { + list.add(iClasspathEntry); + } + } + list.add(jrtEntry); + IClasspathEntry[] newPath = list.toArray(new IClasspathEntry[list.size()]); newPath[old.length] = jrtEntry; project.setRawClasspath(newPath, null); return project; @@ -1764,6 +1771,14 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { ClasspathEntry.getAccessRules(accessibleFiles, nonAccessibleFiles), new IClasspathAttribute[0], false); + } else if (JavaModelManager.isJrtInstallation((new Path(lib)).toString()) || lib.endsWith("jrt-fs.jar")) { + entries[sourceLength+i] = JavaCore.newJrtEntry( + new Path(lib), + null, + null, + ClasspathEntry.getAccessRules(accessibleFiles, nonAccessibleFiles), + new IClasspathAttribute[0], + false); } else { IPath libPath = new Path(lib); if (!libPath.isAbsolute() && libPath.segmentCount() > 0 && libPath.getFileExtension() == null) { diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java index f85115a13c..7c750e26ce 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations18Test.java @@ -61,6 +61,7 @@ import org.eclipse.jdt.core.util.ExternalAnnotationUtil.MergeStrategy; import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; import org.eclipse.jdt.internal.core.ClasspathAttribute; import org.eclipse.jdt.internal.core.ClasspathEntry; +import org.eclipse.jdt.internal.core.JavaModelManager; import org.osgi.framework.Bundle; @SuppressWarnings({"rawtypes", "unchecked"}) @@ -83,7 +84,7 @@ public class ExternalAnnotations18Test extends ModifyingResourceTests { this.entries = entries; } public IPath getPath() { return this.path; } - public IClasspathEntry[] getClasspathEntries() { return this.entries; } + public IClasspathEntry[] getClasspathEntries() { return this.entries; } public String getDescription() { return this.path.toString(); } public int getKind() { return 0; } } @@ -91,15 +92,29 @@ public class ExternalAnnotations18Test extends ModifyingResourceTests { public void initialize(IPath containerPath, IJavaProject project) throws CoreException { String[] jars = Util.getJavaClassLibs(); IClasspathEntry[] entries = new IClasspathEntry[jars.length]; - for (int i = 0; i < jars.length; i++) { - IClasspathAttribute[] extraAttributes; - if (RT_JAR_ANNOTATION_PATH != null && jars[i].endsWith("rt.jar")) + IClasspathAttribute[] extraAttributes; + if (jars.length == 1 && + (jars[0].endsWith("jrt-fs.jar") || JavaModelManager.isJrtInstallation(jars[0]))) { + if (RT_JAR_ANNOTATION_PATH != null) { extraAttributes = externalAnnotationExtraAttributes(RT_JAR_ANNOTATION_PATH); - else + } else { extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES; - entries[i] = JavaCore.newLibraryEntry(new Path(jars[i]), null, null, + } + extraAttributes = externalAnnotationExtraAttributes(RT_JAR_ANNOTATION_PATH); + entries[0] = JavaCore.newJrtEntry((new Path(jars[0])).removeLastSegments(2), null, null, ClasspathEntry.NO_ACCESS_RULES, extraAttributes, false/*not exported*/); + } else { + for (int i = 0; i < jars.length; i++) { + if (RT_JAR_ANNOTATION_PATH != null && jars[i].endsWith("rt.jar")) { + extraAttributes = externalAnnotationExtraAttributes(RT_JAR_ANNOTATION_PATH); + } else { + extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES; + } + entries[i] = JavaCore.newLibraryEntry(new Path(jars[i]), null, null, + ClasspathEntry.NO_ACCESS_RULES, extraAttributes, false/*not exported*/); + } } + JavaCore.setClasspathContainer( new Path(TEST_CONTAINER_NAME), new IJavaProject[]{ project }, diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Java9ElementTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Java9ElementTests.java index bbe21fba87..d4f9ce2f20 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Java9ElementTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Java9ElementTests.java @@ -789,9 +789,8 @@ public class Java9ElementTests extends AbstractJavaModelTests { project1.open(null); IClasspathEntry[] rawClasspath = project1.getRawClasspath(); for (int i = 0; i < rawClasspath.length; i++) { - IPath path = rawClasspath[i].getPath(); - if (path.lastSegment().equals("jrt-fs.jar")) { - path = path.removeLastSegments(2).append("jmods").append("java.base.jmod"); + if (rawClasspath[i].getEntryKind() == IClasspathEntry.CPE_JRT_SYSTEM) { + IPath path = rawClasspath[i].getPath().append("jmods").append("java.base.jmod"); IClasspathEntry newEntry = JavaCore.newLibraryEntry(path, rawClasspath[i].getSourceAttachmentPath(), new Path("java.base")); rawClasspath[i] = newEntry; } @@ -845,8 +844,8 @@ public class Java9ElementTests extends AbstractJavaModelTests { IClasspathEntry[] rawClasspath = project1.getRawClasspath(); for (int i = 0; i < rawClasspath.length; i++) { IPath path = rawClasspath[i].getPath(); - if (path.lastSegment().equals("jrt-fs.jar")) { - path = path.removeLastSegments(2).append("jmods").append("java.base.jmod"); + if (rawClasspath[i].getEntryKind() == IClasspathEntry.CPE_JRT_SYSTEM) { + path = path.append("jmods").append("java.base.jmod"); IClasspathEntry newEntry = JavaCore.newLibraryEntry(path, rawClasspath[i].getSourceAttachmentPath(), new Path("java.base")); rawClasspath[i] = newEntry; } @@ -1410,11 +1409,11 @@ public class Java9ElementTests extends AbstractJavaModelTests { IClasspathEntry[] newClasspath = new IClasspathEntry[rawClasspath.length + 1]; for (int i = 0; i < rawClasspath.length; i++) { IPath path = rawClasspath[i].getPath(); - if (path.lastSegment().equals("jrt-fs.jar")) { - path = path.removeLastSegments(2).append("jmods").append("java.base.jmod"); + if (rawClasspath[i].getEntryKind() == IClasspathEntry.CPE_JRT_SYSTEM) { + path = path.append("jmods").append("java.base.jmod"); IClasspathEntry newEntry = JavaCore.newLibraryEntry(path, rawClasspath[i].getSourceAttachmentPath(), new Path("java.base")); newClasspath[i] = newEntry; - path = path.removeLastSegments(2).append("jmods").append("java.sql.jmod"); + path = path.append("jmods").append("java.sql.jmod"); newEntry = JavaCore.newLibraryEntry(path, rawClasspath[i].getSourceAttachmentPath(), new Path("java.sql")); newClasspath[rawClasspath.length] = newEntry; } else { @@ -1612,6 +1611,37 @@ public class Java9ElementTests extends AbstractJavaModelTests { deleteProject("Java9Elements"); } } + /* + * Tests that a binary type from JRT system is found on the project's classpath + * For now, disabled since it kicks off indexing eventually timing out. + */ + public void testIsOnClasspath1() throws CoreException { + try { + IJavaProject project1 = createJava9Project("Java9Elements", new String[] {"src"}); + project1.open(null); + String fileContent = + "module first {\n" + + " requires second;\n" + + " uses pack11.X11;\n" + + "}\n"; + createFile("/Java9Elements/src/module-info.java", fileContent); + createFolder("/Java9Elements/src/pack11"); + createFile("/Java9Elements/src/pack11/X11.java", + "package pack11;\n" + + "public interface X11 extends Serializable {}\n"); + + project1.close(); // sync + project1.open(null); + waitUntilIndexesReady(); + IType type = project1.findType("java.io.Serializable"); + assertNotNull("type not found", type); + assertTrue("should be a binary type", type.isBinary()); + assertTrue("Not found in the classpath", project1.isOnClasspath(type)); + } + finally { + deleteProject("Java9Elements"); + } + } public void testBug530402() throws CoreException { try { IJavaProject project = createJavaProject("Java9Elements", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); @@ -1665,6 +1695,31 @@ public class Java9ElementTests extends AbstractJavaModelTests { finally { deleteProject("Java9Elements"); } + } + public void testIsOnClasspath2() throws CoreException { + try { + IJavaProject project1 = createJavaProject("Java9Elements", new String[] {"src"}, new String[] {"JCL19_LIB"}, "bin", "9"); + project1.open(null); + String fileContent = + "module first {\n" + + " requires second;\n" + + " uses pack11.X11;\n" + + "}\n"; + createFile("/Java9Elements/src/module-info.java", fileContent); + createFolder("/Java9Elements/src/pack11"); + createFile("/Java9Elements/src/pack11/X11.java", + "package pack11;\n" + + "public interface X11 extends Serializable {}\n"); + + project1.close(); // sync + project1.open(null); + + ICompilationUnit unit = getCompilationUnit("/Java9Elements/src/module-info.java"); + assertTrue("Not found in the classpath", project1.isOnClasspath(unit)); + } + finally { + deleteProject("Java9Elements"); + } } public void test530653() throws CoreException, IOException { try { diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java index c3c7911bd0..1fa7b72b0c 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java @@ -3040,4 +3040,80 @@ public void testBug522554_3() throws CoreException { deleteProject(prj); } } +// module patching +public void testBug522554_4() throws CoreException { + if (!isJRE9) return; + IJavaProject prj = null; + try { + IClasspathAttribute[] jreAttributes = { + JavaCore.newClasspathAttribute(IClasspathAttribute.PATCH_MODULE, "java.activation"), + JavaCore.newClasspathAttribute(IClasspathAttribute.LIMIT_MODULES, "java.se,jdk.security.auth,jdk.security.jgss,jdk.net,java.activation") + }; + prj = createJava9ProjectWithJREAttributes("mod1", new String[] {"src" }, jreAttributes); + createFolder("/mod1/src/modify"); + createFile("/mod1/src/modify/Test.java", + "package modify;\n" + + "\n" + + "import com.sun.activation.registries.*; \n" + + "\n" + + "public class Test {\n" + + " LogSupport logger;\n" + + "}\n"); + prj.getProject().getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + IMarker[] markers = prj.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); + assertMarkers("Unexpected markers", "", markers); + + IClasspathEntry systemLibrary = prj.getRawClasspath()[1]; + assertEquals("Should be system library", getJRE9Path(), systemLibrary.getPath()); + String argLine = JavaModelAccess.getModuleCLIOptions(prj, systemLibrary); + String projectLoc = prj.getProject().getLocation().toOSString(); + assertEquals("Unexpected CLI options", + "--patch-module java.activation="+projectLoc+File.separator+"bin " + + "--limit-modules java.activation,java.se,jdk.net,jdk.security.auth,jdk.security.jgss", + argLine); + } finally { + if (prj != null) + deleteProject(prj); + } +} +// module patching - multiple output locations +public void testBug522554_5() throws CoreException { + if (!isJRE9) return; + IJavaProject prj = null; + try { + IClasspathAttribute[] jreAttributes = { + JavaCore.newClasspathAttribute(IClasspathAttribute.PATCH_MODULE, "java.activation"), + }; + prj = createJava9ProjectWithJREAttributes("mod1", new String[] {"src" }, jreAttributes); + createFolder("/mod1/src2"); + createFolder("/mod1/bin2"); + addClasspathEntry(prj, JavaCore.newSourceEntry(new Path("/mod1/src2"), null, new Path("/mod1/bin2"))); + createFolder("/mod1/src/modify"); + createFile("/mod1/src/modify/Test.java", + "package modify;\n" + + "\n" + + "import com.sun.activation.registries.*; \n" + + "\n" + + "public class Test {\n" + + " LogSupport logger;\n" + + "}\n"); + prj.getProject().getWorkspace().build(IncrementalProjectBuilder.AUTO_BUILD, null); + IMarker[] markers = prj.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE); + assertMarkers("Unexpected markers", "", markers); + + IClasspathEntry systemLibrary = prj.getRawClasspath()[1]; + assertEquals("Should be system library", getJRE9Path(), systemLibrary.getPath()); + String argLine = JavaModelAccess.getModuleCLIOptions(prj, systemLibrary); + String projectLoc = prj.getProject().getLocation().toOSString(); + assertEquals("Unexpected CLI options", + "--patch-module java.activation="+projectLoc+File.separator+"bin"+File.pathSeparator+projectLoc+File.separator+"bin2", + argLine); + } finally { + if (prj != null) + deleteProject(prj); + } +} +protected IPath getJRE9Path() { + return new Path(System.getProperty("java.home")); +} } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java index 7b6388301d..e9d814eaee 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java @@ -57,7 +57,7 @@ public class ModuleBuilderTests extends ModifyingResourceTests { } static { - // TESTS_NAMES = new String[] { "testBug528467" }; +// TESTS_NAMES = new String[] { "testPatch2" }; } private String sourceWorkspacePath = null; protected ProblemRequestor problemRequestor; @@ -2636,9 +2636,8 @@ public class ModuleBuilderTests extends ModifyingResourceTests { IJavaProject project = createJava9Project("Test01", new String[]{"src"}); IClasspathEntry[] rawClasspath = project.getRawClasspath(); for (int i = 0; i < rawClasspath.length; i++) { - IPath path = rawClasspath[i].getPath(); - if (path.lastSegment().equals("jrt-fs.jar")) { - path = path.removeLastSegments(2).append("jmods").append("java.base.jmod"); + if (rawClasspath[i].getEntryKind() == IClasspathEntry.CPE_JRT_SYSTEM) { + IPath path = rawClasspath[i].getPath().append("jmods").append("java.base.jmod"); IClasspathEntry newEntry = JavaCore.newLibraryEntry(path, rawClasspath[i].getSourceAttachmentPath(), new Path("java.base")); rawClasspath[i] = newEntry; } @@ -6429,12 +6428,11 @@ public class ModuleBuilderTests extends ModifyingResourceTests { String jrtPath = null; for (int i = 0; i < rawClasspath.length; i++) { IClasspathEntry iClasspathEntry = rawClasspath[i]; - if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && - iClasspathEntry.getPath().toString().endsWith("jrt-fs.jar")) { + if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_JRT_SYSTEM) { jrtPath = iClasspathEntry.getPath().toOSString(); IAccessRule[] pathRules = new IAccessRule[1]; pathRules[0] = JavaCore.newAccessRule(new Path("java/awt/**"), IAccessRule.K_NON_ACCESSIBLE); - IClasspathEntry newEntry = JavaCore.newLibraryEntry(iClasspathEntry.getPath(), + IClasspathEntry newEntry = JavaCore.newJrtEntry(iClasspathEntry.getPath(), iClasspathEntry.getSourceAttachmentPath(), iClasspathEntry.getSourceAttachmentRootPath(), pathRules, @@ -6476,12 +6474,11 @@ public class ModuleBuilderTests extends ModifyingResourceTests { String jrtPath = null; for (int i = 0; i < rawClasspath.length; i++) { IClasspathEntry iClasspathEntry = rawClasspath[i]; - if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && - iClasspathEntry.getPath().toString().endsWith("jrt-fs.jar")) { + if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_JRT_SYSTEM) { jrtPath = iClasspathEntry.getPath().toOSString(); IAccessRule[] pathRules = new IAccessRule[1]; pathRules[0] = JavaCore.newAccessRule(new Path("java/awt/Image"), IAccessRule.K_NON_ACCESSIBLE); - IClasspathEntry newEntry = JavaCore.newLibraryEntry(iClasspathEntry.getPath(), + IClasspathEntry newEntry = JavaCore.newJrtEntry(iClasspathEntry.getPath(), iClasspathEntry.getSourceAttachmentPath(), iClasspathEntry.getSourceAttachmentRootPath(), pathRules, @@ -6529,12 +6526,11 @@ public class ModuleBuilderTests extends ModifyingResourceTests { String jrtPath = null; for (int i = 0; i < rawClasspath.length; i++) { IClasspathEntry iClasspathEntry = rawClasspath[i]; - if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && - iClasspathEntry.getPath().toString().endsWith("jrt-fs.jar")) { + if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_JRT_SYSTEM) { jrtPath = iClasspathEntry.getPath().toOSString(); IAccessRule[] pathRules = new IAccessRule[1]; pathRules[0] = JavaCore.newAccessRule(new Path("java/awt/**"), IAccessRule.K_NON_ACCESSIBLE); - IClasspathEntry newEntry = JavaCore.newLibraryEntry(iClasspathEntry.getPath(), + IClasspathEntry newEntry = JavaCore.newJrtEntry(iClasspathEntry.getPath(), iClasspathEntry.getSourceAttachmentPath(), iClasspathEntry.getSourceAttachmentRootPath(), pathRules, diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java index 573dae8e1a..4ba351ac7e 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2017 IBM Corporation and others. * 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 @@ -158,7 +158,7 @@ static { // JavaModelManager.VERBOSE = true; // org.eclipse.jdt.internal.core.search.BasicSearchEngine.VERBOSE = true; // TESTS_PREFIX = "testIgnoreIfBetterNonAccessibleRule"; -// TESTS_NAMES = new String[] { "testBug374176" }; +// TESTS_NAMES = new String[] { "testConvertPrimitiveTypeArrayTypeArgument" }; // TESTS_NUMBERS = new int[] { 118823 }; // TESTS_RANGE = new int[] { 16, -1 }; } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java index d779122ec0..dba58619aa 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2017 IBM Corporation and others. + * Copyright (c) 2016, 2018 IBM Corporation and others. * 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 @@ -11,7 +11,6 @@ package org.eclipse.jdt.core.tests.model; -import java.io.File; import java.io.IOException; import org.eclipse.core.resources.IFile; @@ -59,7 +58,7 @@ public class ResolveTests9 extends AbstractJavaModelTests { IJavaProject project = setUpJavaProject("Resolve", "9", true); - String bootModPath = System.getProperty("java.home") + File.separator +"jrt-fs.jar"; + String bootModPath = System.getProperty("java.home"); IClasspathEntry jrtEntry = JavaCore.newLibraryEntry(new Path(bootModPath), null, null, null, null, false); IClasspathEntry[] old = project.getRawClasspath(); IClasspathEntry[] newPath = new IClasspathEntry[old.length +1]; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java index b7683aad29..93c1a7b318 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java @@ -902,14 +902,6 @@ public class Util implements SuffixConstants { return true; } - /** - * Returns true iff str.toLowerCase().endsWith("jrt-fs.jar") - * implementation is not creating extra strings. - */ - public final static boolean isJrt(String name) { - return name.endsWith(JRTUtil.JRT_FS_JAR); - } - public static void reverseQuickSort(char[][] list, int left, int right) { int original_left= left; int original_right= right; diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathContainer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathContainer.java index 5b862f66d7..1ff8d89789 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathContainer.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathContainer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * 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 @@ -25,8 +25,12 @@ import org.eclipse.core.runtime.IPath; * <ul> * <li> library entries (<code>CPE_LIBRARY</code>) </li> * <li> project entries (<code>CPE_PROJECT</code>) </li> + * <li> Module based Java Runtime entries (<code>CPE_JRT_SYSTEM</code>) </li> * </ul> * In particular, a classpath container can neither reference further classpath containers or classpath variables. + * <p> + * Note: Even though it is allowed for containers to have multiple entries of kind <code>CPE_JRT_SYSTEM</code> + * typically, there will be only one such entry. * <p> * A library entry can reference other libraries through the Class-Path section of the JAR's MANIFEST.MF file. If the * container wants such referenced entries to be part of the classpath, the container must explicitly add them to the @@ -64,6 +68,7 @@ public interface IClasspathContainer { * <ul> * <li> library entries (<code>CPE_LIBRARY</code>) </li> * <li> project entries (<code>CPE_PROJECT</code>) </li> + * <li> Module based Java Runtime entries (<code>CPE_JRT_SYSTEM</code>) </li> * </ul> * A classpath container can neither reference further classpath containers * or classpath variables. @@ -84,6 +89,7 @@ public interface IClasspathContainer { * only the following Java model APIs: * <ul> * <li>{@link JavaCore#newLibraryEntry(IPath, IPath, IPath, boolean)} and variants</li> + * <li>{@link JavaCore#newJrtEntry(IPath, IPath, IPath, IAccessRule[], IClasspathAttribute[], boolean)}</li> * <li>{@link JavaCore#newProjectEntry(IPath, boolean)} and variants</li> * <li>{@link JavaCore#create(org.eclipse.core.resources.IWorkspaceRoot)}</li> * <li>{@link JavaCore#create(org.eclipse.core.resources.IProject)}</li> diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathEntry.java index d4e4d46814..199fbd270e 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathEntry.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IClasspathEntry.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2017 IBM Corporation and others. * 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 @@ -148,6 +148,13 @@ public interface IClasspathEntry { * @since 2.0 */ int CPE_CONTAINER = 5; + /** + * Entry kind constant describing a classpath entry representing + * a modularized Java run time system. + * + * @since 3.14 + */ + int CPE_JRT_SYSTEM = 6; /** * Returns whether the access rules of the project's exported entries should be combined with this entry's access rules. @@ -181,7 +188,7 @@ public interface IClasspathEntry { /** * Returns the kind of this classpath entry. * - * @return one of: + * @return one of but not limited to: * <ul> * <li>{@link #CPE_SOURCE} - this entry describes a source root in its project @@ -191,9 +198,12 @@ public interface IClasspathEntry { * * <li>{@link #CPE_VARIABLE} - this entry describes a project or library * indirectly via a classpath variable in the first segment of the path - * * + * * <li>{@link #CPE_CONTAINER} - this entry describes set of entries * referenced indirectly via a classpath container + * + * <li>{@link #CPE_JRT_SYSTEM} - this entry describes an installation of module based + * Java Runtime system. * </ul> */ int getEntryKind(); @@ -383,6 +393,9 @@ public interface IClasspathEntry { * extra segments that can be used as additional hints for resolving this container * reference (also see {@link IClasspathContainer}). * </li> + * <li> A module based Java Runtime (JRT) ({@link #CPE_JRT_SYSTEM}) - the path is the absolute + * path to the Java Runtime installation. + * </li> * </ul> * * @return the path of this classpath entry diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java index 6c8bf763f2..5c5f5b0bc2 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * 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 @@ -4627,6 +4627,41 @@ public final class JavaCore extends Plugin { } /** + * Creates and returns a new classpath entry representing a modularized Java runtime system. + * The entry is of kind <code>CPE_JRT_SYSTEM</code> and the given path points to the + * Java run time installation. + * + * @param javaHome the path where the Java Runtime is located + * @return a new JRT classpath entry + * @since 3.14 + */ + public static IClasspathEntry newJrtEntry(IPath javaHome, + IPath sourceAttachmentPath, + IPath sourceAttachmentRootPath, + IAccessRule[] accessRules, + IClasspathAttribute[] extraAttributes, + boolean isExported) { + if (accessRules == null || accessRules.length==0) { + accessRules = ClasspathEntry.NO_ACCESS_RULES; + } + if (extraAttributes == null || extraAttributes.length==0) { + extraAttributes = ClasspathEntry.NO_EXTRA_ATTRIBUTES; + } + return new ClasspathEntry( + IPackageFragmentRoot.K_BINARY, + IClasspathEntry.CPE_JRT_SYSTEM, + javaHome, + ClasspathEntry.INCLUDE_ALL, // inclusion patterns + ClasspathEntry.EXCLUDE_NONE, // exclusion patterns + sourceAttachmentPath, // source attachment + sourceAttachmentRootPath, // source attachment root + null, // specific output folder + isExported, + accessRules, + true, // combine access rules + extraAttributes); + } + /** * Creates and returns a new classpath entry of kind <code>CPE_CONTAINER</code> * for the given path. This method is fully equivalent to calling * {@link #newContainerEntry(IPath, IAccessRule[], IClasspathAttribute[], boolean) diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AbstractClassFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AbstractClassFile.java index 8a34601403..4923abd37c 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AbstractClassFile.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/AbstractClassFile.java @@ -185,7 +185,7 @@ public abstract class AbstractClassFile extends Openable implements IClassFile, protected byte[] getClassFileContent(JarPackageFragmentRoot root, String className) throws CoreException, IOException { byte[] contents = null; String rootPath = root.getPath().toOSString(); - if (org.eclipse.jdt.internal.compiler.util.Util.isJrt(rootPath)) { + if (root instanceof JrtPackageFragmentRoot) { try { contents = org.eclipse.jdt.internal.compiler.util.JRTUtil.getClassfileContent( new File(rootPath), diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java index 4227b6782f..93c925cc53 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * 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 @@ -219,17 +219,17 @@ private IBinaryType getJarBinaryTypeInfo() throws CoreException, IOException, Cl } IBinaryType result = null; IPackageFragmentRoot root = getPackageFragmentRoot(); - if (getPackageFragmentRoot() instanceof JarPackageFragmentRoot) { + if (root instanceof JarPackageFragmentRoot) { if (root instanceof JrtPackageFragmentRoot || this.name.equals(IModule.MODULE_INFO)) { PackageFragment pkg = (PackageFragment) getParent(); - JarPackageFragmentRoot jarRoot = (JarPackageFragmentRoot) getPackageFragmentRoot(); + JarPackageFragmentRoot jarRoot = (JarPackageFragmentRoot) root; String entryName = jarRoot.getClassFilePath(Util.concatWith(pkg.names, getElementName(), '/')); byte[] contents = getClassFileContent(jarRoot, entryName); if (contents != null) { String fileName; - String rootPath = root.getPath().toOSString(); + char[] mod = null; String rootIdentifier = root.getHandleIdentifier(); - if (org.eclipse.jdt.internal.compiler.util.Util.isJrt(rootPath)) { + if (root instanceof JrtPackageFragmentRoot) { int slash = rootIdentifier.lastIndexOf('/'); if (slash != -1) { StringBuilder extract = new StringBuilder(); @@ -241,7 +241,9 @@ private IBinaryType getJarBinaryTypeInfo() throws CoreException, IOException, Cl } } fileName = rootIdentifier + IDependent.JAR_FILE_ENTRY_SEPARATOR + entryName; - result = new ClassFileReader(contents, fileName.toCharArray(), false); + ClassFileReader reader = new ClassFileReader(contents, fileName.toCharArray(), false); + reader.moduleName = mod; + result = reader; } } else { result = BinaryTypeFactory.readType(descriptor, null); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java index f47326fa57..b9ef295285 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * 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 @@ -119,7 +119,7 @@ public class ClasspathEntry implements IClasspathEntry { /** * Describes the kind of classpath entry - one of - * CPE_PROJECT, CPE_LIBRARY, CPE_SOURCE, CPE_VARIABLE or CPE_CONTAINER + * CPE_PROJECT, CPE_LIBRARY, CPE_SOURCE, CPE_VARIABLE, CPE_CONTAINER or CPE_JRT_SYSTEM */ public int entryKind; @@ -131,27 +131,12 @@ public class ClasspathEntry implements IClasspathEntry { public int contentKind; /** - * The meaning of the path of a classpath entry depends on its entry kind:<ul> - * <li>Source code in the current project (<code>CPE_SOURCE</code>) - - * The path associated with this entry is the absolute path to the root folder. </li> - * <li>A binary library in the current project (<code>CPE_LIBRARY</code>) - the path - * associated with this entry is the absolute path to the JAR (or root folder), and - * in case it refers to an external JAR, then there is no associated resource in - * the workbench. - * <li>A required project (<code>CPE_PROJECT</code>) - the path of the entry denotes the - * path to the corresponding project resource.</li> - * <li>A variable entry (<code>CPE_VARIABLE</code>) - the first segment of the path - * is the name of a classpath variable. If this classpath variable - * is bound to the path <it>P</it>, the path of the corresponding classpath entry - * is computed by appending to <it>P</it> the segments of the returned - * path without the variable.</li> - * <li> A container entry (<code>CPE_CONTAINER</code>) - the first segment of the path is denoting - * the unique container identifier (for which a <code>ClasspathContainerInitializer</code> could be - * registered), and the remaining segments are used as additional hints for resolving the container entry to - * an actual <code>IClasspathContainer</code>.</li> + * The meaning of the path of a classpath entry depends on its entry kind. For + * more details, see {@link IClasspathEntry#getPath()}. */ public IPath path; + /** * Patterns allowing to include/exclude portions of the resource tree denoted by this entry path. */ @@ -817,6 +802,18 @@ public class ClasspathEntry implements IClasspathEntry { extraAttributes, isExported); break; + case IClasspathEntry.CPE_JRT_SYSTEM : + // Caveat: This is meant to be a resolved classpath entry. + // Only required for tests that will put a CPE_JRT_SYSTEM in the raw classpath. + // But this also allows anyone to use this in the .classpath directly instead of JRE_CONTAINER + entry = JavaCore.newJrtEntry( + path, + sourceAttachmentPath, + sourceAttachmentRootPath, + accessRules, + extraAttributes, + isExported); + break; case IClasspathEntry.CPE_SOURCE : // must be an entry in this project or specify another project String projSegment = path.segment(0); @@ -1489,6 +1486,8 @@ public class ClasspathEntry implements IClasspathEntry { return IClasspathEntry.CPE_LIBRARY; if (kindStr.equalsIgnoreCase("output")) //$NON-NLS-1$ return ClasspathEntry.K_OUTPUT; + if (kindStr.equalsIgnoreCase("jrt")) //$NON-NLS-1$ + return IClasspathEntry.CPE_JRT_SYSTEM; return -1; } @@ -1508,6 +1507,8 @@ public class ClasspathEntry implements IClasspathEntry { return "var"; //$NON-NLS-1$ case IClasspathEntry.CPE_CONTAINER : return "con"; //$NON-NLS-1$ + case IClasspathEntry.CPE_JRT_SYSTEM : + return "jrt"; //$NON-NLS-1$ case ClasspathEntry.K_OUTPUT : return "output"; //$NON-NLS-1$ default : @@ -1561,6 +1562,8 @@ public class ClasspathEntry implements IClasspathEntry { case IClasspathEntry.CPE_CONTAINER : buffer.append("CPE_CONTAINER"); //$NON-NLS-1$ break; + case IClasspathEntry.CPE_JRT_SYSTEM : + buffer.append("CPE_JRT_SYSTEM"); //$NON-NLS-1$ } buffer.append("]["); //$NON-NLS-1$ switch (getContentKind()) { @@ -1712,6 +1715,9 @@ public class ClasspathEntry implements IClasspathEntry { case IClasspathEntry.CPE_CONTAINER : this.rootID = "[CON]"+this.path; //$NON-NLS-1$ break; + case IClasspathEntry.CPE_JRT_SYSTEM : + this.rootID = "[JRT]"+this.path; //$NON-NLS-1$ + break; default : this.rootID = ""; //$NON-NLS-1$ break; @@ -1738,6 +1744,7 @@ public class ClasspathEntry implements IClasspathEntry { switch(getEntryKind()) { case IClasspathEntry.CPE_LIBRARY : case IClasspathEntry.CPE_VARIABLE : + case IClasspathEntry.CPE_JRT_SYSTEM : break; default : return null; diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java index 57130cfb9f..4ff21949ba 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java @@ -48,7 +48,7 @@ public class JarEntryFile extends JarEntryResource { @Override public InputStream getContents() throws CoreException { IPackageFragmentRoot root = getPackageFragmentRoot(); - if (Util.isJrt(root.getPath().toOSString())) { + if (root instanceof JrtPackageFragmentRoot) { try { IPath rootPath = root.getPath(); Object target = JavaModel.getTarget(rootPath, false); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java index f31982ad5a..c5e778573d 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java @@ -742,6 +742,7 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement entry= root.getRawClasspathEntry(); switch (entry.getEntryKind()) { + case IClasspathEntry.CPE_JRT_SYSTEM: case IClasspathEntry.CPE_LIBRARY: case IClasspathEntry.CPE_VARIABLE: return getLibraryJavadocLocation(entry); @@ -754,6 +755,7 @@ public abstract class JavaElement extends PlatformObject implements IJavaElement protected static URL getLibraryJavadocLocation(IClasspathEntry entry) throws JavaModelException { switch(entry.getEntryKind()) { + case IClasspathEntry.CPE_JRT_SYSTEM : case IClasspathEntry.CPE_LIBRARY : case IClasspathEntry.CPE_VARIABLE : break; diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java index 12220690e7..b82ef1b784 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java @@ -383,9 +383,6 @@ public static boolean isFile(Object target) { return false; } -public static boolean isJimage(File file) { - return JavaModelManager.isJrt(file.getPath()); -} public static boolean isJmod(File file) { IPath path = Path.fromOSString(file.getPath()); if (path.getFileExtension().equalsIgnoreCase(SuffixConstants.EXTENSION_jmod)) { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java index 74cbf5c8d5..b5c04af72d 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java @@ -32,6 +32,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.StringReader; import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Paths; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; @@ -42,7 +44,9 @@ import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Map; +import java.util.Optional; import java.util.Map.Entry; +import java.util.stream.Stream; import java.util.Set; import java.util.WeakHashMap; import java.util.zip.ZipException; @@ -127,7 +131,6 @@ import org.eclipse.jdt.internal.compiler.env.AccessRestriction; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt; -import org.eclipse.jdt.internal.compiler.util.JRTUtil; import org.eclipse.jdt.internal.compiler.util.ObjectVector; import org.eclipse.jdt.internal.core.JavaProjectElementInfo.ProjectCache; import org.eclipse.jdt.internal.core.builder.JavaBuilder; @@ -180,6 +183,8 @@ public class JavaModelManager implements ISaveParticipant, IContentTypeChangeLis private static final String NON_CHAINING_JARS_CACHE = "nonChainingJarsCache"; //$NON-NLS-1$ private static final String EXTERNAL_FILES_CACHE = "externalFilesCache"; //$NON-NLS-1$ private static final String ASSUMED_EXTERNAL_FILES_CACHE = "assumedExternalFilesCache"; //$NON-NLS-1$ + private static final String RELEASE_FILE = "release"; //$NON-NLS-1$ + private static final String JAVA_VERSION = "JAVA_VERSION"; //$NON-NLS-1$ public static enum ArchiveValidity { BAD_FORMAT, UNABLE_TO_READ, FILE_NOT_FOUND, VALID; @@ -2845,19 +2850,25 @@ public class JavaModelManager implements ISaveParticipant, IContentTypeChangeLis return this.workspaceScope; } - public static boolean isJrt(IPath path) { - return path.toString().endsWith(JRTUtil.JRT_FS_JAR); - } - - public static boolean isJrt(String path) { - return isJrt(new Path(path)); + public static boolean isJrtInstallation(String path) { + java.nio.file.Path releasePath = Paths.get(path, RELEASE_FILE); + if (!Files.exists(releasePath)) + return false; + try (Stream<String> lines = Files.lines(releasePath).filter(s -> s.contains(JAVA_VERSION))) { + Optional<String> hasVersion = lines.findFirst(); + if (hasVersion.isPresent()) { + String line = hasVersion.get(); + String version = line.substring(14, line.length() - 1); // length of JAVA_VERSION + 2 in JAVA_VERSION="9" + return JavaCore.compareJavaVersions(version, JavaCore.VERSION_1_8) > 0; + } + } + catch (IOException e) { + // Just return false; + } + return false; } public void verifyArchiveContent(IPath path) throws CoreException { - // TODO: we haven't finalized what path the JRT is represented by. Don't attempt to validate it. - if (isJrt(path)) { - return; - } throwExceptionIfArchiveInvalid(path); // Check if we can determine the archive's validity by examining the index if (JavaIndex.isEnabled()) { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java index ab9df20290..b7906da61c 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * 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 @@ -663,6 +663,31 @@ public class JavaProject IPackageFragmentRoot root = null; switch(resolvedEntry.getEntryKind()){ + case IClasspathEntry.CPE_JRT_SYSTEM : + PerProjectInfo info = getPerProjectInfo(); + ObjectVector imageRoots; + if (info.jrtRoots == null || !info.jrtRoots.containsKey(entryPath)) { + imageRoots = new ObjectVector(); + loadModulesInJrt(entryPath, imageRoots, rootToResolvedEntries, resolvedEntry, referringEntry); + info.setJrtPackageRoots(entryPath, imageRoots); // unfiltered + rootIDs.add(rootID); + } else { + imageRoots = info.jrtRoots.get(entryPath); + } + if (filterModuleRoots) { + List<String> rootModules = null; + String limitModules = ClasspathEntry.getExtraAttribute(resolvedEntry, IClasspathAttribute.LIMIT_MODULES); + if (limitModules != null) { + rootModules = Arrays.asList(limitModules.split(",")); //$NON-NLS-1$ + } else if (isUnNamedModule()) { + rootModules = defaultRootModules((Iterable) imageRoots); + } + if (rootModules != null) { + imageRoots = filterLimitedModules(entryPath, imageRoots, rootModules); + } + } + accumulatedRoots.addAll(imageRoots); + break; // source folder case IClasspathEntry.CPE_SOURCE : @@ -690,31 +715,7 @@ public class JavaProject } else if (target instanceof File) { // external target if (JavaModel.isFile(target)) { - if (JavaModel.isJimage((File) target)) { - PerProjectInfo info = getPerProjectInfo(); - ObjectVector imageRoots; - if (info.jrtRoots == null || !info.jrtRoots.containsKey(entryPath)) { - imageRoots = new ObjectVector(); - loadModulesInJimage(entryPath, imageRoots, rootToResolvedEntries, resolvedEntry, referringEntry); - info.setJrtPackageRoots(entryPath, imageRoots); // unfiltered - rootIDs.add(rootID); - } else { - imageRoots = info.jrtRoots.get(entryPath); - } - if (filterModuleRoots) { - List<String> rootModules = null; - String limitModules = ClasspathEntry.getExtraAttribute(resolvedEntry, IClasspathAttribute.LIMIT_MODULES); - if (limitModules != null) { - rootModules = Arrays.asList(limitModules.split(",")); //$NON-NLS-1$ - } else if (isUnNamedModule()) { - rootModules = defaultRootModules((Iterable) imageRoots); - } - if (rootModules != null) { - imageRoots = filterLimitedModules(entryPath, imageRoots, rootModules); - } - } - accumulatedRoots.addAll(imageRoots); - } else if (JavaModel.isJmod((File) target)) { + if (JavaModel.isJmod((File) target)) { root = new JModPackageFragmentRoot(entryPath, this); } else { @@ -892,7 +893,7 @@ public class JavaProject } } - private void loadModulesInJimage(final IPath imagePath, final ObjectVector roots, final Map rootToResolvedEntries, + private void loadModulesInJrt(final IPath imagePath, final ObjectVector roots, final Map rootToResolvedEntries, final IClasspathEntry resolvedEntry, final IClasspathEntry referringEntry) { try { org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(imagePath.toFile(), @@ -2203,7 +2204,7 @@ public class JavaProject IFolder linkedFolder = JavaModelManager.getExternalManager().getFolder(externalLibraryPath); if (linkedFolder != null) return new ExternalPackageFragmentRoot(linkedFolder, externalLibraryPath, this); - if (JavaModelManager.isJrt(externalLibraryPath)) { + if (JavaModelManager.isJrtInstallation(externalLibraryPath.toOSString())) { return this.new JImageModuleFragmentBridge(externalLibraryPath); } Object target = JavaModel.getTarget(externalLibraryPath, true/*check existency*/); @@ -2594,6 +2595,7 @@ public class JavaProject IClasspathEntry entry = rawClasspath[i]; switch (entry.getEntryKind()) { case IClasspathEntry.CPE_LIBRARY: + case IClasspathEntry.CPE_JRT_SYSTEM: case IClasspathEntry.CPE_PROJECT: case IClasspathEntry.CPE_SOURCE: if (isOnClasspathEntry(elementPath, isFolderPath, isPackageFragmentRoot, entry)) @@ -3687,6 +3689,7 @@ public class JavaProject break; case IClasspathEntry.CPE_LIBRARY: case IClasspathEntry.CPE_CONTAINER: + case IClasspathEntry.CPE_JRT_SYSTEM: for (IPackageFragmentRoot root : findPackageFragmentRoots(entry)) { module = root.getModuleDescription(); if (module != null && module.getElementName().equals(mainModule)) diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java index bca2552a1e..d0962f5754 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java @@ -121,6 +121,11 @@ public class JrtPackageFragmentRoot extends JarPackageFragmentRoot implements IM return new JarPackageFragment(this, pkgName); } @Override + protected IStatus validateExistence(IResource underlyingResource) { + // check whether this pkg fragment root can be opened + return validateOnClasspath(); + } + @Override public int hashCode() { return this.jarPath.hashCode() + this.moduleName.hashCode(); } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModularClassFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModularClassFile.java index 0f00d8a466..eabf217317 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModularClassFile.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModularClassFile.java @@ -168,9 +168,8 @@ public class ModularClassFile extends AbstractClassFile implements IModularClass byte[] contents = getClassFileContent(jarRoot, entryName); if (contents != null) { String fileName; - String rootPath = root.getPath().toOSString(); String rootIdentifier = root.getHandleIdentifier(); - if (org.eclipse.jdt.internal.compiler.util.Util.isJrt(rootPath)) { + if (root instanceof JrtPackageFragmentRoot) { int slash = rootIdentifier.lastIndexOf('/'); if (slash != -1) rootIdentifier = rootIdentifier.substring(0, slash); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java index 93b4ca0990..d4a3c4eac7 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * 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 @@ -494,7 +494,7 @@ protected void getHandleMemento(StringBuffer buff) { ((JavaElement)getParent()).getHandleMemento(buff); buff.append(getHandleMementoDelimiter()); escapeMementoName(buff, path.toString()); - if (org.eclipse.jdt.internal.compiler.util.Util.isJrt(path.toOSString())) { + if (this instanceof JrtPackageFragmentRoot) { buff.append(JavaElement.JEM_MODULE); escapeMementoName(buff, getElementName()); } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java index 1c4f3acdee..62688325d4 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * 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 @@ -549,22 +549,8 @@ public class SourceMapper String sourceLevel = null; String complianceLevel = null; - if (Util.isJrt(pkgFragmentRootPath.toOSString())) { - try { - JrtPackageNamesAdderVisitor jrtPackageNamesAdderVisitor = new JrtPackageNamesAdderVisitor(firstLevelPackageNames, - sourceLevel, complianceLevel, containsADefaultPackage, containsJavaSource, root); - org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(root.getPath().toFile(), jrtPackageNamesAdderVisitor, JRTUtil.NOTIFY_FILES); - sourceLevel = jrtPackageNamesAdderVisitor.sourceLevel; - complianceLevel = jrtPackageNamesAdderVisitor.complianceLevel; - containsADefaultPackage = jrtPackageNamesAdderVisitor.containsADefaultPackage; - containsJavaSource = jrtPackageNamesAdderVisitor.containsJavaSource; - } catch (IOException e) { - // We are not reading any specific file, so, move on for now - if (VERBOSE) { - e.printStackTrace(); - } - } - } else if (root.isArchive()) { + + if (root.isArchive()) { JavaModelManager manager = JavaModelManager.getJavaModelManager(); ZipFile zip = null; try { @@ -603,7 +589,24 @@ public class SourceMapper } } else { Object target = JavaModel.getTarget(root.getPath(), true); - if (target instanceof IResource) { + if (target == null) { + if (root instanceof JrtPackageFragmentRoot) { + try { + JrtPackageNamesAdderVisitor jrtPackageNamesAdderVisitor = new JrtPackageNamesAdderVisitor(firstLevelPackageNames, + sourceLevel, complianceLevel, containsADefaultPackage, containsJavaSource, root); + org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(root.getPath().toFile(), jrtPackageNamesAdderVisitor, JRTUtil.NOTIFY_FILES); + sourceLevel = jrtPackageNamesAdderVisitor.sourceLevel; + complianceLevel = jrtPackageNamesAdderVisitor.complianceLevel; + containsADefaultPackage = jrtPackageNamesAdderVisitor.containsADefaultPackage; + containsJavaSource = jrtPackageNamesAdderVisitor.containsJavaSource; + } catch (IOException e) { + // We are not reading any specific file, so, move on for now + if (VERBOSE) { + e.printStackTrace(); + } + } + } + } else if (target instanceof IResource) { IResource resource = (IResource) target; if (resource instanceof IContainer) { try { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java index 0f43c83dab..b95c7e7625 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java @@ -124,13 +124,14 @@ static ClasspathLocation forLibrary(String libraryPathname, AccessRuleSet accessRuleSet, IPath annotationsPath, boolean autoModule) { - return Util.isJrt(libraryPathname) ? - new ClasspathJrt(libraryPathname, accessRuleSet, annotationsPath) : - Util.archiveFormat(libraryPathname) == Util.JMOD_FILE ? + return Util.archiveFormat(libraryPathname) == Util.JMOD_FILE ? new ClasspathJMod(libraryPathname, lastModified, accessRuleSet, annotationsPath) : new ClasspathJar(libraryPathname, lastModified, accessRuleSet, annotationsPath, autoModule); } +static ClasspathJrt forJrtSystem(String jdkHome, AccessRuleSet accessRuleSet, IPath annotationsPath) { + return new ClasspathJrt(jdkHome, accessRuleSet, annotationsPath); +} public static ClasspathLocation forLibrary(String libraryPathname, AccessRuleSet accessRuleSet, IPath annotationsPath, boolean autoModule) { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java index d7090e8166..909332dd10 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java @@ -137,7 +137,8 @@ private void computeClasspathLocations( IPath path = entry.getPath(); Object target = JavaModel.getTarget(path, true); IPath externalAnnotationPath = ClasspathEntry.getExternalAnnotationPath(entry, javaProject.getProject(), true); - if (target == null) continue nextEntry; + if (target == null && entry.getEntryKind() != IClasspathEntry.CPE_JRT_SYSTEM) + continue nextEntry; boolean isOnModulePath = isOnModulePath(entry); Set<String> limitModules = ModuleEntryProcessor.computeLimitModules(entry); @@ -150,6 +151,23 @@ private void computeClasspathLocations( this.moduleUpdater.computeModuleUpdates(entry); switch(entry.getEntryKind()) { + case IClasspathEntry.CPE_JRT_SYSTEM : + //TODO: Some of the code in case CPE_LIBRARY is handled here. Revisit when confirmed + // a CPE_LIBRARY need not handle multi module entry. + ClasspathJrt jrtClasspath = + ClasspathLocation.forJrtSystem(entry.getPath().toOSString(), entry.getAccessRuleSet(), externalAnnotationPath); + AccessRuleSet accessRuleSet = + (JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true)) + && JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true))) + ? null + : entry.getAccessRuleSet(); + bLocations.add(jrtClasspath); + if (moduleEntries != null) { + Set<String> libraryLimitModules = (limitModules == null && projectModule != null) ? ClasspathJrt.NO_LIMIT_MODULES : limitModules; + patchedModule = collectModuleEntries(jrtClasspath, path, isOnModulePath, + libraryLimitModules, patchedModuleName, patchedModule, moduleEntries); + } + break; case IClasspathEntry.CPE_SOURCE : if (!(target instanceof IContainer)) continue nextEntry; IPath outputPath = entry.getOutputLocation() != null @@ -262,14 +280,14 @@ private void computeClasspathLocations( IResource resource = (IResource) target; ClasspathLocation bLocation = null; if (resource instanceof IFile) { - AccessRuleSet accessRuleSet = + accessRuleSet = (JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true)) && JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true))) ? null : entry.getAccessRuleSet(); bLocation = ClasspathLocation.forLibrary((IFile) resource, accessRuleSet, externalAnnotationPath, isOnModulePath); } else if (resource instanceof IContainer) { - AccessRuleSet accessRuleSet = + accessRuleSet = (JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true)) && JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true))) ? null @@ -296,7 +314,7 @@ private void computeClasspathLocations( binaryLocationsPerProject.put(p, existingLocations); } } else if (target instanceof File) { - AccessRuleSet accessRuleSet = + accessRuleSet = (JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true)) && JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true))) ? null @@ -304,9 +322,8 @@ private void computeClasspathLocations( ClasspathLocation bLocation = ClasspathLocation.forLibrary(path.toOSString(), accessRuleSet, externalAnnotationPath, isOnModulePath); bLocations.add(bLocation); if (moduleEntries != null) { - Set<String> libraryLimitModules = (limitModules == null && projectModule != null) ? ClasspathJrt.NO_LIMIT_MODULES : limitModules; patchedModule = collectModuleEntries(bLocation, path, isOnModulePath, - libraryLimitModules, patchedModuleName, patchedModule, moduleEntries); + limitModules, patchedModuleName, patchedModule, moduleEntries); } } continue nextEntry; diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java index ae3c904eaf..849a0532df 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java @@ -21,7 +21,6 @@ import org.eclipse.jdt.internal.compiler.env.IUpdatableModule; import org.eclipse.jdt.internal.compiler.env.IUpdatableModule.*; import org.eclipse.jdt.internal.compiler.env.AccessRule; import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; -import org.eclipse.jdt.internal.compiler.util.Util; import org.eclipse.jdt.internal.core.ClasspathAccessRule; import org.eclipse.jdt.internal.core.JavaModelManager; @@ -60,6 +59,7 @@ static final byte SOURCE_FOLDER = 1; static final byte BINARY_FOLDER = 2; static final byte EXTERNAL_JAR = 3; static final byte INTERNAL_JAR = 4; +static final byte JRT_SYSTEM = 5; State() { // constructor with no argument @@ -283,11 +283,16 @@ static State read(IProject project, DataInputStream in) throws IOException { case EXTERNAL_JAR : String jarPath = in.readUTF(); newState.binaryLocations[i] = ClasspathLocation.forLibrary(jarPath, in.readLong(), - readRestriction(in), new Path(in.readUTF()), Util.isJrt(jarPath) ? false : in.readBoolean()); + readRestriction(in), new Path(in.readUTF()), in.readBoolean()); break; case INTERNAL_JAR : newState.binaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())), readRestriction(in), new Path(in.readUTF()), in.readBoolean()); + break; + case JRT_SYSTEM : + jarPath = in.readUTF(); + newState.binaryLocations[i] = ClasspathLocation.forJrtSystem(jarPath, readRestriction(in), new Path(in.readUTF())); + break; } ClasspathLocation loc = newState.binaryLocations[i]; char[] patchName = readName(in); @@ -355,11 +360,16 @@ static State read(IProject project, DataInputStream in) throws IOException { case EXTERNAL_JAR : String jarPath = in.readUTF(); newState.testBinaryLocations[i] = ClasspathLocation.forLibrary(jarPath, in.readLong(), - readRestriction(in), new Path(in.readUTF()), Util.isJrt(jarPath) ? false : in.readBoolean()); + readRestriction(in), new Path(in.readUTF()), in.readBoolean()); break; case INTERNAL_JAR : newState.testBinaryLocations[i] = ClasspathLocation.forLibrary(root.getFile(new Path(in.readUTF())), readRestriction(in), new Path(in.readUTF()), in.readBoolean()); + break; + case JRT_SYSTEM : + jarPath = in.readUTF(); + newState.binaryLocations[i] = ClasspathLocation.forJrtSystem(jarPath, readRestriction(in), new Path(in.readUTF())); + break; } } @@ -556,10 +566,10 @@ void write(DataOutputStream out) throws IOException { out.writeBoolean(jar.isOnModulePath); } else { ClasspathJrt jrt = (ClasspathJrt) c; - out.writeByte(EXTERNAL_JAR); + out.writeByte(JRT_SYSTEM); out.writeUTF(jrt.zipFilename); out.writeLong(-1); - writeRestriction(null, out); + writeRestriction(jrt.accessRuleSet, out); out.writeUTF(""); //$NON-NLS-1$ } char[] patchName = c.patchModuleName == null ? CharOperation.NO_CHAR : c.patchModuleName.toCharArray(); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java index 352d19ad34..28f97a3e62 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java @@ -98,8 +98,7 @@ public class HandleFactory { } // create handle String module = null; - String rootPath = this.lastPkgFragmentRoot.getPath().toOSString(); - if (org.eclipse.jdt.internal.compiler.util.Util.isJrt(rootPath)) { + if (this.lastPkgFragmentRoot instanceof JrtPackageFragmentRoot) { module = resourcePath.substring(separatorIndex + 1, (separatorIndex = resourcePath.lastIndexOf(IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR))); } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java index 47e44edddc..178971a735 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java @@ -846,7 +846,8 @@ public class Util { } } if (path != null) { - if (JavaModelManager.isJrt(path)) { + if (JavaModelManager.isJrtInstallation(path.toOSString())) { + // TODO: This should be taken care of by the clients. return ClassFileConstants.JDK9; } else { jar = JavaModelManager.getJavaModelManager().getZipFile(path); diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java index 74269ef3ff..057c140b88 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * 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 @@ -141,6 +141,7 @@ void add(JavaProject javaProject, IPath pathToAdd, int includeMask, HashSet proj access = cpEntry.getAccessRuleSet(); switch (entry.getEntryKind()) { case IClasspathEntry.CPE_LIBRARY: + case IClasspathEntry.CPE_JRT_SYSTEM: IClasspathEntry rawEntry = null; Map rootPathToRawEntries = perProjectInfo.rootPathToRawEntries; if (rootPathToRawEntries != null) { diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java index aec5bec8d4..c772028987 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaWorkspaceScope.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2017 IBM Corporation and others. * 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 @@ -96,7 +96,7 @@ public IPath[] enclosingProjectsAndJars() { IClasspathEntry[] entries = javaProject.getResolvedClasspath(); for (int j = 0, eLength = entries.length; j < eLength; j++) { IClasspathEntry entry = entries[j]; - if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { + if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY || entry.getEntryKind() == IClasspathEntry.CPE_JRT_SYSTEM) { IPath path = entry.getPath(); Object target = JavaModel.getTarget(path, false/*don't check existence*/); if (target instanceof IFolder) // case of an external folder diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java index 41f93926f7..d22459abd6 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 IBM Corporation and others. + * Copyright (c) 2016, 2017 IBM Corporation and others. * 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 @@ -46,12 +46,6 @@ public class AddJrtToIndex extends BinaryContainer { DELETED } - public AddJrtToIndex(IFile resource, IndexLocation indexFile, IndexManager manager, final boolean updateIndex) { - super(resource.getFullPath(), manager); - this.resource = resource; - this.indexFileURL = indexFile; - this.forceIndexUpdate = updateIndex; - } public AddJrtToIndex(IPath jrtPath, IndexLocation indexFile, IndexManager manager, final boolean updateIndex) { // external JAR scenario - no resource super(jrtPath, manager); diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java index 91ac2cc5a6..889d526ecb 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2017 IBM Corporation and others. * 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 @@ -82,6 +82,8 @@ public class IndexAllProject extends IndexRequest { // ensure a job exists to index it as a binary folder this.manager.indexLibrary(projectPath, this.project, ((ClasspathEntry)entry).getLibraryIndexLocation()); return true; + } else if (entry.getEntryKind() == IClasspathEntry.CPE_JRT_SYSTEM) { + this.manager.indexJrtSystem(entry.getPath(), this.project, ((ClasspathEntry)entry).getLibraryIndexLocation()); } } diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java index f499b83941..ea0d892e45 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2017 IBM Corporation and others. * 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 @@ -42,7 +42,6 @@ import org.eclipse.jdt.internal.compiler.ISourceElementRequestor; import org.eclipse.jdt.internal.compiler.SourceElementParser; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; -import org.eclipse.jdt.internal.compiler.util.JRTUtil; import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; import org.eclipse.jdt.internal.compiler.util.SimpleSet; import org.eclipse.jdt.internal.core.ClasspathEntry; @@ -578,8 +577,11 @@ public void indexAll(IProject project) { IClasspathEntry[] entries = javaProject.getResolvedClasspath(); for (int i = 0; i < entries.length; i++) { IClasspathEntry entry= entries[i]; - if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) + if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { indexLibrary(entry.getPath(), project, ((ClasspathEntry)entry).getLibraryIndexLocation()); + } else if (entry.getEntryKind() == IClasspathEntry.CPE_JRT_SYSTEM) { + indexJrtSystem(entry.getPath(), project, ((ClasspathEntry)entry).getLibraryIndexLocation()); + } } } catch(JavaModelException e){ // cannot retrieve classpath info } @@ -589,18 +591,40 @@ public void indexAll(IProject project) { if (!isJobWaiting(request)) request(request); } +public void indexJrtSystem(IPath path, IProject requestingProject, URL indexURL) { + this.indexer.makeWorkspacePathDirty(path); + // requestingProject is no longer used to cancel jobs but leave it here just in case + IndexLocation indexFile = null; + boolean forceIndexUpdate = false; + if(indexURL != null) { + if(IS_MANAGING_PRODUCT_INDEXES_PROPERTY) { + indexFile = computeIndexLocation(path, indexURL); + } + else { + indexFile = IndexLocation.createIndexLocation(indexURL); + } + } + if (JavaCore.getPlugin() == null) return; + IndexRequest request = new AddJrtToIndex(path, indexFile, this, forceIndexUpdate); + + if (!isJobWaiting(request)) + request(request); +} public void indexLibrary(IPath path, IProject requestingProject, URL indexURL) { this.indexLibrary(path, requestingProject, indexURL, false); } private IndexRequest getRequest(Object target, IPath jPath, IndexLocation indexFile, IndexManager manager, boolean updateIndex) { - return isJrt(((File) target).getName()) ? new AddJrtToIndex(jPath, indexFile, this, updateIndex) : - new AddJarFileToIndex(jPath, indexFile, this, updateIndex); + if (target instanceof File) { + return new AddJarFileToIndex(jPath, indexFile, this, updateIndex); + } else if (target == null) { + if (JavaModelManager.isJrtInstallation(jPath.toOSString())) { + return new AddJrtToIndex(jPath, indexFile, this, updateIndex); + } + } + return null; } -private boolean isJrt(String fileName) { - return fileName != null && fileName.endsWith(JRTUtil.JRT_FS_JAR); -} /** * Trigger addition of a library to an index * Note: the actual operation is performed in background @@ -628,19 +652,15 @@ public void indexLibrary(IPath path, IProject requestingProject, URL indexURL, f IndexRequest request = null; Object target = JavaModel.getTarget(path, true); if (target instanceof IFile) { - request = isJrt(((IFile) target).getFullPath().toOSString()) ? - new AddJrtToIndex((IFile) target, indexFile, this, forceIndexUpdate) : - new AddJarFileToIndex((IFile) target, indexFile, this, forceIndexUpdate); - } else if (target instanceof File) { - request = getRequest(target, path, indexFile, this, forceIndexUpdate); + request = new AddJarFileToIndex((IFile) target, indexFile, this, forceIndexUpdate); } else if (target instanceof IContainer) { request = new IndexBinaryFolder((IContainer) target, this); } else { - return; + request = getRequest(target, path, indexFile, this, forceIndexUpdate); } // check if the same request is not already in the queue - if (!isJobWaiting(request)) + if (request != null && !isJobWaiting(request)) request(request); } @@ -727,7 +747,6 @@ private void rebuildIndex(IndexLocation indexLocation, IPath containerPath) { private void rebuildIndex(IndexLocation indexLocation, IPath containerPath, final boolean updateIndex) { this.indexer.makeWorkspacePathDirty(containerPath); Object target = JavaModel.getTarget(containerPath, true); - if (target == null) return; if (VERBOSE) Util.verbose("-> request to rebuild index: "+indexLocation+" path: "+containerPath); //$NON-NLS-1$ //$NON-NLS-2$ @@ -741,10 +760,8 @@ private void rebuildIndex(IndexLocation indexLocation, IPath containerPath, fina } else if (target instanceof IFolder) { request = new IndexBinaryFolder((IFolder) target, this); } else if (target instanceof IFile) { - request = isJrt(((IFile) target).getFullPath().toOSString()) ? - new AddJrtToIndex((IFile) target, null, this, updateIndex) : - new AddJarFileToIndex((IFile) target, null, this, updateIndex); - } else if (target instanceof File) { + request = new AddJarFileToIndex((IFile) target, null, this, updateIndex); + } else { request = getRequest(target, containerPath, null, this, updateIndex); } if (request != null) diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java index babf866a16..fc368cccc9 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java @@ -43,6 +43,7 @@ import org.eclipse.jdt.internal.core.JavaElementRequestor; import org.eclipse.jdt.internal.core.JavaModel; import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.core.JavaProject; +import org.eclipse.jdt.internal.core.JrtPackageFragmentRoot; import org.eclipse.jdt.internal.core.NameLookup; import org.eclipse.jdt.internal.core.PackageFragmentRoot; import org.eclipse.jdt.internal.core.builder.ClasspathJar; @@ -156,7 +157,7 @@ private ClasspathLocation mapToClassPathLocation(JavaModelManager manager, Packa try { if (root.isArchive()) { ClasspathEntry rawClasspathEntry = (ClasspathEntry) root.getRawClasspathEntry(); - cp = JavaModelManager.isJrt(path) ? + cp = (root instanceof JrtPackageFragmentRoot) ? new ClasspathJrt(path.toOSString(), rawClasspathEntry.getAccessRuleSet(), ClasspathEntry.getExternalAnnotationPath(rawClasspathEntry, ((IJavaProject)root.getParent()).getProject(), true)) : new ClasspathJar(manager.getZipFile(path), rawClasspathEntry.getAccessRuleSet(), diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java index 2eb1b04a85..111021e38b 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java @@ -74,6 +74,7 @@ import org.eclipse.jdt.internal.core.JarPackageFragmentRoot; import org.eclipse.jdt.internal.core.JavaElement; import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.core.JavaProject; +import org.eclipse.jdt.internal.core.JrtPackageFragmentRoot; import org.eclipse.jdt.internal.core.LambdaFactory; import org.eclipse.jdt.internal.core.LocalVariable; import org.eclipse.jdt.internal.core.ModularClassFile; @@ -260,7 +261,7 @@ public static IBinaryType classFileReader(IType type) { return Util.newClassFileReader(((JavaElement) type).resource()); String rootPath = root.getPath().toOSString(); - if (org.eclipse.jdt.internal.compiler.util.Util.isJrt(rootPath)) { + if (root instanceof JrtPackageFragmentRoot) { String classFileName = classFile.getElementName(); String path = Util.concatWith(pkg.names, classFileName, '/'); return ClassFileReader.readFromJrt(new File(rootPath), null, path); |