Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Arthanareeswaran2019-02-27 16:56:24 +0000
committerJay Arthanareeswaran2019-02-27 16:56:24 +0000
commit2d1a2262035ea1459de3b9e679b11a5b72bfeb91 (patch)
tree904879a31c777f0fbe7357dd3c349ec101db92ac
parent6940b0b9166a7ea6c9647fc7c86ed1cd6c67da51 (diff)
downloadeclipse.jdt.core-2d1a2262035ea1459de3b9e679b11a5b72bfeb91.tar.gz
eclipse.jdt.core-2d1a2262035ea1459de3b9e679b11a5b72bfeb91.tar.xz
eclipse.jdt.core-2d1a2262035ea1459de3b9e679b11a5b72bfeb91.zip
Revert "Revert "Bug 540922 - [12] ct.sym file has been restructured again for older releases""
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java7
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java2
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java13
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java453
-rw-r--r--org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java20
-rw-r--r--org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java303
-rw-r--r--org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java13
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java262
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java182
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java387
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathLocation.java8
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java2
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java28
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/JavaSearchNameEnvironment.java3
15 files changed, 1454 insertions, 233 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
index 65587be739..349e89cf8d 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
@@ -40,7 +40,7 @@ import junit.framework.Test;
public class ModuleCompilationTests extends AbstractBatchCompilerTest {
static {
-// TESTS_NAMES = new String[] { "testBug540067e" };
+// TESTS_NAMES = new String[] { "test001" };
// TESTS_NUMBERS = new int[] { 1 };
// TESTS_RANGE = new int[] { 298, -1 };
}
@@ -3975,11 +3975,11 @@ public void testBug521362_emptyFile() {
"}",
},
"\"" + OUTPUT_DIR + File.separator + "X.java\""
- + " --release 6 -d \"" + OUTPUT_DIR + "\"",
+ + " --release 7 -d \"" + OUTPUT_DIR + "\"",
"",
"",
true);
- String expectedOutput = "// Compiled from X.java (version 1.6 : 50.0, super bit)";
+ String expectedOutput = "// Compiled from X.java (version 1.7 : 51.0, super bit)";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput);
}
public void testReleaseOption4() throws Exception {
@@ -4094,6 +4094,7 @@ public void testBug521362_emptyFile() {
true);
}
public void testReleaseOption10() throws Exception {
+ if (isJRE12Plus) return;
this.runNegativeTest(
new String[] {
"X.java",
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
index 33aa81cb9a..fee9aacbe9 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
@@ -53,6 +53,7 @@ public class AbstractCompilerTest extends TestCase {
protected boolean enableAPT = false;
protected static boolean isJRE9Plus = false; // Stop gap, so tests need not be run at 9, but some tests can be adjusted for JRE 9
protected static boolean isJRE11Plus = false;
+ protected static boolean isJRE12Plus = false;
protected static boolean reflectNestedClassUseDollar;
/**
@@ -147,6 +148,7 @@ public class AbstractCompilerTest extends TestCase {
int lessthan9 = F_1_3 | F_1_4 | F_1_5 | F_1_6 | F_1_7 | F_1_8;
isJRE9Plus = !isJRELevel(lessthan9);
isJRE11Plus = isJRELevel(F_11);
+ isJRE12Plus = "12".equals(System.getProperty("java.specification.version"));
}
/**
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 df6e565b35..72600309b7 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
@@ -74,6 +74,9 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases {
protected String endChar = ",";
protected static boolean isJRE9 = false;
+ protected static boolean isJRE10 = false;
+ protected static boolean isJRE11 = false;
+ protected static boolean isJRE12 = false;
protected static String DEFAULT_MODULES = null;
static {
String javaVersion = System.getProperty("java.version");
@@ -87,6 +90,16 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases {
}
}
long jdkLevel = CompilerOptions.versionToJdkLevel(javaVersion.length() > 3 ? javaVersion.substring(0, 3) : javaVersion);
+ if (jdkLevel >= ClassFileConstants.JDK11) {
+ if (CompilerOptions.versionToJdkLevel(javaVersion.length() > 3 ? javaVersion.substring(0, 3) : javaVersion, false) == 0) {
+ // version was capped to 11 during versionToJdkLevel(version, true)
+ isJRE12 = true;
+ }
+ isJRE11 = true;
+ }
+ if (jdkLevel >= ClassFileConstants.JDK10) {
+ isJRE10 = true;
+ }
if (jdkLevel >= ClassFileConstants.JDK9) {
isJRE9 = true;
if (vmName.contains("HotSpot")) {
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 b80de70c73..ddc65ad408 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
@@ -696,8 +696,14 @@ public class ModuleBuilderTests extends ModifyingResourceTests {
public void testConvertToModule() throws CoreException, IOException {
Hashtable<String, String> javaCoreOptions = JavaCore.getOptions();
try {
- IJavaProject project = setUpJavaProject("ConvertToModule", "9");
- assertEquals(project.getOption("org.eclipse.jdt.core.compiler.compliance", true), "9");
+ IJavaProject project = setUpJavaProject("ConvertToModule");
+ Map<String, String> options = new HashMap<>();
+ // Make sure the new options map doesn't reset.
+ options.put(CompilerOptions.OPTION_Compliance, "9");
+ options.put(CompilerOptions.OPTION_Source, "9");
+ options.put(CompilerOptions.OPTION_TargetPlatform, "9");
+ options.put(CompilerOptions.OPTION_Release, "enabled");
+ project.setOptions(options);
project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
IPackageFragmentRoot theRoot = null;
@@ -709,7 +715,14 @@ public class ModuleBuilderTests extends ModifyingResourceTests {
}
assertNotNull("should not be null", theRoot);
String[] modules = JavaCore.getReferencedModules(project);
- assertStringsEqual("incorrect result", new String[]{"java.desktop", "java.rmi", "java.sql"}, modules);
+ if (isJRE12)
+ assertStringsEqual("incorrect result", new String[]{"java.desktop", "java.rmi", "java.sql"}, modules);
+ else if (isJRE11)
+ assertStringsEqual("incorrect result", new String[]{"java.datatransfer", "java.desktop", "java.net.http", "java.rmi", "java.sql"}, modules);
+ else if (isJRE10)
+ assertStringsEqual("incorrect result", new String[]{"java.datatransfer", "java.desktop", "java.rmi", "java.sql"}, modules);
+ else // 9
+ assertStringsEqual("incorrect result", new String[]{"java.desktop", "java.rmi", "java.sql"}, modules);
} finally {
this.deleteProject("ConvertToModule");
JavaCore.setOptions(javaCoreOptions);
@@ -8040,6 +8053,440 @@ public class ModuleBuilderTests extends ModifyingResourceTests {
}
}
+ public void testReleaseOption1() throws Exception {
+ Hashtable<String, String> options = JavaCore.getOptions();
+ IJavaProject p = createJava9Project("p");
+ p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+ String outputDirectory = Util.getOutputDirectory();
+ try {
+ String testSource = "public class X {\n" +
+ "}";
+ String mPath = "p/src/X.java";
+ createFile(mPath,
+ testSource);
+ p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
+ waitForAutoBuild();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("Unexpected markers",
+ "", markers);
+
+ } finally {
+ JavaCore.setOptions(options);
+ deleteProject(p);
+ File outputDir = new File(outputDirectory);
+ if (outputDir.exists())
+ Util.flushDirectoryContent(outputDir);
+ }
+ }
+ public void testReleaseOption2() throws Exception {
+ if (!isJRE12)
+ return;
+ Hashtable<String, String> options = JavaCore.getOptions();
+ IJavaProject p = createJava9Project("p");
+ p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6);
+ p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_6);
+ p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_6);
+ p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+ String outputDirectory = Util.getOutputDirectory();
+ try {
+ String testSource = "public class X {\n" +
+ " public java.util.stream.Stream<String> emptyStream() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}";
+ String mPath = "p/src/X.java";
+ createFile(mPath,
+ testSource);
+ p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
+ waitForAutoBuild();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("Unexpected markers",
+ "The project was not built due to \"release 6 is not found in the system\". "
+ + "Fix the problem, then try refreshing this project and building it since it may be inconsistent", markers);
+
+ } finally {
+ JavaCore.setOptions(options);
+ deleteProject(p);
+ File outputDir = new File(outputDirectory);
+ if (outputDir.exists())
+ Util.flushDirectoryContent(outputDir);
+ }
+ }
+ public void testReleaseOption3() throws Exception {
+ if (isJRE12)
+ return;
+ Hashtable<String, String> options = JavaCore.getOptions();
+ IJavaProject p = createJava9Project("p");
+ p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+ String outputDirectory = Util.getOutputDirectory();
+ try {
+ String testSource = "public class X {\n" +
+ " public java.util.stream.Stream<String> emptyStream() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}";
+ String mPath = "p/src/X.java";
+ createFile(mPath,
+ testSource);
+ p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
+ waitForAutoBuild();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("Unexpected markers",
+ "java.util.stream.Stream cannot be resolved to a type", markers);
+
+ } finally {
+ JavaCore.setOptions(options);
+ deleteProject(p);
+ File outputDir = new File(outputDirectory);
+ if (outputDir.exists())
+ Util.flushDirectoryContent(outputDir);
+ }
+ }
+ public void testReleaseOption4() throws Exception {
+ Hashtable<String, String> options = JavaCore.getOptions();
+ IJavaProject p = createJava9Project("p");
+ p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
+ p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
+ p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
+ p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+ String outputDirectory = Util.getOutputDirectory();
+ try {
+ String testSource = "public class X {\n" +
+ " public java.util.stream.Stream<String> emptyStream() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}";
+ String mPath = "p/src/X.java";
+ createFile(mPath,
+ testSource);
+ p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
+ waitForAutoBuild();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("Unexpected markers",
+ "", markers);
+
+ } finally {
+ JavaCore.setOptions(options);
+ deleteProject(p);
+ File outputDir = new File(outputDirectory);
+ if (outputDir.exists())
+ Util.flushDirectoryContent(outputDir);
+ }
+ }
+ public void testReleaseOption5() throws Exception {
+ Hashtable<String, String> options = JavaCore.getOptions();
+ IJavaProject p = createJava9Project("p");
+ p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+ String outputDirectory = Util.getOutputDirectory();
+ try {
+ String testSource = "public class X {\n" +
+ " public java.util.stream.Stream<String> emptyStream() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}";
+ String mPath = "p/src/X.java";
+ createFile(mPath,
+ testSource);
+ p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
+ waitForAutoBuild();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("Unexpected markers",
+ "java.util.stream.Stream cannot be resolved to a type", markers);
+
+ } finally {
+ JavaCore.setOptions(options);
+ deleteProject(p);
+ File outputDir = new File(outputDirectory);
+ if (outputDir.exists())
+ Util.flushDirectoryContent(outputDir);
+ }
+ }
+ public void testReleaseOption6() throws Exception {
+ Hashtable<String, String> options = JavaCore.getOptions();
+ IJavaProject p = createJava9Project("p");
+ p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+ String outputDirectory = Util.getOutputDirectory();
+ try {
+ String testSource = "interface I {\n" +
+ " int add(int x, int y);\n" +
+ "}\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " I i = (x, y) -> {\n" +
+ " return x + y;\n" +
+ " };\n" +
+ " }\n" +
+ "}\n";
+ String mPath = "p/src/X.java";
+ createFile(mPath,
+ testSource);
+ p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
+ waitForAutoBuild();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("Unexpected markers",
+ "Lambda expressions are allowed only at source level 1.8 or above", markers);
+
+ } finally {
+ JavaCore.setOptions(options);
+ deleteProject(p);
+ File outputDir = new File(outputDirectory);
+ if (outputDir.exists())
+ Util.flushDirectoryContent(outputDir);
+ }
+ }
+ public void testReleaseOption7() throws Exception {
+ if (isJRE12)
+ return;
+ Hashtable<String, String> options = JavaCore.getOptions();
+ IJavaProject p = createJava9Project("p");
+ p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6);
+ p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_6);
+ p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_6);
+ p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+ String outputDirectory = Util.getOutputDirectory();
+ try {
+ String testSource = "import java.io.*;\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " try {\n" +
+ " System.out.println();\n" +
+ " Reader r = new FileReader(args[0]);\n" +
+ " r.read();\n" +
+ " } catch(IOException | FileNotFoundException e) {\n" +
+ " e.printStackTrace();\n" +
+ " }\n" +
+ " }\n" +
+ "}";
+ String mPath = "p/src/X.java";
+ createFile(mPath,
+ testSource);
+ p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
+ waitForAutoBuild();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ sortMarkers(markers);
+ assertMarkers("Unexpected markers",
+ "Multi-catch parameters are not allowed for source level below 1.7\n" +
+ "The exception FileNotFoundException is already caught by the alternative IOException", markers);
+
+ } finally {
+ JavaCore.setOptions(options);
+ deleteProject(p);
+ File outputDir = new File(outputDirectory);
+ if (outputDir.exists())
+ Util.flushDirectoryContent(outputDir);
+ }
+ }
+ public void testReleaseOption8() throws Exception {
+ Hashtable<String, String> options = JavaCore.getOptions();
+ IJavaProject p = createJava9Project("p");
+ p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_9);
+ p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_9);
+ p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_9);
+ p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+ String outputDirectory = Util.getOutputDirectory();
+ try {
+ String testSource = "module mod.one { \n" +
+ " requires java.base;\n" +
+ "}";
+ String mPath = "p/src/module-info.java";
+ createFile(mPath,
+ testSource);
+ p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
+ waitForAutoBuild();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("Unexpected markers",
+ "", markers);
+
+ } finally {
+ JavaCore.setOptions(options);
+ deleteProject(p);
+ File outputDir = new File(outputDirectory);
+ if (outputDir.exists())
+ Util.flushDirectoryContent(outputDir);
+ }
+ }
+ public void testReleaseOption9() throws Exception {
+ if (!isJRE10) return;
+ Hashtable<String, String> options = JavaCore.getOptions();
+ IJavaProject p = createJava9Project("p");
+ p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_10);
+ p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_10);
+ p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_10);
+ p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+ String outputDirectory = Util.getOutputDirectory();
+ try {
+ String testSource = "module mod.one { \n" +
+ " requires java.base;\n" +
+ "}";
+ String mPath = "p/src/module-info.java";
+ createFile(mPath,
+ testSource);
+ p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
+ waitForAutoBuild();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("Unexpected markers",
+ "", markers);
+
+ } finally {
+ JavaCore.setOptions(options);
+ deleteProject(p);
+ File outputDir = new File(outputDirectory);
+ if (outputDir.exists())
+ Util.flushDirectoryContent(outputDir);
+ }
+ }
+ public void testReleaseOption10() throws Exception {
+ Hashtable<String, String> options = JavaCore.getOptions();
+ IJavaProject p = createJava9Project("p");
+ p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
+ p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
+ p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
+ p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+ String outputDirectory = Util.getOutputDirectory();
+ try {
+ String testSource = "module mod.one { \n" +
+ " requires java.base;\n" +
+ "}";
+ String mPath = "p/src/module-info.java";
+ createFile(mPath,
+ testSource);
+ p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
+ waitForAutoBuild();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ sortMarkers(markers);
+ String expected =
+ "Syntax error on token \"module\", package expected\n" +
+ "Syntax error on token(s), misplaced construct(s)\n" +
+ "Syntax error on token \".\", , expected\n" +
+ "Syntax error on token \"}\", delete this token";
+ assertMarkers("Unexpected markers",
+ expected, markers);
+
+ } finally {
+ JavaCore.setOptions(options);
+ deleteProject(p);
+ File outputDir = new File(outputDirectory);
+ if (outputDir.exists())
+ Util.flushDirectoryContent(outputDir);
+ }
+ }
+ public void testReleaseOption11() throws Exception {
+ Hashtable<String, String> options = JavaCore.getOptions();
+ IJavaProject p = createJava9Project("p");
+ p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
+ p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
+ p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
+ p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+ String outputDirectory = Util.getOutputDirectory();
+ try {
+ createFolder("p/src/foo");
+ createFile(
+ "p/src/foo/Module.java",
+ "package foo;\n" +
+ "public class Module {}\n");
+ createFile(
+ "p/src/foo/X.java",
+ "package foo;\n" +
+ "public class X { \n" +
+ " public Module getModule(String name) {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}");
+ p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
+ waitForAutoBuild();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("Unexpected markers",
+ "", markers);
+
+ } finally {
+ JavaCore.setOptions(options);
+ deleteProject(p);
+ File outputDir = new File(outputDirectory);
+ if (outputDir.exists())
+ Util.flushDirectoryContent(outputDir);
+ }
+ }
+ public void testReleaseOption12() throws Exception {
+ if (!isJRE12)
+ return;
+ Hashtable<String, String> options = JavaCore.getOptions();
+ IJavaProject p = createJava9Project("p");
+ p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_7);
+ p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+ String outputDirectory = Util.getOutputDirectory();
+ try {
+ String testSource = "import java.io.*;\n" +
+ "\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " String str = Integer.toUnsignedString(1, 1);\n" +
+ " }\n" +
+ "}";
+ String mPath = "p/src/X.java";
+ createFile(mPath,
+ testSource);
+ p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
+ waitForAutoBuild();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("Unexpected markers",
+ "The method toUnsignedString(int, int) is undefined for the type Integer", markers);
+
+ } finally {
+ JavaCore.setOptions(options);
+ deleteProject(p);
+ File outputDir = new File(outputDirectory);
+ if (outputDir.exists())
+ Util.flushDirectoryContent(outputDir);
+ }
+ }
+ public void testReleaseOption13() throws Exception {
+ if (!isJRE12)
+ return;
+ Hashtable<String, String> options = JavaCore.getOptions();
+ IJavaProject p = createJava9Project("p");
+ p.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
+ p.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
+ p.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
+ p.setOption(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+ String outputDirectory = Util.getOutputDirectory();
+ try {
+ String testSource = "\n" +
+ "public class X {\n" +
+ " public static void main(String[] args) {\n" +
+ " Integer.toUnsignedString(1, 1);\n" +
+ " }\n" +
+ "}";
+ String mPath = "p/src/X.java";
+ createFile(mPath,
+ testSource);
+ p.getProject().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
+ waitForAutoBuild();
+ IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+ assertMarkers("Unexpected markers",
+ "", markers);
+
+ } finally {
+ JavaCore.setOptions(options);
+ deleteProject(p);
+ File outputDir = new File(outputDirectory);
+ if (outputDir.exists())
+ Util.flushDirectoryContent(outputDir);
+ }
+ }
protected void assertNoErrors() throws CoreException {
for (IProject p : getWorkspace().getRoot().getProjects()) {
int maxSeverity = p.findMaxProblemSeverity(null, true, IResource.DEPTH_INFINITE);
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java
index 7a39271115..8aad54669b 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2018 IBM Corporation.
+ * Copyright (c) 2018, 2019 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
@@ -42,15 +42,15 @@ import org.eclipse.jdt.internal.compiler.util.Util;
public class ClasspathJep247 extends ClasspathJrt {
- private java.nio.file.FileSystem fs = null;
- private String compliance = null;
- private long jdklevel;
- private String releaseInHex = null;
- private String[] subReleases = null;
- private Path releasePath = null;
- private Set<String> packageCache;
- File jdkHome;
- String modulePath = null;
+ protected java.nio.file.FileSystem fs = null;
+ protected String compliance = null;
+ protected long jdklevel;
+ protected String releaseInHex = null;
+ protected String[] subReleases = null;
+ protected Path releasePath = null;
+ protected Set<String> packageCache;
+ protected File jdkHome;
+ protected String modulePath = null;
public ClasspathJep247(File jdkHome, String release, AccessRuleSet accessRuleSet) {
super(jdkHome, false, accessRuleSet, null);
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java
new file mode 100644
index 0000000000..52a83987cf
--- /dev/null
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java
@@ -0,0 +1,303 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.batch;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystemNotFoundException;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.IModule;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class ClasspathJep247Jdk12 extends ClasspathJep247 {
+
+ Map<String, IModule> modules;
+
+ public ClasspathJep247Jdk12(File jdkHome, String release, AccessRuleSet accessRuleSet) {
+ super(jdkHome, release, accessRuleSet);
+ }
+ @Override
+ public List<Classpath> fetchLinkedJars(FileSystem.ClasspathSectionProblemReporter problemReporter) {
+ return null;
+ }
+ @Override
+ public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String moduleName, String qualifiedBinaryFileName) {
+ return findClass(typeName, qualifiedPackageName, moduleName, qualifiedBinaryFileName, false);
+ }
+ @Override
+ public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String moduleName, String qualifiedBinaryFileName, boolean asBinaryOnly) {
+ if (!isPackage(qualifiedPackageName, moduleName))
+ return null; // most common case
+
+ try {
+ ClassFileReader reader = null;
+ byte[] content = null;
+ qualifiedBinaryFileName = qualifiedBinaryFileName.replace(".class", ".sig"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (this.subReleases != null && this.subReleases.length > 0) {
+ done: for (String rel : this.subReleases) {
+ if (moduleName == null) {
+ Path p = this.fs.getPath(rel);
+ try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(p)) {
+ for (final java.nio.file.Path subdir: stream) {
+ Path f = this.fs.getPath(rel, subdir.getFileName().toString(), qualifiedBinaryFileName);
+ if (Files.exists(f)) {
+ content = JRTUtil.safeReadBytes(f);
+ if (content != null)
+ break done;
+ }
+ }
+ }
+ } else {
+ Path p = this.fs.getPath(rel, moduleName, qualifiedBinaryFileName);
+ if (Files.exists(p)) {
+ content = JRTUtil.safeReadBytes(p);
+ if (content != null)
+ break;
+ }
+ }
+ }
+ } else {
+ content = JRTUtil.safeReadBytes(this.fs.getPath(this.releaseInHex, qualifiedBinaryFileName));
+ }
+ if (content != null) {
+ reader = new ClassFileReader(content, qualifiedBinaryFileName.toCharArray());
+ return new NameEnvironmentAnswer(reader, fetchAccessRestriction(qualifiedBinaryFileName), null);
+ }
+ } catch(ClassFormatException e) {
+ // Continue
+ } catch (IOException e) {
+ // continue
+ }
+ return null;
+ }
+
+ @Override
+ public void initialize() throws IOException {
+ if (this.compliance == null) {
+ return;
+ }
+ if (this.fs != null) {
+ super.initialize();
+ return;
+ }
+ this.releaseInHex = Integer.toHexString(Integer.parseInt(this.compliance)).toUpperCase();
+ Path filePath = this.jdkHome.toPath().resolve("lib").resolve("ct.sym"); //$NON-NLS-1$ //$NON-NLS-2$
+ URI t = filePath.toUri();
+ if (!Files.exists(filePath)) {
+ return;
+ }
+ URI uri = URI.create("jar:file:" + t.getRawPath()); //$NON-NLS-1$
+ try {
+ this.fs = FileSystems.getFileSystem(uri);
+ } catch(FileSystemNotFoundException fne) {
+ // Ignore and move on
+ }
+ if (this.fs == null) {
+ HashMap<String, ?> env = new HashMap<>();
+ this.fs = FileSystems.newFileSystem(uri, env);
+ }
+ this.releasePath = this.fs.getPath("/"); //$NON-NLS-1$
+ if (!Files.exists(this.fs.getPath(this.releaseInHex))) {
+ throw new IllegalArgumentException("release " + this.compliance + " is not found in the system"); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ List<String> sub = new ArrayList<>();
+ try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) {
+ for (final java.nio.file.Path subdir: stream) {
+ String rel = subdir.getFileName().toString();
+ if (rel.contains(this.releaseInHex))
+ sub.add(rel);
+ }
+ this.subReleases = sub.toArray(new String[sub.size()]);
+ } catch (IOException e) {
+ //e.printStackTrace();
+ }
+ super.initialize();
+ }
+ @Override
+ public void loadModules() {
+ // Modules below level 8 are not dealt with here. Leave it to ClasspathJrt
+ if (this.jdklevel <= ClassFileConstants.JDK1_8) {
+ super.loadModules();
+ return;
+ }
+ final Path modPath = this.fs.getPath(this.releaseInHex);
+ this.modulePath = this.file.getPath() + "|" + modPath.toString(); //$NON-NLS-1$
+ this.modules = ModulesCache.get(this.modulePath);
+ if (this.modules == null) {
+ try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) {
+ for (final java.nio.file.Path subdir: stream) {
+ String rel = subdir.getFileName().toString();
+ if (!rel.contains(this.releaseInHex)) {
+ continue;
+ }
+ Files.walkFileTree(subdir, Collections.EMPTY_SET, 2, new FileVisitor<java.nio.file.Path>() {
+
+ @Override
+ public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs)
+ throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(java.nio.file.Path f, BasicFileAttributes attrs) throws IOException {
+ if (attrs.isDirectory() || f.getNameCount() < 3)
+ return FileVisitResult.CONTINUE;
+ byte[] content = null;
+ if (Files.exists(f)) {
+ content = JRTUtil.safeReadBytes(f);
+ if (content == null)
+ return FileVisitResult.CONTINUE;
+ Path m = f.subpath(1, f.getNameCount() - 1);
+ ClasspathJep247Jdk12.this.acceptModule(m.getFileName().toString(), content);
+ ClasspathJep247Jdk12.this.moduleNamesCache.add(m.getFileName().toString());
+ }
+ return FileVisitResult.SKIP_SIBLINGS;
+ }
+
+ @Override
+ public FileVisitResult visitFileFailed(java.nio.file.Path f, IOException exc) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(java.nio.file.Path dir, IOException exc) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else {
+ this.moduleNamesCache.addAll(this.modules.keySet());
+ }
+ }
+ @Override
+ public Collection<String> getModuleNames(Collection<String> limitModule, Function<String, IModule> getModule) {
+ return selectModules(this.moduleNamesCache, limitModule, getModule);
+ }
+ @Override
+ public IModule getModule(char[] moduleName) {
+ if (this.modules != null) {
+ return this.modules.get(String.valueOf(moduleName));
+ }
+ return null;
+ }
+ void acceptModule(String name, byte[] content) {
+ if (content == null)
+ return;
+
+ if (this.modules != null) {
+ if (this.modules.containsKey(name))
+ return;
+ }
+
+ ClassFileReader reader = null;
+ try {
+ reader = new ClassFileReader(content, IModule.MODULE_INFO_CLASS.toCharArray());
+ } catch (ClassFormatException e) {
+ e.printStackTrace();
+ }
+ if (reader != null) {
+ acceptModule(reader);
+ }
+ }
+ @Override
+ void acceptModule(ClassFileReader reader) {
+ // Modules below level 8 are not dealt with here. Leave it to ClasspathJrt
+ if (this.jdklevel <= ClassFileConstants.JDK1_8) {
+ super.acceptModule(reader);
+ return;
+ }
+ if (reader != null) {
+ IModule moduleDecl = reader.getModuleDeclaration();
+ if (moduleDecl != null) {
+ if (this.modules == null) {
+ ModulesCache.put(this.modulePath, this.modules = new HashMap<String,IModule>());
+ }
+ this.modules.put(String.valueOf(moduleDecl.name()), moduleDecl);
+ }
+ }
+ }
+ @Override
+ public synchronized char[][] getModulesDeclaringPackage(String qualifiedPackageName, String moduleName) {
+ // Ignore moduleName as this has nothing to do with modules (as of now)
+ if (this.packageCache != null)
+ return singletonModuleNameIf(this.packageCache.contains(qualifiedPackageName));
+
+ this.packageCache = new HashSet<>(41);
+ this.packageCache.add(Util.EMPTY_STRING);
+ try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) {
+ for (final java.nio.file.Path subdir: stream) {
+ String rel = subdir.getFileName().toString();
+ if (!rel.contains(this.releaseInHex)) {
+ continue;
+ }
+ try (DirectoryStream<java.nio.file.Path> stream2 = Files.newDirectoryStream(subdir)) {
+ for (final java.nio.file.Path subdir2: stream2) {
+ Files.walkFileTree(subdir2, new FileVisitor<java.nio.file.Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs) throws IOException {
+ if (dir.getNameCount() <= 2)
+ return FileVisitResult.CONTINUE;
+ Path relative = dir.subpath(2, dir.getNameCount());
+ addToPackageCache(relative.toString(), false);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(java.nio.file.Path f, BasicFileAttributes attrs) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFileFailed(java.nio.file.Path f, IOException exc) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(java.nio.file.Path dir, IOException exc) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ // Rethrow
+ }
+ return singletonModuleNameIf(this.packageCache.contains(qualifiedPackageName));
+ }
+}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
index 1a81699b44..060351e20a 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -164,11 +164,14 @@ public class FileSystem implements IModuleAwareNameEnvironment, SuffixConstants
Set<String> knownFileNames;
protected boolean annotationsFromClasspath; // should annotation files be read from the classpath (vs. explicit separate path)?
private static HashMap<File, Classpath> JRT_CLASSPATH_CACHE = null;
-
protected Map<String,Classpath> moduleLocations = new HashMap<>();
/** Tasks resulting from --add-reads or --add-exports command line options. */
Map<String,UpdatesByKind> moduleUpdates = new HashMap<>();
+ static final boolean isJRE12Plus;
+ static {
+ isJRE12Plus = "12".equals(System.getProperty("java.specification.version")); //$NON-NLS-1$ //$NON-NLS-2$
+ }
/*
classPathNames is a collection is Strings representing the full path of each class path
@@ -205,6 +208,8 @@ protected FileSystem(Classpath[] paths, String[] initialFileNames, boolean annot
final Classpath classpath = paths[i];
try {
classpath.initialize();
+ for (String moduleName : classpath.getModuleNames(limitedModules))
+ this.moduleLocations.put(moduleName, classpath);
this.classpaths[counter++] = classpath;
} catch(IOException | InvalidPathException exception) {
// JRE 9 could throw an IAE if the linked JAR paths have invalid chars, such as ":"
@@ -256,7 +261,9 @@ public static Classpath getJrtClasspath(String jdkHome, String encoding, AccessR
return new ClasspathJrt(new File(convertPathSeparators(jdkHome)), true, accessRuleSet, null);
}
public static Classpath getOlderSystemRelease(String jdkHome, String release, AccessRuleSet accessRuleSet) {
- return new ClasspathJep247(new File(convertPathSeparators(jdkHome)), release, accessRuleSet);
+ return isJRE12Plus ?
+ new ClasspathJep247Jdk12(new File(convertPathSeparators(jdkHome)), release, accessRuleSet) :
+ new ClasspathJep247(new File(convertPathSeparators(jdkHome)), release, accessRuleSet);
}
public static Classpath getClasspath(String classpathName, String encoding,
boolean isSourceOnly, AccessRuleSet accessRuleSet,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java
index bb3bfb757c..b11078dfe5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/NameEnvironmentAnswer.java
@@ -32,9 +32,7 @@ public class NameEnvironmentAnswer {
String externalAnnotationPath; // should be an absolute file system path
public NameEnvironmentAnswer(IBinaryType binaryType, AccessRestriction accessRestriction) {
- this.binaryType = binaryType;
- this.accessRestriction = accessRestriction;
- this.moduleName = binaryType.getModule();
+ this(binaryType, accessRestriction, binaryType.getModule());
}
public NameEnvironmentAnswer(IBinaryType binaryType, AccessRestriction accessRestriction, char[] module) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
index 481bbef429..f6903f814f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
@@ -22,6 +22,7 @@ import java.net.URLClassLoader;
import java.nio.channels.ClosedByInterruptException;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystem;
+import java.nio.file.FileSystemNotFoundException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
@@ -59,7 +60,7 @@ public class JRTUtil {
public static int NOTIFY_ALL = NOTIFY_FILES | NOTIFY_PACKAGES | NOTIFY_MODULES;
// TODO: Java 9 Think about clearing the cache too.
- private static Map<File, JrtFileSystem> images = null;
+ private static Map<String, JrtFileSystem> images = null;
private static final Object lock = new Object();
@@ -100,7 +101,11 @@ public class JRTUtil {
}
public static JrtFileSystem getJrtSystem(File image) {
- Map<File, JrtFileSystem> i = images;
+ return getJrtSystem(image, null);
+ }
+
+ public static JrtFileSystem getJrtSystem(File image, String release) {
+ Map<String, JrtFileSystem> i = images;
if (images == null) {
synchronized (lock) {
i = images;
@@ -110,10 +115,12 @@ public class JRTUtil {
}
}
JrtFileSystem system = null;
+ String key = image.toString();
+ if (release != null) key = key + "|" + release; //$NON-NLS-1$
synchronized(i) {
- if ((system = images.get(image)) == null) {
+ if ((system = images.get(key)) == null) {
try {
- images.put(image, system = new JrtFileSystem(image));
+ images.put(key, system = JrtFileSystem.getNewJrtFileSystem(image, release));
} catch (IOException e) {
e.printStackTrace();
// Needs better error handling downstream? But for now, make sure
@@ -138,8 +145,8 @@ public class JRTUtil {
* /modules/$MODULE/$PATH
* /packages/$PACKAGE/$MODULE
* The latter provides quick look up of the module that contains a particular package. However,
- * this method only notifies its clients of the entries within the modules sub-directory. The
- * clients can decide which notifications they want to receive. See {@link JRTUtil#NOTIFY_ALL},
+ * this method only notifies its clients of the entries within the modules (latter) sub-directory.
+ * Clients can decide which notifications they want to receive. See {@link JRTUtil#NOTIFY_ALL},
* {@link JRTUtil#NOTIFY_FILES}, {@link JRTUtil#NOTIFY_PACKAGES} and {@link JRTUtil#NOTIFY_MODULES}.
*
* @param image a java.io.File handle to the JRT image.
@@ -148,7 +155,10 @@ public class JRTUtil {
* @throws IOException
*/
public static void walkModuleImage(File image, final JRTUtil.JrtFileVisitor<java.nio.file.Path> visitor, int notify) throws IOException {
- getJrtSystem(image).walkModuleImage(visitor, false, notify);
+ getJrtSystem(image, null).walkModuleImage(visitor, notify);
+ }
+ public static void walkModuleImage(File image, String release, final JRTUtil.JrtFileVisitor<java.nio.file.Path> visitor, int notify) throws IOException {
+ getJrtSystem(image, release).walkModuleImage(visitor, notify);
}
public static InputStream getContentFromJrt(File jrt, String fileName, String module) throws IOException {
@@ -187,13 +197,138 @@ public class JRTUtil {
}
}
}
+class JrtFileSystemWithOlderRelease extends JrtFileSystem {
+ final String release;
+ String releaseInHex = null;
+ //private Path releasePath = null;
+ private String[] subReleases = null;
+ protected Path modulePath = null;
+
+ /**
+ * The jrt file system is based on the location of the JRE home whose libraries
+ * need to be loaded.
+ *
+ * @param jrt the path to the root of the JRE whose libraries we are interested in.
+ * @param release the older release where classes and modules should be searched for.
+ * @throws IOException
+ */
+ JrtFileSystemWithOlderRelease(File jrt, String release) throws IOException {
+ super(jrt);
+ this.release = release;
+ initialize(jrt, release);
+ }
+ @Override
+ void initialize(File jdk) throws IOException {
+ // Just to make sure we don't do anything in super.initialize()
+ // before setting this.release
+ }
+ void initialize(File jdk, String rel) throws IOException {
+ super.initialize(jdk);
+ this.fs = null;// reset and proceed, TODO: this is crude and need to be removed.
+ this.releaseInHex = Integer.toHexString(Integer.parseInt(this.release)).toUpperCase();
+ Path ct = Paths.get(this.jdkHome, "lib", "ct.sym"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (!Files.exists(ct)) {
+ return;
+ }
+ URI uri = URI.create("jar:file:" + ct.toUri().getRawPath()); //$NON-NLS-1$
+ try {
+ this.fs = FileSystems.getFileSystem(uri);
+ } catch(FileSystemNotFoundException fne) {
+ // Ignore and move on
+ }
+ if (this.fs == null) {
+ HashMap<String, ?> env = new HashMap<>();
+ try {
+ this.fs = FileSystems.newFileSystem(uri, env);
+ } catch (IOException e) {
+ return;
+ }
+ }
+ Path releasePath = this.fs.getPath("/"); //$NON-NLS-1$
+ if (!Files.exists(this.fs.getPath(this.releaseInHex))
+ || Files.exists(this.fs.getPath(this.releaseInHex, "system-modules"))) { //$NON-NLS-1$
+ this.fs = null;
+ }
+ if (this.release != null) {
+ List<String> sub = new ArrayList<>();
+ try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(releasePath)) {
+ for (final java.nio.file.Path subdir: stream) {
+ String r = subdir.getFileName().toString();
+ if (r.contains(this.releaseInHex)) {
+ sub.add(r);
+ } else {
+ continue;
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ // Rethrow?
+ }
+ this.subReleases = sub.toArray(new String[sub.size()]);
+ }
+ // Ensure walkJrtForModules() is not called
+ }
+ @Override
+ void walkModuleImage(final JRTUtil.JrtFileVisitor<java.nio.file.Path> visitor, final int notify) throws IOException {
+ if (this.subReleases != null && this.subReleases.length > 0) {
+ for (String rel : this.subReleases) {
+ Path p = this.fs.getPath(rel);
+ Files.walkFileTree(p, new JRTUtil.AbstractFileVisitor<java.nio.file.Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs)
+ throws IOException {
+ int count = dir.getNameCount();
+ if (count == 1) {
+ return FileVisitResult.CONTINUE;
+ }
+ if (count == 2) {
+ // e.g. /9A/java.base
+ java.nio.file.Path mod = dir.getName(1);
+ if ((JRTUtil.MODULE_TO_LOAD != null && JRTUtil.MODULE_TO_LOAD.length() > 0
+ && JRTUtil.MODULE_TO_LOAD.indexOf(mod.toString()) == -1)) {
+ return FileVisitResult.SKIP_SUBTREE;
+ }
+ return ((notify & JRTUtil.NOTIFY_MODULES) == 0) ? FileVisitResult.CONTINUE
+ : visitor.visitModule(dir);
+ }
+ if ((notify & JRTUtil.NOTIFY_PACKAGES) == 0) {
+ // client is not interested in packages
+ return FileVisitResult.CONTINUE;
+ }
+ return visitor.visitPackage(dir.subpath(2, count), dir.getName(1), attrs);
+ }
+
+ @Override
+ public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs)
+ throws IOException {
+ if ((notify & JRTUtil.NOTIFY_FILES) == 0) {
+ return FileVisitResult.CONTINUE;
+ }
+ // This happens when a file in a default package is present. E.g. /modules/some.module/file.name
+ if (file.getNameCount() == 3) {
+ cachePackage(JRTUtil.DEFAULT_PACKAGE, file.getName(1).toString());
+ }
+ return visitor.visitFile(file.subpath(2, file.getNameCount()), file.getName(1), attrs);
+ }
+ });
+ }
+ }
+ }
+
+}
class JrtFileSystem {
private final Map<String, String> packageToModule = new HashMap<String, String>();
private final Map<String, List<String>> packageToModules = new HashMap<String, List<String>>();
- FileSystem jrtSystem = null;
-
+ FileSystem fs = null;
+ Path modRoot = null;
+ String jdkHome = null;
+ public static JrtFileSystem getNewJrtFileSystem(File jrt, String release) throws IOException {
+ return (release == null) ? new JrtFileSystem(jrt) :
+ new JrtFileSystemWithOlderRelease(jrt, release);
+
+ }
/**
* The jrt file system is based on the location of the JRE home whose libraries
* need to be loaded.
@@ -201,18 +336,18 @@ class JrtFileSystem {
* @param jrt the path to the root of the JRE whose libraries we are interested in.
* @throws IOException
*/
- public JrtFileSystem(File jrt) throws IOException {
+ JrtFileSystem(File jrt) throws IOException {
initialize(jrt);
}
void initialize(File jrt) throws IOException {
URL jrtPath = null;
- String jdkHome = null;
+ this.jdkHome = null;
if (jrt.toString().endsWith(JRTUtil.JRT_FS_JAR)) {
jrtPath = jrt.toPath().toUri().toURL();
- jdkHome = jrt.getParentFile().getParent();
+ this.jdkHome = jrt.getParentFile().getParent();
} else {
- jdkHome = jrt.toPath().toString();
- jrtPath = Paths.get(jdkHome, "lib", JRTUtil.JRT_FS_JAR).toUri().toURL(); //$NON-NLS-1$
+ this.jdkHome = jrt.toPath().toString();
+ jrtPath = Paths.get(this.jdkHome, "lib", JRTUtil.JRT_FS_JAR).toUri().toURL(); //$NON-NLS-1$
}
JRTUtil.MODULE_TO_LOAD = System.getProperty("modules.to.load"); //$NON-NLS-1$
@@ -220,13 +355,15 @@ class JrtFileSystem {
if (javaVersion != null && javaVersion.startsWith("1.8")) { //$NON-NLS-1$
URLClassLoader loader = new URLClassLoader(new URL[] { jrtPath });
HashMap<String, ?> env = new HashMap<>();
- this.jrtSystem = FileSystems.newFileSystem(JRTUtil.JRT_URI, env, loader);
+ this.fs = FileSystems.newFileSystem(JRTUtil.JRT_URI, env, loader);
} else {
HashMap<String, String> env = new HashMap<>();
- env.put("java.home", jdkHome); //$NON-NLS-1$
- this.jrtSystem = FileSystems.newFileSystem(JRTUtil.JRT_URI, env);
+ env.put("java.home", this.jdkHome); //$NON-NLS-1$
+ this.fs = FileSystems.newFileSystem(JRTUtil.JRT_URI, env);
}
- walkModuleImage(null, true, 0 /* doesn't matter */);
+ this.modRoot = this.fs.getPath(JRTUtil.MODULES_SUBDIR);
+ // Set up the root directory wherere modules are located
+ walkJrtForModules();
}
public List<String> getModulesDeclaringPackage(String qualifiedPackageName, String moduleName) {
@@ -279,7 +416,7 @@ class JrtFileSystem {
String knownModule = this.packageToModule.get(qualifiedPackageName);
if (knownModule == null || (knownModule != JRTUtil.MULTIPLE && !knownModule.equals(module)))
return false;
- Path packagePath = this.jrtSystem.getPath(JRTUtil.MODULES_SUBDIR, module, qualifiedPackageName);
+ Path packagePath = this.fs.getPath(JRTUtil.MODULES_SUBDIR, module, qualifiedPackageName);
if (!Files.exists(packagePath))
return false;
// iterate files:
@@ -294,11 +431,11 @@ class JrtFileSystem {
public InputStream getContentFromJrt(String fileName, String module) throws IOException {
if (module != null) {
- return Files.newInputStream(this.jrtSystem.getPath(JRTUtil.MODULES_SUBDIR, module, fileName));
+ return Files.newInputStream(this.fs.getPath(JRTUtil.MODULES_SUBDIR, module, fileName));
}
String[] modules = getModules(fileName);
for (String mod : modules) {
- return Files.newInputStream(this.jrtSystem.getPath(JRTUtil.MODULES_SUBDIR, mod, fileName));
+ return Files.newInputStream(this.fs.getPath(JRTUtil.MODULES_SUBDIR, mod, fileName));
}
return null;
}
@@ -309,7 +446,7 @@ class JrtFileSystem {
for (String mod : modules) {
if (moduleNameFilter != null && !moduleNameFilter.test(mod))
continue;
- content = JRTUtil.safeReadBytes(this.jrtSystem.getPath(JRTUtil.MODULES_SUBDIR, mod, fileName));
+ content = JRTUtil.safeReadBytes(this.fs.getPath(JRTUtil.MODULES_SUBDIR, mod, fileName));
if (content != null) {
module = mod;
break;
@@ -330,7 +467,7 @@ class JrtFileSystem {
} else {
String[] modules = getModules(fileName);
for (String mod : modules) {
- content = JRTUtil.safeReadBytes(this.jrtSystem.getPath(JRTUtil.MODULES_SUBDIR, mod, fileName));
+ content = JRTUtil.safeReadBytes(this.fs.getPath(JRTUtil.MODULES_SUBDIR, mod, fileName));
if (content != null) {
break;
}
@@ -339,7 +476,7 @@ class JrtFileSystem {
return content;
}
private byte[] getClassfileBytes(String fileName, String module) throws IOException, ClassFormatException {
- return JRTUtil.safeReadBytes(this.jrtSystem.getPath(JRTUtil.MODULES_SUBDIR, module, fileName));
+ return JRTUtil.safeReadBytes(this.fs.getPath(JRTUtil.MODULES_SUBDIR, module, fileName));
}
public ClassFileReader getClassfile(String fileName, String module, Predicate<String> moduleNameFilter) throws IOException, ClassFormatException {
ClassFileReader reader = null;
@@ -367,47 +504,12 @@ class JrtFileSystem {
return reader;
}
- void walkModuleImage(final JRTUtil.JrtFileVisitor<java.nio.file.Path> visitor, boolean visitPackageMapping, final int notify) throws IOException {
- Iterable<java.nio.file.Path> roots = this.jrtSystem.getRootDirectories();
+ void walkJrtForModules() throws IOException {
+ Iterable<java.nio.file.Path> roots = this.fs.getRootDirectories();
for (java.nio.file.Path path : roots) {
try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(path)) {
for (final java.nio.file.Path subdir: stream) {
- if (subdir.toString().equals(JRTUtil.MODULES_SUBDIR)) {
- if (visitPackageMapping) continue;
- Files.walkFileTree(subdir, new JRTUtil.AbstractFileVisitor<java.nio.file.Path>() {
- @Override
- public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs) throws IOException {
- int count = dir.getNameCount();
- if (count == 2) {
- // e.g. /modules/java.base
- java.nio.file.Path mod = dir.getName(1);
- if ((JRTUtil.MODULE_TO_LOAD != null && JRTUtil.MODULE_TO_LOAD.length() > 0 &&
- JRTUtil.MODULE_TO_LOAD.indexOf(mod.toString()) == -1)) {
- return FileVisitResult.SKIP_SUBTREE;
- }
- return ((notify & JRTUtil.NOTIFY_MODULES) == 0) ?
- FileVisitResult.CONTINUE : visitor.visitModule(mod);
- }
- if (dir == subdir || count < 3 || (notify & JRTUtil.NOTIFY_PACKAGES) == 0) {
- // We are dealing with a module or not client is not interested in packages
- return FileVisitResult.CONTINUE;
- }
- return visitor.visitPackage(dir.subpath(2, count), dir.getName(1), attrs);
- }
-
- @Override
- public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs) throws IOException {
- if ((notify & JRTUtil.NOTIFY_FILES) == 0)
- return FileVisitResult.CONTINUE;
- int count = file.getNameCount();
- // This happens when a file in a default package is present. E.g. /modules/some.module/file.name
- if (count == 3) {
- cachePackage(JRTUtil.DEFAULT_PACKAGE, file.getName(1).toString());
- }
- return visitor.visitFile(file.subpath(2, file.getNameCount()), file.getName(1), attrs);
- }
- });
- } else if (visitPackageMapping) {
+ if (!subdir.toString().equals(JRTUtil.MODULES_SUBDIR)) {
Files.walkFileTree(subdir, new JRTUtil.AbstractFileVisitor<java.nio.file.Path>() {
@Override
public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs) throws IOException {
@@ -424,6 +526,42 @@ class JrtFileSystem {
}
}
}
+ void walkModuleImage(final JRTUtil.JrtFileVisitor<java.nio.file.Path> visitor, final int notify) throws IOException {
+ Files.walkFileTree(this.modRoot, new JRTUtil.AbstractFileVisitor<java.nio.file.Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs) throws IOException {
+ int count = dir.getNameCount();
+ if (count == 1) return FileVisitResult.CONTINUE;
+ if (count == 2) {
+ // e.g. /modules/java.base
+ java.nio.file.Path mod = dir.getName(1);
+ if ((JRTUtil.MODULE_TO_LOAD != null && JRTUtil.MODULE_TO_LOAD.length() > 0 &&
+ JRTUtil.MODULE_TO_LOAD.indexOf(mod.toString()) == -1)) {
+ return FileVisitResult.SKIP_SUBTREE;
+ }
+ return ((notify & JRTUtil.NOTIFY_MODULES) == 0) ?
+ FileVisitResult.CONTINUE : visitor.visitModule(mod);
+ }
+ if ((notify & JRTUtil.NOTIFY_PACKAGES) == 0) {
+ // We are dealing with a module or not client is not interested in packages
+ return FileVisitResult.CONTINUE;
+ }
+ return visitor.visitPackage(dir.subpath(2, count), dir.getName(1), attrs);
+ }
+
+ @Override
+ public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs) throws IOException {
+ if ((notify & JRTUtil.NOTIFY_FILES) == 0)
+ return FileVisitResult.CONTINUE;
+ int count = file.getNameCount();
+ // This happens when a file in a default package is present. E.g. /modules/some.module/file.name
+ if (count == 3) {
+ cachePackage(JRTUtil.DEFAULT_PACKAGE, file.getName(1).toString());
+ }
+ return visitor.visitFile(file.subpath(2, file.getNameCount()), file.getName(1), attrs);
+ }
+ });
+ }
void cachePackage(String packageName, String module) {
packageName = packageName.intern();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java
index 34ab941c95..50cfd275f1 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016, 2018 IBM Corporation and others.
+ * Copyright (c) 2016, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -15,16 +15,9 @@ package org.eclipse.jdt.internal.core.builder;
import java.io.File;
import java.io.IOException;
-import java.net.URI;
-import java.nio.file.DirectoryStream;
-import java.nio.file.FileSystemNotFoundException;
-import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -35,7 +28,6 @@ import java.util.function.Predicate;
import java.util.zip.ZipFile;
import org.eclipse.core.runtime.IPath;
-import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
@@ -50,36 +42,29 @@ import org.eclipse.jdt.internal.compiler.util.JRTUtil;
import org.eclipse.jdt.internal.compiler.util.SimpleSet;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
import org.eclipse.jdt.internal.core.JavaProject;
-import org.eclipse.jdt.internal.core.util.Util;
public class ClasspathJrt extends ClasspathLocation implements IMultiModuleEntry {
//private HashMap<String, SimpleSet> packagesInModule = null;
-private static HashMap<String, HashMap<String, SimpleSet>> PackageCache = new HashMap<>();
-private static HashMap<String, Set<IModule>> ModulesCache = new HashMap<>();
+protected static HashMap<String, HashMap<String, SimpleSet>> PackageCache = new HashMap<>();
+protected static HashMap<String, Set<IModule>> ModulesCache = new HashMap<>();
String externalAnnotationPath;
-private ZipFile annotationZipFile;
+protected ZipFile annotationZipFile;
String zipFilename; // keep for equals
AccessRuleSet accessRuleSet;
-String release = null;
-String releaseInHex = null;
-private Path releasePath = null;
-private String[] subReleases = null;
-private java.nio.file.FileSystem fs = null;
static final Set<String> NO_LIMIT_MODULES = new HashSet<>();
-public ClasspathJrt(String zipFilename, AccessRuleSet accessRuleSet, IPath externalAnnotationPath, String release) {
+/*
+ * Only for use from ClasspathJrtWithOlderRelease
+ */
+protected ClasspathJrt() {
+}
+public ClasspathJrt(String zipFilename, AccessRuleSet accessRuleSet, IPath externalAnnotationPath) {
this.zipFilename = zipFilename;
this.accessRuleSet = accessRuleSet;
if (externalAnnotationPath != null)
this.externalAnnotationPath = externalAnnotationPath.toString();
- if (release != null && release.length() == 0) {
- this.release = null;
- } else {
- this.release = release;
- }
- initialize();
loadModules(this);
}
/**
@@ -89,7 +74,7 @@ public ClasspathJrt(String zipFilename, AccessRuleSet accessRuleSet, IPath exter
*/
static HashMap<String, SimpleSet> findPackagesInModules(final ClasspathJrt jrt) {
String zipFileName = jrt.zipFilename;
- HashMap<String, SimpleSet> cache = PackageCache.get(zipFileName);
+ HashMap<String, SimpleSet> cache = PackageCache.get(jrt.getKey());
if (cache != null) {
return cache;
}
@@ -97,7 +82,7 @@ static HashMap<String, SimpleSet> findPackagesInModules(final ClasspathJrt jrt)
PackageCache.put(zipFileName, packagesInModule);
try {
final File imageFile = new File(zipFileName);
- org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(imageFile,
+ org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(imageFile,
new org.eclipse.jdt.internal.compiler.util.JRTUtil.JrtFileVisitor<Path>() {
SimpleSet packageSet = null;
@Override
@@ -132,12 +117,11 @@ static HashMap<String, SimpleSet> findPackagesInModules(final ClasspathJrt jrt)
}
public static void loadModules(final ClasspathJrt jrt) {
- String zipFileName = jrt.zipFilename;
- Set<IModule> cache = ModulesCache.get(zipFileName);
+ Set<IModule> cache = ModulesCache.get(jrt.getKey());
if (cache == null) {
try {
- final File imageFile = new File(zipFileName);
+ final File imageFile = new File(jrt.zipFilename);
org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(imageFile,
new org.eclipse.jdt.internal.compiler.util.JRTUtil.JrtFileVisitor<Path>() {
SimpleSet packageSet = null;
@@ -174,70 +158,11 @@ public static void loadModules(final ClasspathJrt jrt) {
// }
}
}
-public void initialize() {
- if (this.release == null) {
- return;
- }
- this.release = getReleaseOptionFromCompliance(this.release);
- this.releaseInHex = Integer.toHexString(Integer.parseInt(this.release)).toUpperCase();
- Path lib = Paths.get(this.zipFilename).getParent();
- Path filePath = Paths.get(lib.toString(), "ct.sym"); //$NON-NLS-1$
- URI t = filePath.toUri();
- if (!Files.exists(filePath)) {
- return;
- }
- URI uri = URI.create("jar:file:" + t.getRawPath()); //$NON-NLS-1$
- try {
- this.fs = FileSystems.getFileSystem(uri);
- } catch(FileSystemNotFoundException fne) {
- // Ignore and move on
- }
- if (this.fs == null) {
- HashMap<String, ?> env = new HashMap<>();
- try {
- this.fs = FileSystems.newFileSystem(uri, env);
- } catch (IOException e) {
- this.release = null;
- return;
- }
- }
- this.releasePath = this.fs.getPath("/"); //$NON-NLS-1$
- if (!Files.exists(this.fs.getPath(this.releaseInHex))
- || Files.exists(this.fs.getPath(this.releaseInHex, "system-modules"))) { //$NON-NLS-1$
- this.release = null;
- }
- if (this.release != null) {
- List<String> sub = new ArrayList<>();
- try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) {
- for (final java.nio.file.Path subdir: stream) {
- String rel = subdir.getFileName().toString();
- if (rel.contains(this.releaseInHex)) {
- sub.add(rel);
- } else {
- continue;
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- // Rethrow
- }
- this.subReleases = sub.toArray(new String[sub.size()]);
- }
-}
-private String getReleaseOptionFromCompliance(String comp) {
- if (JavaCore.compareJavaVersions(comp, JavaCore.VERSION_1_5) <= 0) {
- // For a JDK 9 and above, the minimum release we support is "6"
- return "6"; //$NON-NLS-1$
- }
- int index = comp.indexOf("1."); //$NON-NLS-1$
- if (index != -1) {
- return comp.substring(index + 2, comp.length());
- } else {
- return comp;
- }
+protected String getKey() {
+ return this.zipFilename;
}
void acceptModule(byte[] content) {
- if (content == null)
+ if (content == null)
return;
ClassFileReader reader = null;
try {
@@ -246,11 +171,12 @@ void acceptModule(byte[] content) {
e.printStackTrace();
}
if (reader != null) {
+ String key = getKey();
IModule moduleDecl = reader.getModuleDeclaration();
if (moduleDecl != null) {
- Set<IModule> cache = ModulesCache.get(this.zipFilename);
+ Set<IModule> cache = ModulesCache.get(key);
if (cache == null) {
- ModulesCache.put(this.zipFilename, cache = new HashSet<IModule>());
+ ModulesCache.put(key, cache = new HashSet<IModule>());
}
cache.add(moduleDecl);
}
@@ -265,7 +191,6 @@ public void cleanup() {
}
this.annotationZipFile = null;
}
- this.fs = null;
}
@Override
@@ -273,9 +198,6 @@ public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ClasspathJrt)) return false;
ClasspathJrt jar = (ClasspathJrt) o;
- if (!Util.equalOrNull(this.release, jar.release)) {
- return false;
- }
if (this.accessRuleSet != jar.accessRuleSet)
if (this.accessRuleSet == null || !this.accessRuleSet.equals(jar.accessRuleSet))
return false;
@@ -288,43 +210,31 @@ public NameEnvironmentAnswer findClass(String binaryFileName, String qualifiedPa
if (!isPackage(qualifiedPackageName, moduleName)) return null; // most common case
try {
- IBinaryType reader = null;
- byte[] content = null;
String fileNameWithoutExtension = qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - SuffixConstants.SUFFIX_CLASS.length);
- if (this.subReleases != null && this.subReleases.length > 0) {
- qualifiedBinaryFileName = qualifiedBinaryFileName.replace(".class", ".sig"); //$NON-NLS-1$ //$NON-NLS-2$
- for (String rel : this.subReleases) {
- Path p = this.fs.getPath(rel, qualifiedBinaryFileName);
- if (Files.exists(p)) {
- content = JRTUtil.safeReadBytes(p);
- if (content != null) {
- reader = new ClassFileReader(content, qualifiedBinaryFileName.toCharArray());
- break;
- }
- }
- }
- } else {
- reader = ClassFileReader.readFromModule(new File(this.zipFilename), moduleName, qualifiedBinaryFileName, moduleNameFilter);
- }
- if (reader != null) {
- if (this.externalAnnotationPath != null) {
- try {
- if (this.annotationZipFile == null) {
- this.annotationZipFile = ExternalAnnotationDecorator.getAnnotationZipFile(this.externalAnnotationPath, null);
- }
- reader = ExternalAnnotationDecorator.create(reader, this.externalAnnotationPath, fileNameWithoutExtension, this.annotationZipFile);
- } catch (IOException e) {
- // don't let error on annotations fail class reading
+ IBinaryType reader = ClassFileReader.readFromModule(new File(this.zipFilename), moduleName, qualifiedBinaryFileName, moduleNameFilter);
+ return createAnswer(fileNameWithoutExtension, reader);
+ } catch (ClassFormatException e) { // treat as if class file is missing
+ } catch (IOException e) { // treat as if class file is missing
+ }
+ return null;
+}
+protected NameEnvironmentAnswer createAnswer(String fileNameWithoutExtension, IBinaryType reader) {
+ if (reader != null) {
+ if (this.externalAnnotationPath != null) {
+ try {
+ if (this.annotationZipFile == null) {
+ this.annotationZipFile = ExternalAnnotationDecorator.getAnnotationZipFile(this.externalAnnotationPath, null);
}
+ reader = ExternalAnnotationDecorator.create(reader, this.externalAnnotationPath, fileNameWithoutExtension, this.annotationZipFile);
+ } catch (IOException e) {
+ // don't let error on annotations fail class reading
}
- if (this.accessRuleSet == null)
- return new NameEnvironmentAnswer(reader, null, reader.getModule());
- return new NameEnvironmentAnswer(reader,
- this.accessRuleSet.getViolatedRestriction(fileNameWithoutExtension.toCharArray()),
- reader.getModule());
}
- } catch (ClassFormatException e) { // treat as if class file is missing
- } catch (IOException e) { // treat as if class file is missing
+ if (this.accessRuleSet == null)
+ return new NameEnvironmentAnswer(reader, null, reader.getModule());
+ return new NameEnvironmentAnswer(reader,
+ this.accessRuleSet.getViolatedRestriction(fileNameWithoutExtension.toCharArray()),
+ reader.getModule());
}
return null;
}
@@ -341,7 +251,7 @@ public int hashCode() {
@Override
public char[][] getModulesDeclaringPackage(String qualifiedPackageName, String moduleName) {
List<String> moduleNames = JRTUtil.getModulesDeclaringPackage(new File(this.zipFilename), qualifiedPackageName, moduleName);
- return CharOperation.toCharArrays(moduleNames);
+ return CharOperation.toCharArrays(moduleNames);
}
@Override
public boolean hasCompilationUnit(String qualifiedPackageName, String moduleName) {
@@ -374,7 +284,7 @@ public boolean hasModule() {
}
@Override
public IModule getModule(char[] moduleName) {
- Set<IModule> modules = ModulesCache.get(this.zipFilename);
+ Set<IModule> modules = ModulesCache.get(getKey());
if (modules != null) {
for (IModule mod : modules) {
if (CharOperation.equals(mod.name(), moduleName))
@@ -391,7 +301,7 @@ public Collection<String> getModuleNames(Collection<String> limitModules) {
return Collections.emptyList();
}
-private Collection<String> selectModules(Set<String> keySet, Collection<String> limitModules) {
+protected Collection<String> selectModules(Set<String> keySet, Collection<String> limitModules) {
Collection<String> rootModules;
if (limitModules == NO_LIMIT_MODULES) {
rootModules = new HashSet<>(keySet);
@@ -408,7 +318,7 @@ private Collection<String> selectModules(Set<String> keySet, Collection<String>
return allModules;
}
-private void addRequired(String mod, Set<String> allModules) {
+protected void addRequired(String mod, Set<String> allModules) {
IModule iMod = getModule(mod.toCharArray());
for (IModuleReference requiredRef : iMod.requires()) {
IModule reqMod = getModule(requiredRef.name());
@@ -421,7 +331,7 @@ private void addRequired(String mod, Set<String> allModules) {
}
@Override
public NameEnvironmentAnswer findClass(String typeName, String qualifiedPackageName, String moduleName, String qualifiedBinaryFileName) {
- //
+ //
return findClass(typeName, qualifiedPackageName, moduleName, qualifiedBinaryFileName, false, null);
}
/** TEST ONLY */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java
new file mode 100644
index 0000000000..a5d8446c37
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java
@@ -0,0 +1,387 @@
+/*******************************************************************************
+ * Copyright (c) 2016, 2019 IBM Corporation and others.
+ *
+ * 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.builder;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystemNotFoundException;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Predicate;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+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.AccessRuleSet;
+import org.eclipse.jdt.internal.compiler.env.IBinaryType;
+import org.eclipse.jdt.internal.compiler.env.IModule;
+import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
+import org.eclipse.jdt.internal.compiler.util.SimpleSet;
+import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
+import org.eclipse.jdt.internal.core.util.Util;
+
+public class ClasspathJrtWithReleaseOption extends ClasspathJrt {
+
+ final String release;
+ String releaseInHex;
+ private String[] subReleases;
+ private java.nio.file.FileSystem fs;
+ protected Path modulePath;
+ private String modPathString;
+ private boolean isJRE12Plus;
+
+ public ClasspathJrtWithReleaseOption(String zipFilename, AccessRuleSet accessRuleSet, IPath externalAnnotationPath,
+ String release) throws CoreException {
+ super();
+ if (release == null || release.equals("")) { //$NON-NLS-1$
+ throw new IllegalArgumentException("--release argument can not be null"); //$NON-NLS-1$
+ }
+ this.zipFilename = zipFilename;
+ this.accessRuleSet = accessRuleSet;
+ if (externalAnnotationPath != null)
+ this.externalAnnotationPath = externalAnnotationPath.toString();
+ this.release = getReleaseOptionFromCompliance(release);
+ initialize();
+ loadModules(this);
+ }
+ /*
+ * JDK 11 doesn't contain release 5. Hence
+ * if the compliance is below 6, we simply return the lowest supported
+ * release, which is 6.
+ */
+ private String getReleaseOptionFromCompliance(String comp) {
+ if (JavaCore.compareJavaVersions(comp, JavaCore.VERSION_1_5) <= 0) {
+ return "6"; //$NON-NLS-1$
+ }
+ int index = comp.indexOf("1."); //$NON-NLS-1$
+ if (index != -1) {
+ return comp.substring(index + 2, comp.length());
+ } else {
+ return comp;
+ }
+ }
+ private boolean isJRE12Plus(Path path) {
+ try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(path)) {
+ for (final java.nio.file.Path subdir : stream) {
+ String rel = subdir.getFileName().toString();
+ if (Files.exists(this.fs.getPath(rel, "system-modules"))) { //$NON-NLS-1$
+ int parseInt = Integer.parseInt(rel, 16);
+ return (parseInt > 11);
+ }
+ }
+ } catch (IOException e) {
+ this.fs = null;
+ }
+ return false;
+ }
+ /*
+ * Set up the paths where modules and regular classes need to be read. We need to deal with two different kind of
+ * formats of cy.sym: Post JDK 12: ct.sym -> 9 -> java/ -> lang/* 9-modules -> java.base -> module-info.sig
+ *
+ * From JDK 12 onward: ct.sym -> 9 -> java.base -> module-info.sig java/ -> lang/* Notably, 1) in JDK 12 modules
+ * classes and ordinary classes are located in the same location 2) in JDK 12, ordinary classes are found inside
+ * their respective modules
+ *
+ */
+ protected void initialize() throws CoreException {
+ this.releaseInHex = Integer.toHexString(Integer.parseInt(this.release)).toUpperCase();
+ Path lib = Paths.get(this.zipFilename).getParent();
+ Path filePath = Paths.get(lib.toString(), "ct.sym"); //$NON-NLS-1$
+ URI t = filePath.toUri();
+ if (!Files.exists(filePath)) {
+ return;
+ }
+ URI uri = URI.create("jar:file:" + t.getRawPath()); //$NON-NLS-1$
+ try {
+ this.fs = FileSystems.getFileSystem(uri);
+ } catch (FileSystemNotFoundException fne) {
+ // Ignore and move on
+ }
+ if (this.fs == null) {
+ HashMap<String, ?> env = new HashMap<>();
+ try {
+ this.fs = FileSystems.newFileSystem(uri, env);
+ } catch (IOException e) {
+ return;
+ }
+ }
+ Path releasePath = this.fs.getPath("/"); //$NON-NLS-1$
+ this.isJRE12Plus = isJRE12Plus(releasePath);
+ Path modPath = this.fs.getPath(this.releaseInHex + (this.isJRE12Plus ? "" : "-modules")); //$NON-NLS-1$ //$NON-NLS-2$
+ if (Files.exists(modPath)) {
+ this.modulePath = modPath;
+ this.modPathString = this.zipFilename + "|"+ modPath.toString(); //$NON-NLS-1$
+ }
+
+ if (!Files.exists(releasePath.resolve(this.releaseInHex))) {
+ Exception e = new IllegalArgumentException("release " + this.release + " is not found in the system"); //$NON-NLS-1$//$NON-NLS-2$
+ throw new CoreException(new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, e.getMessage(), e));
+ }
+ if (Files.exists(this.fs.getPath(this.releaseInHex, "system-modules"))) { //$NON-NLS-1$
+ this.fs = null; // Fallback to default version
+ return;
+ }
+ if (this.release != null) {
+ List<String> sub = new ArrayList<>();
+ try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(releasePath)) {
+ for (final java.nio.file.Path subdir : stream) {
+ String rel = subdir.getFileName().toString();
+ if (rel.contains(this.releaseInHex)) {
+ sub.add(rel);
+ } else {
+ continue;
+ }
+ }
+ } catch (IOException e) {
+ this.fs = null; // Fallback to default version
+ }
+ this.subReleases = sub.toArray(new String[sub.size()]);
+ }
+ }
+
+ static HashMap<String, SimpleSet> findPackagesInModules(final ClasspathJrtWithReleaseOption jrt) {
+ // In JDK 11 and before, classes are not listed under their respective modules
+ // Hence, we simply go to the default module system for package-module mapping
+ if (jrt.fs == null || !jrt.isJRE12Plus) {
+ return ClasspathJrt.findPackagesInModules(jrt);
+ }
+ String zipFileName = jrt.zipFilename;
+ HashMap<String, SimpleSet> cache = PackageCache.get(jrt.modPathString);
+ if (cache != null) {
+ return cache;
+ }
+ final HashMap<String, SimpleSet> packagesInModule = new HashMap<>();
+ PackageCache.put(jrt.modPathString, packagesInModule);
+ try {
+ final File imageFile = new File(zipFileName);
+ org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(imageFile, jrt.release,
+ new org.eclipse.jdt.internal.compiler.util.JRTUtil.JrtFileVisitor<Path>() {
+ SimpleSet packageSet = null;
+
+ @Override
+ public FileVisitResult visitPackage(Path dir, Path mod, BasicFileAttributes attrs)
+ throws IOException {
+ ClasspathJar.addToPackageSet(this.packageSet, dir.toString(), true);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, Path mod, BasicFileAttributes attrs)
+ throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitModule(Path mod) throws IOException {
+ String name = mod.getName(1).toString();
+ this.packageSet = new SimpleSet(41);
+ this.packageSet.add(""); //$NON-NLS-1$
+ packagesInModule.put(name, this.packageSet);
+ return FileVisitResult.CONTINUE;
+ }
+ }, JRTUtil.NOTIFY_PACKAGES | JRTUtil.NOTIFY_MODULES);
+ } catch (IOException e) {
+ // return empty handed
+ }
+ return packagesInModule;
+ }
+
+ public static void loadModules(final ClasspathJrtWithReleaseOption jrt) {
+ if (jrt.fs == null || !jrt.isJRE12Plus) {
+ ClasspathJrt.loadModules(jrt);
+ return;
+ }
+ if (jrt.modPathString == null)
+ return;
+ Set<IModule> cache = ModulesCache.get(jrt.modPathString);
+ if (cache == null) {
+ try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(jrt.modulePath)) {
+ for (final java.nio.file.Path subdir : stream) {
+
+ Files.walkFileTree(subdir, Collections.EMPTY_SET, 1, new FileVisitor<java.nio.file.Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs)
+ throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(java.nio.file.Path f, BasicFileAttributes attrs)
+ throws IOException {
+ byte[] content = null;
+ if (Files.exists(f)) {
+ content = JRTUtil.safeReadBytes(f);
+ if (content == null)
+ return FileVisitResult.CONTINUE;
+ jrt.acceptModule(content);
+ }
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFileFailed(java.nio.file.Path f, IOException exc)
+ throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(java.nio.file.Path dir, IOException exc)
+ throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+ } catch (IOException e) {
+ // Nothing much to do
+ }
+ }
+ }
+
+
+ @Override
+ public NameEnvironmentAnswer findClass(String binaryFileName, String qualifiedPackageName, String moduleName,
+ String qualifiedBinaryFileName, boolean asBinaryOnly, Predicate<String> moduleNameFilter) {
+
+ if (this.fs == null) {
+ return super.findClass(binaryFileName, qualifiedPackageName, moduleName, qualifiedBinaryFileName,
+ asBinaryOnly, moduleNameFilter);
+ }
+ if (!isPackage(qualifiedPackageName, moduleName))
+ return null; // most common case
+
+ try {
+ IBinaryType reader = null;
+ byte[] content = null;
+ String fileNameWithoutExtension = qualifiedBinaryFileName.substring(0,
+ qualifiedBinaryFileName.length() - SuffixConstants.SUFFIX_CLASS.length);
+ if (this.subReleases != null && this.subReleases.length > 0) {
+ qualifiedBinaryFileName = qualifiedBinaryFileName.replace(".class", ".sig"); //$NON-NLS-1$ //$NON-NLS-2$
+ outer: for (String rel : this.subReleases) {
+ Path p = null;
+ inner: if (this.isJRE12Plus) {
+ if (moduleName != null) {
+ p = this.fs.getPath(rel, moduleName, qualifiedBinaryFileName);
+ }
+ else {
+ try (DirectoryStream<java.nio.file.Path> stream = Files
+ .newDirectoryStream(this.fs.getPath(rel))) {
+ for (final java.nio.file.Path subdir : stream) {
+ p = subdir.resolve(qualifiedBinaryFileName);
+ if (Files.exists(p)) {
+ if (subdir.getNameCount() == 2 ) {
+ moduleName = subdir.getName(1).toString();
+ }
+ break inner;
+ }
+ }
+ }
+ }
+ } else {
+ p = this.fs.getPath(rel, qualifiedBinaryFileName);
+ }
+ if (Files.exists(p)) {
+ content = JRTUtil.safeReadBytes(p);
+ if (content != null) {
+ reader = new ClassFileReader(content, qualifiedBinaryFileName.toCharArray());
+ if (moduleName != null)
+ ((ClassFileReader) reader).moduleName = moduleName.toCharArray();
+ break outer;
+ }
+ }
+ }
+ } else {
+ reader = ClassFileReader.readFromModule(new File(this.zipFilename), moduleName, qualifiedBinaryFileName,
+ moduleNameFilter);
+ }
+ return createAnswer(fileNameWithoutExtension, reader);
+ } catch (ClassFormatException e) {
+ // treat as if class file is missing
+ } catch (IOException e) {
+ // treat as if class file is missing
+ }
+ return null;
+ }
+
+ @Override
+ public Collection<String> getModuleNames(Collection<String> limitModules) {
+ HashMap<String, SimpleSet> cache = findPackagesInModules(this);
+ if (cache != null)
+ return selectModules(cache.keySet(), limitModules);
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void cleanup() {
+ try {
+ super.reset();
+ } finally {
+ // The same file system is also used in JRTUtil, so don't close it here.
+ this.fs = null;
+ }
+ }
+
+ @Override
+ public boolean hasModule() {
+ return this.modPathString != null;
+ }
+
+ @Override
+ protected String getKey() {
+ return this.modPathString;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (!(o instanceof ClasspathJrtWithReleaseOption))
+ return false;
+ ClasspathJrtWithReleaseOption jar = (ClasspathJrtWithReleaseOption) o;
+ if (!Util.equalOrNull(this.release, jar.release)) {
+ return false;
+ }
+ return super.equals(o);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = this.zipFilename == null ? super.hashCode() : this.zipFilename.hashCode();
+ return Util.combineHashCodes(hash, this.release.hashCode());
+ }
+
+ @Override
+ public String toString() {
+ String start = "Classpath jrt file " + this.zipFilename + " with --release option " + this.release; //$NON-NLS-1$ //$NON-NLS-2$
+ return start;
+ }
+
+}
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 d501e436cf..52cd7e0c31 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -23,6 +23,7 @@ import java.util.zip.ZipFile;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
@@ -141,8 +142,9 @@ static ClasspathLocation forLibrary(String libraryPathname,
new ClasspathMultiReleaseJar(libraryPathname, lastModified, accessRuleSet, annotationsPath, autoModule, compliance));
}
-static ClasspathJrt forJrtSystem(String jrtPath, AccessRuleSet accessRuleSet, IPath annotationsPath, String release) {
- return new ClasspathJrt(jrtPath, accessRuleSet, annotationsPath, release);
+public static ClasspathJrt forJrtSystem(String jrtPath, AccessRuleSet accessRuleSet, IPath annotationsPath, String release) throws CoreException {
+ return (release == null || release.equals("")) ? new ClasspathJrt(jrtPath, accessRuleSet, annotationsPath) : //$NON-NLS-1$
+ new ClasspathJrtWithReleaseOption(jrtPath, accessRuleSet, annotationsPath, release);
}
public static ClasspathLocation forLibrary(String libraryPathname, AccessRuleSet accessRuleSet, IPath annotationsPath,
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
index 269e064480..abf0ebc7a7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java
@@ -152,7 +152,7 @@ public static void removeProblemsAndTasksFor(IResource resource) {
}
}
-public static State readState(IProject project, DataInputStream in) throws IOException {
+public static State readState(IProject project, DataInputStream in) throws IOException, CoreException {
return State.read(project, in);
}
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 dd240bcacb..a57cc107e6 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -56,7 +56,7 @@ private long previousStructuralBuildTime;
private StringSet structurallyChangedTypes;
public static int MaxStructurallyChangedTypes = 100; // keep track of ? structurally changed types, otherwise consider all to be changed
-public static final byte VERSION = 0x0021;
+public static final byte VERSION = 0x0022;
static final byte SOURCE_FOLDER = 1;
static final byte BINARY_FOLDER = 2;
@@ -233,7 +233,7 @@ void removeQualifiedTypeName(String qualifiedTypeNameToRemove) {
this.typeLocators.removeKey(qualifiedTypeNameToRemove);
}
-static State read(IProject project, DataInputStream in) throws IOException {
+static State read(IProject project, DataInputStream in) throws IOException, CoreException {
if (JavaBuilder.DEBUG)
System.out.println("About to read state " + project.getName()); //$NON-NLS-1$
if (VERSION != in.readByte()) {
@@ -568,13 +568,20 @@ void write(DataOutputStream out) throws IOException {
out.writeBoolean(jar.isOnModulePath);
out.writeUTF(jar.compliance == null ? "" : jar.compliance); //$NON-NLS-1$
- } else {
+ } else if (c instanceof ClasspathJrt) {
ClasspathJrt jrt = (ClasspathJrt) c;
out.writeByte(EXTERNAL_JAR);
out.writeUTF(jrt.zipFilename);
writeRestriction(jrt.accessRuleSet, out);
out.writeUTF(jrt.externalAnnotationPath != null ? jrt.externalAnnotationPath : ""); //$NON-NLS-1$
- out.writeUTF(jrt.release != null ? jrt.release : ""); //$NON-NLS-1$
+ out.writeUTF(""); //$NON-NLS-1$
+ } else {
+ ClasspathJrtWithReleaseOption jrt = (ClasspathJrtWithReleaseOption) c;
+ out.writeByte(EXTERNAL_JAR);
+ out.writeUTF(jrt.zipFilename);
+ writeRestriction(jrt.accessRuleSet, out);
+ out.writeUTF(jrt.externalAnnotationPath != null ? jrt.externalAnnotationPath : ""); //$NON-NLS-1$
+ out.writeUTF(jrt.release);
}
char[] patchName = c.patchModuleName == null ? CharOperation.NO_CHAR : c.patchModuleName.toCharArray();
writeName(patchName, out);
@@ -680,13 +687,20 @@ void write(DataOutputStream out) throws IOException {
out.writeUTF(jar.externalAnnotationPath != null ? jar.externalAnnotationPath : ""); //$NON-NLS-1$
out.writeBoolean(jar.isOnModulePath);
out.writeUTF(jar.compliance != null ? jar.compliance : ""); //$NON-NLS-1$
- } else {
+ } else if (c instanceof ClasspathJrt) {
ClasspathJrt jrt = (ClasspathJrt) c;
out.writeByte(EXTERNAL_JAR);
out.writeUTF(jrt.zipFilename);
writeRestriction(jrt.accessRuleSet, out);
out.writeUTF(jrt.externalAnnotationPath != null ? jrt.externalAnnotationPath : ""); //$NON-NLS-1$
- out.writeUTF(jrt.release != null ? jrt.release : ""); //$NON-NLS-1$
+ out.writeUTF(""); //$NON-NLS-1$
+ } else {
+ ClasspathJrtWithReleaseOption jrt = (ClasspathJrtWithReleaseOption) c;
+ out.writeByte(EXTERNAL_JAR);
+ out.writeUTF(jrt.zipFilename);
+ writeRestriction(jrt.accessRuleSet, out);
+ out.writeUTF(jrt.externalAnnotationPath != null ? jrt.externalAnnotationPath : ""); //$NON-NLS-1$
+ out.writeUTF(jrt.release);
}
}
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 a61e40abd2..db613ca5a3 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
@@ -49,7 +49,6 @@ 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.ClasspathJrt;
import org.eclipse.jdt.internal.core.builder.ClasspathLocation;
import org.eclipse.jdt.internal.core.util.Util;
@@ -162,7 +161,7 @@ private ClasspathLocation mapToClassPathLocation(JavaModelManager manager, Packa
IJavaProject project = (IJavaProject) root.getParent();
String compliance = project.getOption(JavaCore.COMPILER_COMPLIANCE, true);
cp = (root instanceof JrtPackageFragmentRoot) ?
- new ClasspathJrt(path.toOSString(), rawClasspathEntry.getAccessRuleSet(),
+ ClasspathLocation.forJrtSystem(path.toOSString(), rawClasspathEntry.getAccessRuleSet(),
ClasspathEntry.getExternalAnnotationPath(rawClasspathEntry, project.getProject(), true), compliance) :
ClasspathLocation.forLibrary(manager.getZipFile(path), rawClasspathEntry.getAccessRuleSet(),
ClasspathEntry.getExternalAnnotationPath(rawClasspathEntry,

Back to the top