Bug 480992 - [1.9] Versioning Changes support - JEP 223

Change-Id: Id359b3ea40cbce87bdda3a618f6cae7d80e350b8
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/Jimage.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/JrtFileSystem.java
similarity index 88%
rename from org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/Jimage.java
rename to org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/JrtFileSystem.java
index 5a0e3e2..9c8b866 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/Jimage.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/JrtFileSystem.java
@@ -41,11 +41,11 @@
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
 import org.eclipse.jdt.internal.compiler.env.IModule;
 
-public class Jimage extends Archive {
+public class JrtFileSystem extends Archive {
 
 	private static URI JRT_URI = URI.create("jrt:/"); //$NON-NLS-1$
 	
-	private static final String BOOT_MODULE = "bootmodules.jimage"; //$NON-NLS-1$
+	private static final String BOOT_MODULE = "jrt-fs.jar"; //$NON-NLS-1$
 	
 	private static final String MODULES_SUBDIR = "/modules"; //$NON-NLS-1$
 	
@@ -53,7 +53,7 @@
 
 	private Set<String> typesCache = null;
 	
-	public Jimage(File file) throws ZipException, IOException {
+	public JrtFileSystem(File file) throws ZipException, IOException {
 		this.file = file;
 		initialize();
 	}
@@ -111,7 +111,7 @@
 	}
 	
 	public ArchiveFileObject getArchiveFileObject(String fileName, Charset charset) {
-		return new JimageFileObject(this.file, fileName, null, charset);
+		return new JrtFileObject(this.file, fileName, null, charset);
 	}
 	
 	@Override
@@ -150,12 +150,12 @@
 	
 	@Override
 	public String toString() {
-		return "Jimage: " + (this.file == null ? "UNKNOWN_ARCHIVE" : this.file.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
+		return "JRT: " + (this.file == null ? "UNKNOWN_ARCHIVE" : this.file.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
 	}
 	
-	class JimageFileObject extends ArchiveFileObject {
+	class JrtFileObject extends ArchiveFileObject {
 		IModule module = null;
-		private JimageFileObject(File file, String fileName, IModule module, Charset charset) {
+		private JrtFileObject(File file, String fileName, IModule module, Charset charset) {
 			super(file, fileName, charset);
 			this.module = module;
 		}
@@ -169,7 +169,7 @@
 		protected ClassFileReader getClassReader() {
 			ClassFileReader reader = null;
 			try {
-				reader = ClassFileReader.readFromJimage(this.file, this.entryName, this.module);
+				reader = ClassFileReader.readFromJrt(this.file, this.entryName, this.module);
 			} catch (ClassFormatException e) {
 				e.printStackTrace();
 			} catch (IOException e) {
@@ -186,7 +186,7 @@
 		public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
 			try {
 				return Util.getCharContents(this, ignoreEncodingErrors,
-						org.eclipse.jdt.internal.compiler.util.JimageUtil.getClassfileContent(this.file, this.entryName, new String(this.module.name())),
+						org.eclipse.jdt.internal.compiler.util.JRTUtil.getClassfileContent(this.file, this.entryName, new String(this.module.name())),
 						this.charset.name());
 			} catch (ClassFormatException e) {
 				e.printStackTrace();
@@ -215,7 +215,7 @@
 		 */
 		@Override
 		public InputStream openInputStream() throws IOException {
-			return org.eclipse.jdt.internal.compiler.util.JimageUtil.getContentFromJimage(this.file, this.entryName, null);
+			return org.eclipse.jdt.internal.compiler.util.JRTUtil.getContentFromJrt(this.file, this.entryName, null);
 		}
 
 		/* (non-Javadoc)
@@ -248,7 +248,7 @@
 		@Override
 		public URI toUri() {
 			try {
-				return new URI("jimage:" + this.file.toURI().getPath() + "!" + this.entryName); //$NON-NLS-1$//$NON-NLS-2$
+				return new URI("JRT:" + this.file.toURI().getPath() + "!" + this.entryName); //$NON-NLS-1$//$NON-NLS-2$
 			} catch (URISyntaxException e) {
 				return null;
 			}
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java
index 6340245..57fc22c 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java
@@ -195,8 +195,8 @@
 			// create a new archive
 			if (f.exists()) {
 				try {
-					if (isJimage(f)) {
-						archive = new Jimage(f);
+					if (isJrt(f)) {
+						archive = new JrtFileSystem(f);
 					} else {
 						archive = new Archive(f);
 					}
@@ -715,14 +715,14 @@
 	}
 
 	private boolean isArchive(File f) {
+		if (isJrt(f)) 
+			return false;
 		String extension = getExtension(f);
-		return extension.equalsIgnoreCase(".jar") || extension.equalsIgnoreCase(".zip") ||  //$NON-NLS-1$ //$NON-NLS-2$
-				extension.equalsIgnoreCase(".jimage");//$NON-NLS-1$
+		return extension.equalsIgnoreCase(".jar") || extension.equalsIgnoreCase(".zip"); //$NON-NLS-1$ //$NON-NLS-2$
 	}
 	
-	private boolean isJimage(File f) {
-		String extension = getExtension(f);
-		return extension.equalsIgnoreCase(".jimage");//$NON-NLS-1$
+	private boolean isJrt(File f) {
+		return f.getName().toLowerCase().equals(JrtFileSystem.BOOT_MODULE);
 	}
 
 	/* (non-Javadoc)
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/Jimage.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/JrtFileSystem.java
similarity index 86%
rename from org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/Jimage.java
rename to org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/JrtFileSystem.java
index 6d4c456..36ffc04 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/Jimage.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/JrtFileSystem.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2015 IBM Corporation.
+ * Copyright (c) 2015, 2016 IBM Corporation.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -39,13 +39,13 @@
 
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
-import org.eclipse.jdt.internal.compiler.util.JimageUtil;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 
-public class Jimage extends Archive {
+public class JrtFileSystem extends Archive {
 
 	private static URI JRT_URI = URI.create("jrt:/"); //$NON-NLS-1$
 	
-	private static final String BOOT_MODULE = "bootmodules.jimage"; //$NON-NLS-1$
+	static final String BOOT_MODULE = "jrt-fs.jar"; //$NON-NLS-1$
 	
 	private static final String MODULES_SUBDIR = "/modules"; //$NON-NLS-1$
 	
@@ -53,7 +53,7 @@
 
 	private Set<String> typesCache = null;
 	
-	public Jimage(File file) throws ZipException, IOException {
+	public JrtFileSystem(File file) throws ZipException, IOException {
 		this.file = file;
 		initialize();
 	}
@@ -113,10 +113,10 @@
 	
 	@Override
 	public ArchiveFileObject getArchiveFileObject(String fileName, String module, Charset charset) {
-		return new JimageFileObject(this.file, fileName, module, charset);
+		return new JrtFileObject(this.file, fileName, module, charset);
 	}
 	public ArchiveFileObject getArchiveFileObject(String fileName, Charset charset) {
-		return new JimageFileObject(this.file, fileName, null, charset);
+		return new JrtFileObject(this.file, fileName, null, charset);
 	}
 	
 	@Override
@@ -155,12 +155,12 @@
 	
 	@Override
 	public String toString() {
-		return "Jimage: " + (this.file == null ? "UNKNOWN_ARCHIVE" : this.file.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
+		return "JRT: " + (this.file == null ? "UNKNOWN_ARCHIVE" : this.file.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
 	}
 	
-	class JimageFileObject extends ArchiveFileObject {
+	class JrtFileObject extends ArchiveFileObject {
 		String module = null;
-		private JimageFileObject(File file, String fileName, String module, Charset charset) {
+		private JrtFileObject(File file, String fileName, String module, Charset charset) {
 			super(file, fileName, charset);
 			this.module = module;
 		}
@@ -174,7 +174,7 @@
 		protected ClassFileReader getClassReader() {
 			ClassFileReader reader = null;
 			try {
-				byte[] content = JimageUtil.getClassfileContent(this.file, this.entryName, this.module);
+				byte[] content = JRTUtil.getClassfileContent(this.file, this.entryName, this.module);
 				if (content == null) return null;
 				return new ClassFileReader(content, this.entryName.toCharArray());
 			} catch (ClassFormatException e) {
@@ -193,7 +193,7 @@
 		public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
 			try {
 				return Util.getCharContents(this, ignoreEncodingErrors,
-						org.eclipse.jdt.internal.compiler.util.JimageUtil.getClassfileContent(this.file, this.entryName, this.module),
+						org.eclipse.jdt.internal.compiler.util.JRTUtil.getClassfileContent(this.file, this.entryName, this.module),
 						this.charset.name());
 			} catch (ClassFormatException e) {
 				e.printStackTrace();
@@ -222,7 +222,7 @@
 		 */
 		@Override
 		public InputStream openInputStream() throws IOException {
-			return org.eclipse.jdt.internal.compiler.util.JimageUtil.getContentFromJimage(this.file, this.entryName, null);
+			return org.eclipse.jdt.internal.compiler.util.JRTUtil.getContentFromJrt(this.file, this.entryName, null);
 		}
 
 		/* (non-Javadoc)
@@ -255,7 +255,7 @@
 		@Override
 		public URI toUri() {
 			try {
-				return new URI("jimage:" + this.file.toURI().getPath() + "!" + this.entryName); //$NON-NLS-1$//$NON-NLS-2$
+				return new URI("JRT:" + this.file.toURI().getPath() + "!" + this.entryName); //$NON-NLS-1$//$NON-NLS-2$
 			} catch (URISyntaxException e) {
 				return null;
 			}
diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/PackageInfoTest.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/PackageInfoTest.java
index 7288ab2..74f5df8 100644
--- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/PackageInfoTest.java
+++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/PackageInfoTest.java
@@ -1,10 +1,14 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -134,9 +138,14 @@
 	env.addFile(root, "testcase/package-info.java", //$NON-NLS-1$ //$NON-NLS-2$
 		"@TestAnnotation package testcase;" //$NON-NLS-1$
 	);
-
 	incrementalBuild(projectPath);
-	expectingNoProblems();
+	String javaVersion = System.getProperty("java.version");
+	if (javaVersion != null && javaVersion.startsWith("9")) {
+		expectingProblemsFor(new Path("/Project/src/testcase/Main.java"), 
+				"Problem : The method getPackage(String) from the type Package is deprecated [ resource : </Project/src/testcase/Main.java> range : <125,147> category : <110> severity : <1>]");
+	} else {
+		expectingNoProblems();
+	}
 	executeClass(projectPath, "testcase.Main", "@testcase.TestAnnotation()@testcase.TestAnnotation()", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 }
 public void test003() throws JavaModelException {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/EvalTestsTarget.zip b/org.eclipse.jdt.core.tests.compiler/src/EvalTestsTarget.zip
index 19bb2e9..477ae07 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/EvalTestsTarget.zip
+++ b/org.eclipse.jdt.core.tests.compiler/src/EvalTestsTarget.zip
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
index 6aad45f..868450d 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
@@ -5,6 +5,10 @@
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contribution for
@@ -148,6 +152,8 @@
 			this.version = JavaCore.VERSION_1_7;
 		} else if (rawVersion.indexOf("1.8") != -1) {
 			this.version = JavaCore.VERSION_1_8;
+		} else if(rawVersion.startsWith("9")) {
+			this.version = JavaCore.VERSION_9;
 		} else {
 			throw new RuntimeException("unknown javac version: " + rawVersion);
 		}
@@ -203,6 +209,9 @@
 				return 1500;
 			}
 		}
+		if (version == JavaCore.VERSION_9) {
+			return 0000; // We are still in EA
+		}
 		throw new RuntimeException("unknown raw javac version: " + rawVersion);
 	}
 	// returns 0L if everything went fine; else the lower word contains the
@@ -1071,7 +1080,7 @@
 	}
 
 	protected INameEnvironment[] getClassLibs(boolean useDefaultClasspaths) {
-		String encoding = (String)getCompilerOptions().get(CompilerOptions.OPTION_Encoding);
+		String encoding = getCompilerOptions().get(CompilerOptions.OPTION_Encoding);
 		if ("".equals(encoding))
 			encoding = null;
 		if (useDefaultClasspaths && encoding == null)
@@ -1083,8 +1092,8 @@
 		);
 		return classLibs;
 	}
-	protected Map getCompilerOptions() {
-		Map defaultOptions = super.getCompilerOptions();
+	protected Map<String, String> getCompilerOptions() {
+		Map<String, String> defaultOptions = super.getCompilerOptions();
 		defaultOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
 		defaultOptions.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.WARNING);
 		defaultOptions.put(CompilerOptions.OPTION_ReportUnusedImport, CompilerOptions.WARNING);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR335ClassFileTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR335ClassFileTest.java
index d38273d..e95b102 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR335ClassFileTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JSR335ClassFileTest.java
@@ -5,6 +5,10 @@
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     Jesper Steen Moller - initial API and implementation
  *            Bug 416885 - [1.8][compiler]IncompatibleClassChange error (edit)
@@ -21,14 +25,22 @@
 import org.eclipse.jdt.core.tests.util.Util;
 import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
 import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 
 @SuppressWarnings({ "unchecked", "rawtypes" })
 public class JSR335ClassFileTest extends AbstractComparableTest {
 
+	String versionString = null;
+
 public JSR335ClassFileTest(String name) {
 	super(name);
 }
+// No need for a tearDown()
+protected void setUp() throws Exception {
+	super.setUp();
+	this.versionString = (this.complianceLevel < ClassFileConstants.JDK9) ? "version 1.8 : 52.0" : "version 9 : 53.0";
+}
 
 /*
  * Toggle compiler in mode -1.8
@@ -77,7 +89,7 @@
 	);
 
 	String expectedOutput =
-		"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+		"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 		"public class X {\n" + 
 		"  Constant pool:\n" + 
 		"    constant #1 class: #2 X\n" + 
@@ -184,7 +196,7 @@
 	);
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -293,7 +305,7 @@
 	);
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -398,7 +410,7 @@
 	);
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -520,7 +532,7 @@
 		},
 	"SUCCESS"
 	);
-	verifyClassFile(			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+	verifyClassFile("// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -634,7 +646,7 @@
 	"SUCCESS"
 	);
 	String expected =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -745,7 +757,7 @@
 	);
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -868,7 +880,7 @@
 	);
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -990,7 +1002,7 @@
 	);
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -1109,7 +1121,7 @@
 	);
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -1261,7 +1273,7 @@
 	);
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -1429,7 +1441,7 @@
 	);
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -1597,7 +1609,7 @@
 		"");
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -1759,7 +1771,7 @@
 		"");
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -1898,7 +1910,7 @@
 		"");
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -2092,7 +2104,7 @@
 		"");
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"public class X {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X\n" + 
@@ -2340,7 +2352,7 @@
 		"Lambda");
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"class X$1Y {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X$1Y\n" + 
@@ -2517,7 +2529,7 @@
 		"Lambda");
 
 	String expectedOutput =
-			"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 			"class X$1Y {\n" + 
 			"  Constant pool:\n" + 
 			"    constant #1 class: #2 X$1Y\n" + 
@@ -2940,7 +2952,7 @@
 			"m(bridge method(i))");
 		
 		String expectedOutput =
-						"// Compiled from X.java (version 1.8 : 52.0, super bit)\n" + 
+						"// Compiled from X.java (" + this.versionString + ", super bit)\n" + 
 						"public class X {\n" + 
 						"  Constant pool:\n" + 
 						"    constant #1 class: #2 X\n" + 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
index 7fd9bdf..58dfbb2 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
@@ -1024,6 +1024,9 @@
 }
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=406641, [1.8][compiler][codegen] Code generation for intersection cast.
 public void test039() {
+	String errMsg = isJRE9 ?
+			"X (in module: Unnamed Module) cannot be cast to I (in module: Unnamed Module)" :
+				"X cannot be cast to I";
 	this.runConformTest(
 			new String[] {
 					"X.java",
@@ -1044,7 +1047,7 @@
 					"	}\n" +
 					"}\n",
 				},
-				"X cannot be cast to I");
+				errMsg);
 }
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=406773, [1.8][compiler][codegen] "java.lang.IncompatibleClassChangeError" caused by attempted invocation of private constructor
 public void test041() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodParametersAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodParametersAttributeTest.java
index dd5e3ea..c89aa32 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodParametersAttributeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodParametersAttributeTest.java
@@ -1,10 +1,14 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2015 Jesper Steen Moeller and others.
+ * Copyright (c) 2013, 2016 Jesper Steen Moeller and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- * 
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     Jesper Steen Moeller - initial API and implementation
  *******************************************************************************/
@@ -19,17 +23,23 @@
 import org.eclipse.jdt.core.ToolFactory;
 import org.eclipse.jdt.core.tests.util.Util;
 import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
+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.IBinaryMethod;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 
-@SuppressWarnings({ "unchecked", "rawtypes" })
 public class MethodParametersAttributeTest extends AbstractRegressionTest {
+	String versionString = null;
 	public MethodParametersAttributeTest(String name) {
 		super(name);
 	}
-
+	// No need for a tearDown()
+	protected void setUp() throws Exception {
+		super.setUp();
+		this.versionString = (this.complianceLevel < ClassFileConstants.JDK9) ? "version 1.8 : 52.0" : "version 9 : 53.0";
+	}
+	@SuppressWarnings("rawtypes")
 	public static Class testClass() {
 		return MethodParametersAttributeTest.class;
 	}
@@ -377,7 +387,7 @@
 				ClassFileBytesDisassembler.DETAILED);
 	
 		String expectedOutput =
-				"// Compiled from ParameterNames.java (version 1.8 : 52.0, super bit)\n" + 
+				"// Compiled from ParameterNames.java (" + this.versionString + ", super bit)\n" + 
 				"public class ParameterNames {\n" + 
 				"  \n" + 
 				"  // Method descriptor #6 ()V\n" + 
@@ -463,7 +473,7 @@
 				ClassFileBytesDisassembler.DETAILED);
 
 		String expectedOutput =
-			"// Compiled from ParameterNames.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from ParameterNames.java (" + this.versionString + ", super bit)\n" + 
 			"// Signature: Ljava/lang/Object;Ljava/util/concurrent/Callable<Ljava/lang/String;>;\n" + 
 			"class ParameterNames$1 implements java.util.concurrent.Callable {\n" + 
 			"  \n" + 
@@ -543,7 +553,7 @@
 				ClassFileBytesDisassembler.DETAILED);
 
 		String expectedOutput =
-			"// Compiled from FancyEnum.java (version 1.8 : 52.0, super bit)\n" + 
+			"// Compiled from FancyEnum.java (" + this.versionString + ", super bit)\n" + 
 			"// Signature: Ljava/lang/Enum<LFancyEnum;>;\n" + 
 			"public final enum FancyEnum {\n" + 
 			"  \n" + 
@@ -935,7 +945,7 @@
 	}
 
 	private void runParameterNameTest(String fileName, String body) {
-		Map compilerOptions = getCompilerOptions();
+		Map<String, String> compilerOptions = getCompilerOptions();
 		compilerOptions.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE);
 		compilerOptions.put(CompilerOptions.OPTION_MethodParametersAttribute, CompilerOptions.GENERATE);
 		this.runConformTest(
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/runtime/LocalVMLauncher.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/runtime/LocalVMLauncher.java
index f888373..ca68e24 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/runtime/LocalVMLauncher.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/runtime/LocalVMLauncher.java
@@ -65,7 +65,13 @@
 	if (osName.startsWith("Mac")) {
 		return new MacVMLauncher();
 	}
-	File file = new File(Util.getJREDirectory() + "/lib/rt.jar");
+	File file = null;
+	String javaVersion = System.getProperty("java.version");
+	if (javaVersion != null && javaVersion.length() > 0 && javaVersion.charAt(0) == '9') {
+		file = new File(Util.getJREDirectory() + "/jrt-fs.jar");
+	} else {
+		new File(Util.getJREDirectory() + "/lib/rt.jar");
+	}
 	if (file.exists()) {
 		return new StandardVMLauncher();
 	}
@@ -135,7 +141,10 @@
 		}
 		System.out.println();
 		*/
-
+		System.out.println("Command line: ");
+		for (String string : commandLine) {
+			System.out.println(string);
+		}
 		vmProcess= Runtime.getRuntime().exec(commandLine);
 	} catch (IOException e) {
 		throw new TargetException("Error launching VM at " + this.vmPath);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/runtime/StandardVMLauncher.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/runtime/StandardVMLauncher.java
index 3723e57..d7236d6 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/runtime/StandardVMLauncher.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/runtime/StandardVMLauncher.java
@@ -1,10 +1,14 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -28,10 +32,15 @@
 @SuppressWarnings({ "rawtypes" ,"unchecked" })
 public class StandardVMLauncher extends LocalVMLauncher {
 	String batchFileName;
+	private boolean isJrtBasedVM;
 /**
  * Creates a new StandardVMLauncher that launches a standard VM
  * on the same machine.
  */
+public StandardVMLauncher(boolean isJrtBasedVM) {
+	super();
+	this.isJrtBasedVM = isJrtBasedVM;
+}
 public StandardVMLauncher() {
 	super();
 }
@@ -50,17 +59,19 @@
 			bootPathString.append(pathSeparator);
 		}
 	} else {
-		// Add regular rt.jar
-		bootPathString.append(this.vmPath);
-		bootPathString.append(File.separator);
-		if (!(this.vmPath.toLowerCase().endsWith("jre") || this.vmPath.toLowerCase().endsWith("jre" + File.separator))) {
-			bootPathString.append("jre");
+		if (!this.isJrtBasedVM) {
+			// Add regular rt.jar
+			bootPathString.append(this.vmPath);
 			bootPathString.append(File.separator);
+			if (!(this.vmPath.toLowerCase().endsWith("jre") || this.vmPath.toLowerCase().endsWith("jre" + File.separator))) {
+				bootPathString.append("jre");
+				bootPathString.append(File.separator);
+			}
+			bootPathString.append("lib");
+			bootPathString.append(File.separator);
+			bootPathString.append("rt.jar");
+			bootPathString.append(pathSeparator);
 		}
-		bootPathString.append("lib");
-		bootPathString.append(File.separator);
-		bootPathString.append("rt.jar");
-		bootPathString.append(pathSeparator);
 	}
 
 	// Add boot class path directory if needed
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java
index ce7b35c..080a69b 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java
@@ -33,6 +33,7 @@
 import org.eclipse.jdt.internal.compiler.IProblemFactory;
 import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
 import org.eclipse.jdt.internal.compiler.batch.FileSystem;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblem;
@@ -724,6 +725,18 @@
  * Returns null if none could be found.
 */
 public static String[] getJavaClassLibs() {
+	String javaVersion = System.getProperty("java.version");
+	if (javaVersion.length() > 3) {
+		javaVersion = javaVersion.substring(0, 3);
+	}
+	long jdkLevel = CompilerOptions.versionToJdkLevel(javaVersion);
+	if (jdkLevel >= ClassFileConstants.JDK9) {
+		String jreDir = getJREDirectory();
+		return new String[] {
+				toNativePath(jreDir + "/jrt-fs.jar")
+		};
+	}
+
 	// check bootclasspath properties for Sun, JRockit and Harmony VMs
 	String bootclasspathProperty = System.getProperty("sun.boot.class.path"); //$NON-NLS-1$
 	if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) {
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 ce9bb7c..e506282 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
@@ -2836,7 +2836,13 @@
 			newJclLibString = "JCL18_FULL";
 			newJclSrcString = "JCL18_SRC"; // Use the same source
 		} else {
-			if (compliance.charAt(2) > '7') {
+			if (compliance.length() < 3) {
+				// stop-gap measure. As of now, the Java 9 tests rely
+				// on adding the JREContainer directly to the classpath.
+					newJclLibString = "JCL18_LIB";
+					newJclSrcString = "JCL18_SRC";
+				//}
+			} else if (compliance.charAt(2) > '7') {
 				newJclLibString = "JCL18_LIB";
 				newJclSrcString = "JCL18_SRC";
 			} else if (compliance.charAt(2) > '4') {
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 5880ee4..db4d82f 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
@@ -32,7 +32,7 @@
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
-import org.eclipse.jdt.internal.core.ModulePackageFragmentRoot;
+import org.eclipse.jdt.internal.core.JrtPackageFragmentRoot;
 
 import junit.framework.Test;
 
@@ -59,6 +59,7 @@
 
 	public void setUpSuite() throws Exception {
 		super.setUpSuite();
+		System.setProperty("modules.to.load", "java.baserequires java.desktop;java.rmi;java.sql;");
 		this.currentProject = createJava9Project("P1");
 		this.createFile("P1/src/module-info.java", "");
 		this.createFolder("P1/src/com/greetings");
@@ -67,14 +68,14 @@
 		waitForAutoBuild();
 	}
 	private IJavaProject createJava9Project(String name) throws CoreException {
-		String bootModPath = System.getProperty("java.home") +File.separator +"lib/modules/bootmodules.jimage";
-		IClasspathEntry jimageEntry = JavaCore.newLibraryEntry(new Path(bootModPath), null, null, null, null, false);
+		String bootModPath = System.getProperty("java.home") + File.separator +"jrt-fs.jar";
+		IClasspathEntry jrtEntry = JavaCore.newLibraryEntry(new Path(bootModPath), null, null, null, null, false);
 		IJavaProject project = this.createJavaProject(name, new String[] { "src" }, new String[0],
 				new String[0], "bin", "9");
 		IClasspathEntry[] old = project.getRawClasspath();
 		IClasspathEntry[] newPath = new IClasspathEntry[old.length +1];
 		System.arraycopy(old, 0, newPath, 0, old.length);
-		newPath[old.length] = jimageEntry;
+		newPath[old.length] = jrtEntry;
 		project.setRawClasspath(newPath, null);
 		return project;
 	}
@@ -91,7 +92,7 @@
 				}
 			}
 			assertNotNull("Java.base module should not null", base);
-			assertTrue("Java.base should be a module package fragment root", (base instanceof ModulePackageFragmentRoot));
+			assertTrue("Java.base should be a module package fragment root", (base instanceof JrtPackageFragmentRoot));
 			assertMarkers("Unexpected markers", "", this.currentProject);
 		} finally {
 		}
@@ -736,5 +737,6 @@
 	public void tearDownSuite() throws Exception {
 		super.tearDownSuite();
 		deleteProject("P1");
+		System.setProperty("modules.on.demand", "");
 	}
 }
diff --git a/org.eclipse.jdt.core.tests.model/workspace/ConvertToModule/.classpath b/org.eclipse.jdt.core.tests.model/workspace/ConvertToModule/.classpath
index aeedbc3..47313f3 100644
--- a/org.eclipse.jdt.core.tests.model/workspace/ConvertToModule/.classpath
+++ b/org.eclipse.jdt.core.tests.model/workspace/ConvertToModule/.classpath
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>

 <classpath>

 	<classpathentry kind="src" path="jdt.test"/>

-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-9.0"/>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-9"/>

 	<classpathentry kind="lib" path="m1.jar"/>

 	<classpathentry kind="output" path="bin"/>

 </classpath>

diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
index cad7d9e..3cdc0d6 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJar.java
@@ -39,7 +39,7 @@
 import org.eclipse.jdt.internal.compiler.env.IModule;
 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
 import org.eclipse.jdt.internal.compiler.lookup.ModuleEnvironment;
-import org.eclipse.jdt.internal.compiler.util.JimageUtil;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 import org.eclipse.jdt.internal.compiler.util.ManifestAnalyzer;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.compiler.util.Util;
@@ -53,20 +53,20 @@
 protected boolean closeZipFileAtEnd;
 private Set<String> packageCache;
 protected List<String> annotationPaths;
-protected boolean isJimage;
+protected boolean isJrt;
 
 public ClasspathJar(File file, boolean closeZipFileAtEnd,
-		AccessRuleSet accessRuleSet, String destinationPath, boolean jimage) {
+		AccessRuleSet accessRuleSet, String destinationPath, boolean isJrt) {
 	super(accessRuleSet, destinationPath);
 	this.file = file;
-	this.isJimage = jimage;
+	this.isJrt = isJrt;
 	this.closeZipFileAtEnd = closeZipFileAtEnd;
 }
 
 public List fetchLinkedJars(FileSystem.ClasspathSectionProblemReporter problemReporter) {
 	// expected to be called once only - if multiple calls desired, consider
 	// using a cache
-	if (this.isJimage) return null;
+	if (this.isJrt) return null;
 	InputStream inputStream = null;
 	try {
 		initialize();
@@ -95,7 +95,9 @@
 			}
 		}
 		return result;
-	} catch (IOException e) {
+	} catch (IOException | IllegalArgumentException e) {
+		// JRE 9 could throw an IAE if the path is incorrect. We are to ignore such
+		// linked jars
 		return null;
 	} finally {
 		if (inputStream != null) {
@@ -116,8 +118,8 @@
 
 	try {
 		ClassFileReader reader = null;
-		if (this.isJimage) {
-			reader = ClassFileReader.readFromJimage(this.file, qualifiedBinaryFileName, mod);
+		if (this.isJrt) {
+			reader = ClassFileReader.readFromJrt(this.file, qualifiedBinaryFileName, mod);
 		} else {
 			reader = ClassFileReader.read(this.zipFile, qualifiedBinaryFileName);
 		}
@@ -148,7 +150,7 @@
 }
 @Override
 public boolean hasAnnotationFileFor(String qualifiedTypeName) {
-	if (this.isJimage) return false; // TODO: Revisit
+	if (this.isJrt) return false; // TODO: Revisit
 	return this.zipFile.getEntry(qualifiedTypeName+ExternalAnnotationProvider.ANNOTATION_FILE_SUFFIX) != null; 
 }
 public char[][][] findTypeNames(final String qualifiedPackageName, final IModule mod) {
@@ -156,9 +158,9 @@
 		return null; // most common case
 	final char[] packageArray = qualifiedPackageName.toCharArray();
 	final ArrayList answers = new ArrayList();
-	if (this.isJimage) {
+	if (this.isJrt) {
 		try {
-			JimageUtil.walkModuleImage(this.file, new JimageUtil.JimageVisitor<java.nio.file.Path>() {
+			JRTUtil.walkModuleImage(this.file, new JRTUtil.JrtFileVisitor<java.nio.file.Path>() {
 
 				@Override
 				public FileVisitResult visitPackage(java.nio.file.Path dir, java.nio.file.Path modPath, BasicFileAttributes attrs) throws IOException {
@@ -189,7 +191,7 @@
 					return FileVisitResult.CONTINUE;
 				}
 
-			}, JimageUtil.NOTIFY_ALL);
+			}, JRTUtil.NOTIFY_ALL);
 		} catch (IOException e) {
 			// Ignore and move on
 		}
@@ -228,7 +230,7 @@
 	}
 }
 public void initialize() throws IOException {
-	if (this.zipFile == null && !this.isJimage) {
+	if (this.zipFile == null && !this.isJrt) {
 		this.zipFile = new ZipFile(this.file);
 	}
 }
@@ -250,9 +252,9 @@
 
 	this.packageCache = new HashSet<>(41);
 	this.packageCache.add(Util.EMPTY_STRING);
-	if (this.isJimage) {
+	if (this.isJrt) {
 		try {
-			JimageUtil.walkModuleImage(this.file, new JimageUtil.JimageVisitor<java.nio.file.Path>() {
+			JRTUtil.walkModuleImage(this.file, new JRTUtil.JrtFileVisitor<java.nio.file.Path>() {
 
 				@Override
 				public FileVisitResult visitPackage(java.nio.file.Path dir, java.nio.file.Path mod, BasicFileAttributes attrs) throws IOException {
@@ -270,7 +272,7 @@
 					return FileVisitResult.CONTINUE;
 				}
 
-			}, JimageUtil.NOTIFY_PACKAGES);
+			}, JRTUtil.NOTIFY_PACKAGES);
 		} catch (IOException e) {
 			// Ignore and move on
 		}
@@ -301,7 +303,7 @@
 			this.annotationZipFile = null;
 		}
 	}
-	if (!this.isJimage || this.annotationPaths != null) {
+	if (!this.isJrt || this.annotationPaths != null) {
 		this.packageCache = null;
 		this.annotationPaths = null;
 	}
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 547e72f..d1ae473 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
@@ -34,6 +34,7 @@
 import org.eclipse.jdt.internal.compiler.env.IModule;
 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
 import org.eclipse.jdt.internal.compiler.lookup.ModuleEnvironment;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.compiler.util.Util;
 
@@ -118,7 +119,7 @@
 	protected Classpath[] classpaths;
 	Set knownFileNames;
 	protected boolean annotationsFromClasspath; // should annotation files be read from the classpath (vs. explicit separate path)?
-	private static HashMap<File, Classpath> JIMAGES = null;
+	private static HashMap<File, Classpath> JRT_CLASSPATH_CACHE = null;
 
 /*
 	classPathNames is a collection is Strings representing the full path of each class path
@@ -153,7 +154,8 @@
 		try {
 			classpath.initialize();
 			this.classpaths[counter++] = classpath;
-		} catch(IOException exception) {
+		} catch(IOException | IllegalArgumentException exception) {
+			// JRE 9 could through an IAE if the linked JAR paths have invalid chars, such as ":"
 			// ignore
 		}
 	}
@@ -197,15 +199,15 @@
 						convertPathSeparators(destinationPath));
 			} else if (destinationPath == null) {
 				// class file only mode
-				if (format == Util.JIMAGE_FILE) {
-					if (JIMAGES == null) {
-						JIMAGES = new HashMap<>();
+				if (classpathName.endsWith(JRTUtil.JRT_FS_JAR)) {
+					if (JRT_CLASSPATH_CACHE == null) {
+						JRT_CLASSPATH_CACHE = new HashMap<>();
 					} else {
-						result = JIMAGES.get(file);
+						result = JRT_CLASSPATH_CACHE.get(file);
 					}
 					if (result == null) {
 						result = new ClasspathJar(file, true, accessRuleSet, null, true);
-						JIMAGES.put(file, result);
+						JRT_CLASSPATH_CACHE.put(file, result);
 					}
 				} else {
 					result = new ClasspathJar(file, true, accessRuleSet, null, false);
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index f46fe1f..c9006fe 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -115,7 +115,6 @@
 		private static final String CLASSPATH_FOLDER = "FOLDER"; //$NON-NLS-1$
 		private static final String CLASSPATH_ID = "id"; //$NON-NLS-1$
 		private static final String CLASSPATH_JAR = "JAR"; //$NON-NLS-1$
-		private static final String CLASSPATH_JIMAGE = "JIMAGE"; //$NON-NLS-1$
 		private static final String CLASSPATHS = "classpaths"; //$NON-NLS-1$
 		private static final String COMMAND_LINE_ARGUMENT = "argument"; //$NON-NLS-1$
 		private static final String COMMAND_LINE_ARGUMENTS = "command_line"; //$NON-NLS-1$
@@ -513,9 +512,6 @@
 						if (f.isFile()) {
 							int kind = Util.archiveFormat(classpath);
 							switch (kind) {
-								case Util.JIMAGE_FILE:
-									id = Logger.CLASSPATH_JIMAGE;
-									break;
 								case Util.ZIP_FILE:
 									id = Logger.CLASSPATH_JAR;
 									break;
@@ -1692,6 +1688,8 @@
 			return ClassFileConstants.JDK1_7 >= minimalSupportedVersion;
 		case ClassFileConstants.MAJOR_VERSION_1_8: // 1.8
 			return ClassFileConstants.JDK1_8 >= minimalSupportedVersion;
+		case ClassFileConstants.MAJOR_VERSION_9: // 9
+			return ClassFileConstants.JDK9 >= minimalSupportedVersion;
 	}
 	// unknown version
 	return false;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
index 8e0d2b7..e60cc0b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
@@ -39,7 +39,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.ExternalAnnotationStatus;
-import org.eclipse.jdt.internal.compiler.util.JimageUtil;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 import org.eclipse.jdt.internal.compiler.util.Util;
 
 public class ClassFileReader extends ClassFileStruct implements IBinaryType {
@@ -125,19 +125,19 @@
 }
 
 public static ClassFileReader readFromJimage(
-		File jimage,
+		File jrt,
 		String filename)
 		throws ClassFormatException, java.io.IOException {
 
-		return readFromJimage(jimage, filename, null);
+		return readFromJrt(jrt, filename, null);
 	}
-public static ClassFileReader readFromJimage(
-		File jimage,
+public static ClassFileReader readFromJrt(
+		File jrt,
 		String filename,
 		IModule module)
 
 		throws ClassFormatException, java.io.IOException {
-		return JimageUtil.getClassfile(jimage, filename, module);
+		return JRTUtil.getClassfile(jrt, filename, module);
 	}
 
 public static ClassFileReader read(
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index ea47165..a6fbdfd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -60,7 +60,7 @@
 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
 import org.eclipse.jdt.internal.compiler.util.HashtableOfPackage;
-import org.eclipse.jdt.internal.compiler.util.JimageUtil;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 
 @SuppressWarnings({"rawtypes", "unchecked"})
@@ -208,7 +208,7 @@
 		return null;
 
 	char[] module = answer.moduleName();
-	if (module != null && !CharOperation.equals(module, JimageUtil.JAVA_BASE.toCharArray()) 
+	if (module != null && !CharOperation.equals(module, JRTUtil.JAVA_BASE.toCharArray()) 
 			&& !this.nameEnvironment.isPackageVisible(packageBinding.readableName(), module, mod)) {
 		return null;
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
index 4c02a98..46d7565 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
@@ -25,7 +25,7 @@
 import org.eclipse.jdt.internal.compiler.env.IModule;
 import org.eclipse.jdt.internal.compiler.env.IModule.IModuleReference;
 import org.eclipse.jdt.internal.compiler.env.IModule.IPackageExport;
-import org.eclipse.jdt.internal.compiler.util.JimageUtil;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 
 public class ModuleBinding extends Binding {
 
@@ -147,7 +147,7 @@
 		}
 		if (!CharOperation.equals(this.moduleName, TypeConstants.JAVA_BASE)) {
 			// TODO: Do we need to add java.base here?
-			allRequires.add(this.environment.getModule(JimageUtil.JAVA_BASE_CHAR));
+			allRequires.add(this.environment.getModule(JRTUtil.JAVA_BASE_CHAR));
 		}
 		return this.requiredModules = allRequires.size() > 0 ? allRequires.toArray(new ModuleBinding[allRequires.size()]) : NO_REQUIRES;
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleEnvironment.java
index efebbd3..f702267 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleEnvironment.java
@@ -28,7 +28,7 @@
 import org.eclipse.jdt.internal.compiler.env.IModuleLocation;
 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
-import org.eclipse.jdt.internal.compiler.util.JimageUtil;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 
 public abstract class ModuleEnvironment implements INameEnvironment {
 	/*
@@ -83,7 +83,7 @@
 		NameEnvironmentAnswer answer = findType(typeName, packageName, getVisibleModules(client));
 		char[] module = null;
 		if(answer == null || (module = answer.moduleName()) == null || 
-				CharOperation.equals(module, JimageUtil.JAVA_BASE_CHAR)) {
+				CharOperation.equals(module, JRTUtil.JAVA_BASE_CHAR)) {
 			return answer;
 		}
 		return returnAnswerAfterValidation(packageName, answer, client);
@@ -178,7 +178,7 @@
 		IModule[] targets = null;
 		if (mod != null && !CharOperation.equals(mod, UNNAMED)) {
 			Set<IModule> set = new LinkedHashSet<>();
-			IModule client = getModule(JimageUtil.JAVA_BASE.toCharArray());
+			IModule client = getModule(JRTUtil.JAVA_BASE.toCharArray());
 			if (client != null) set.add(client);
 			client = getModule(mod);
 			if (client != null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JimageUtil.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
similarity index 70%
rename from org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JimageUtil.java
rename to org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
index eac9925..7004933 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JimageUtil.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
@@ -39,7 +39,7 @@
 import org.eclipse.jdt.internal.compiler.env.IModule;
 import org.eclipse.jdt.internal.compiler.lookup.ModuleEnvironment;
 
-public class JimageUtil {
+public class JRTUtil {
 
 	public static final String JAVA_DOT = "java."; //$NON-NLS-1$
 	public static final String JAVA_BASE = "java.base"; //$NON-NLS-1$
@@ -49,7 +49,7 @@
 	static final String[] NO_MODULE = new String[0];
 	static final String MULTIPLE = "MU"; //$NON-NLS-1$
 	static final String DEFAULT_PACKAGE = ""; //$NON-NLS-1$
-	static final String MODULES_ON_DEMAND = System.getProperty("modules"); //$NON-NLS-1$
+	static String MODULE_TO_LOAD = null;
 	public static final String JRT_FS_JAR = "jrt-fs.jar"; //$NON-NLS-1$
 	static URI JRT_URI = URI.create("jrt:/"); //$NON-NLS-1$
 	public static int NOTIFY_FILES = 0x0001;
@@ -58,11 +58,11 @@
 	public static int NOTIFY_ALL = NOTIFY_FILES | NOTIFY_PACKAGES | NOTIFY_MODULES;
 
 	// TODO: BETA_JAVA9 Think about clearing the cache too.
-	private static Map<File, JimageFileSystem> images = null;
+	private static Map<File, JrtFileSystem> images = null;
 
 	private static final Object lock = new Object();
 
-	public interface JimageVisitor<T> {
+	public interface JrtFileVisitor<T> {
 
 		public FileVisitResult visitPackage(T dir, T mod, BasicFileAttributes attrs) throws IOException;
 
@@ -70,7 +70,7 @@
 		/**
 		 * Invoked when a root directory of a module being visited. The element returned 
 		 * contains only the module name segment - e.g. "java.base". Clients can use this to control
-		 * how the Jimage needs to be processed, for e.g., clients can skip a particular module
+		 * how the JRT needs to be processed, for e.g., clients can skip a particular module
 		 * by returning FileVisitResult.SKIP_SUBTREE
 		 */
 		public FileVisitResult visitModule(T mod) throws IOException;
@@ -98,8 +98,8 @@
 		}
 	}
 
-	public static JimageFileSystem getJimageSystem(File image) {
-		Map<File, JimageFileSystem> i = images;
+	public static JrtFileSystem getJrtSystem(File image) {
+		Map<File, JrtFileSystem> i = images;
 		if (images == null) {
 			synchronized (lock) {
 	            i = images;
@@ -108,15 +108,15 @@
 	            }
 	        }
 		}
-		JimageFileSystem system = null;
+		JrtFileSystem system = null;
 		synchronized(i) {
 			if ((system = images.get(image)) == null) {
 				try {
-					images.put(image, system = new JimageFileSystem(image));
+					images.put(image, system = new JrtFileSystem(image));
 				} catch (IOException e) {
 					e.printStackTrace();
 					// Needs better error handling downstream? But for now, make sure 
-					// a dummy JimageFileSystem is not created.
+					// a dummy JrtFileSystem is not created.
 				}
 			}
 		}
@@ -132,58 +132,59 @@
 	 *  /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 JimageUtil#NOTIFY_ALL},
-	 *  {@link JimageUtil#NOTIFY_FILES}, {@link JimageUtil#NOTIFY_PACKAGES} and {@link JimageUtil#NOTIFY_MODULES}.
+	 *  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.
-	 * @param visitor an instance of JimageVisitor to be notified of the entries in the JRT image.
+	 * @param visitor an instance of JrtFileVisitor to be notified of the entries in the JRT image.
 	 * @param notify flag indicating the notifications the client is interested in.
 	 * @throws IOException
 	 */
-	public static void walkModuleImage(File image, final JimageUtil.JimageVisitor<java.nio.file.Path> visitor, int notify) throws IOException {
-		getJimageSystem(image).walkModuleImage(visitor, false, notify);
+	public static void walkModuleImage(File image, final JRTUtil.JrtFileVisitor<java.nio.file.Path> visitor, int notify) throws IOException {
+		getJrtSystem(image).walkModuleImage(visitor, false, notify);
 	}
 
-	public static InputStream getContentFromJimage(File jimage, String fileName, String module) throws IOException {
-		return getJimageSystem(jimage).getContentFromJimage(fileName, module);
+	public static InputStream getContentFromJrt(File jrt, String fileName, String module) throws IOException {
+		return getJrtSystem(jrt).getContentFromJrt(fileName, module);
 	}
-	public static byte[] getClassfileContent(File jimage, String fileName, String module) throws IOException, ClassFormatException {
-		return getJimageSystem(jimage).getClassfileContent(fileName, module);
+	public static byte[] getClassfileContent(File jrt, String fileName, String module) throws IOException, ClassFormatException {
+		return getJrtSystem(jrt).getClassfileContent(fileName, module);
 	}
-	public static ClassFileReader getClassfile(File jimage, String fileName, IModule module) throws IOException, ClassFormatException {
-		return getJimageSystem(jimage).getClassfile(fileName, module);
+	public static ClassFileReader getClassfile(File jrt, String fileName, IModule module) throws IOException, ClassFormatException {
+		return getJrtSystem(jrt).getClassfile(fileName, module);
 	}
 }
-class JimageFileSystem {
+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 jrt = null;
+	FileSystem jrtSystem = null;
 	
 	/**
-	 * As of now, the passed reference to the jimage file is not being used. Perhaps eventually
-	 * when we know how to read a particular jimage, we will make use of this.
+	 * The jrt file system is based on the location of the JRE home whose libraries
+	 * need to be loaded.
 	 *
-	 * @param image
+	 * @param jrt the path to the root of the JRE whose libraries we are interested in.
 	 * @throws IOException 
 	 */
-	public JimageFileSystem(File image) throws IOException {
-		initialize(image);
+	public JrtFileSystem(File jrt) throws IOException {
+		initialize(jrt);
 	}
-	void initialize(File image) throws IOException {
+	void initialize(File jrt) throws IOException {
 		URL url = null;
-		if (image.toString().endsWith(JimageUtil.JRT_FS_JAR)) {
-			url = image.toPath().toUri().toURL();
-		} else if (image.isDirectory()) {
-			url = image.toPath().toUri().toURL();
+		if (jrt.toString().endsWith(JRTUtil.JRT_FS_JAR)) {
+			url = jrt.toPath().toUri().toURL();
+		} else if (jrt.isDirectory()) {
+			url = jrt.toPath().toUri().toURL();
 		} else {
-			String jdkHome = image.getParentFile().getParentFile().getParent();
-			url = Paths.get(jdkHome, JimageUtil.JRT_FS_JAR).toUri().toURL();
+			String jdkHome = jrt.getParentFile().getParentFile().getParent();
+			url = Paths.get(jdkHome, JRTUtil.JRT_FS_JAR).toUri().toURL();
 		}
+		JRTUtil.MODULE_TO_LOAD = System.getProperty("modules.to.load"); //$NON-NLS-1$
 		URLClassLoader loader = new URLClassLoader(new URL[] { url });
 		HashMap<String, ?> env = new HashMap<>();
-		this.jrt = FileSystems.newFileSystem(JimageUtil.JRT_URI, env, loader);
+		this.jrtSystem = FileSystems.newFileSystem(JRTUtil.JRT_URI, env, loader);
 		walkModuleImage(null, true, 0 /* doesn't matter */);
 	}
 
@@ -193,27 +194,27 @@
 		if (idx != -1) {
 			pack = fileName.substring(0, idx);
 		} else {
-			pack = JimageUtil.DEFAULT_PACKAGE;
+			pack = JRTUtil.DEFAULT_PACKAGE;
 		}
 		String module = this.packageToModule.get(pack);
 		if (module != null) {
-			if (module == JimageUtil.MULTIPLE) {
+			if (module == JRTUtil.MULTIPLE) {
 				List<String> list = this.packageToModules.get(pack);
 				return list.toArray(new String[list.size()]);
 			} else {
 				return new String[]{module};
 			}
 		}
-		return JimageUtil.DEFAULT_MODULE;
+		return JRTUtil.DEFAULT_MODULE;
 	}
 
-	public InputStream getContentFromJimage(String fileName, String module) throws IOException {
+	public InputStream getContentFromJrt(String fileName, String module) throws IOException {
 		if (module != null) {
-			return Files.newInputStream(this.jrt.getPath(JimageUtil.MODULES_SUBDIR, module, fileName));
+			return Files.newInputStream(this.jrtSystem.getPath(JRTUtil.MODULES_SUBDIR, module, fileName));
 		}
 		String[] modules = getModules(fileName);
 		for (String mod : modules) {
-			return Files.newInputStream(this.jrt.getPath(JimageUtil.MODULES_SUBDIR, mod, fileName));
+			return Files.newInputStream(this.jrtSystem.getPath(JRTUtil.MODULES_SUBDIR, mod, fileName));
 		}
 		return null;
 	}
@@ -223,7 +224,7 @@
 		String module = null;
 		for (String mod : modules) {
 			try {
-				content = Files.readAllBytes(this.jrt.getPath(JimageUtil.MODULES_SUBDIR, mod, fileName));
+				content = Files.readAllBytes(this.jrtSystem.getPath(JRTUtil.MODULES_SUBDIR, mod, fileName));
 				if (content != null) {
 					module = mod;
 					break;
@@ -246,7 +247,7 @@
 			String[] modules = getModules(fileName);
 			for (String mod : modules) {
 				try {
-					content = Files.readAllBytes(this.jrt.getPath(JimageUtil.MODULES_SUBDIR, mod, fileName));
+					content = Files.readAllBytes(this.jrtSystem.getPath(JRTUtil.MODULES_SUBDIR, mod, fileName));
 					if (content != null) {
 						break;
 					}
@@ -260,7 +261,7 @@
 	private byte[] getClassfile(String fileName, String module) throws IOException, ClassFormatException {
 		byte[] content = null;
 		try {
-			content = Files.readAllBytes(this.jrt.getPath(JimageUtil.MODULES_SUBDIR, module, fileName));
+			content = Files.readAllBytes(this.jrtSystem.getPath(JRTUtil.MODULES_SUBDIR, module, fileName));
 		} catch(NoSuchFileException e) {
 			return null;
 		}
@@ -280,29 +281,29 @@
 		return reader;
 	}
 
-	void walkModuleImage(final JimageUtil.JimageVisitor<java.nio.file.Path> visitor, boolean visitPackageMapping, final int notify) throws IOException {
-		Iterable<java.nio.file.Path> roots = this.jrt.getRootDirectories();
+	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();
 		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(JimageUtil.MODULES_SUBDIR)) {
+					if (subdir.toString().equals(JRTUtil.MODULES_SUBDIR)) {
 						if (visitPackageMapping) continue;
-						Files.walkFileTree(subdir, new JimageUtil.AbstractFileVisitor<java.nio.file.Path>() {
+						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 (!mod.toString().startsWith(JimageUtil.JAVA_DOT) ||
-											(JimageUtil.MODULES_ON_DEMAND != null &&
-											JimageUtil.MODULES_ON_DEMAND.indexOf(mod.toString()) == -1)) {
+									if (!mod.toString().startsWith(JRTUtil.JAVA_DOT) ||
+											(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 & JimageUtil.NOTIFY_MODULES) == 0) ? 
+									return ((notify & JRTUtil.NOTIFY_MODULES) == 0) ? 
 											FileVisitResult.CONTINUE : visitor.visitModule(mod);
 								}
-								if (dir == subdir || count < 3 || (notify & JimageUtil.NOTIFY_PACKAGES) == 0) {
+								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;
 								}
@@ -311,23 +312,23 @@
 
 							@Override
 							public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs) throws IOException {
-								if ((notify & JimageUtil.NOTIFY_FILES) == 0)
+								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(JimageUtil.DEFAULT_PACKAGE, file.getName(1).toString());
+									cachePackage(JRTUtil.DEFAULT_PACKAGE, file.getName(1).toString());
 								}
 								return visitor.visitFile(file.subpath(2, file.getNameCount()), file.getName(1), attrs);
 							}
 						});
 					} else if (visitPackageMapping) {
-						Files.walkFileTree(subdir, new JimageUtil.AbstractFileVisitor<java.nio.file.Path>() {
+						Files.walkFileTree(subdir, new JRTUtil.AbstractFileVisitor<java.nio.file.Path>() {
 							@Override
 							public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs) throws IOException {
 								// e.g. /modules/java.base
 								java.nio.file.Path mod = file.getName(file.getNameCount() - 1);
-								if (!mod.toString().startsWith(JimageUtil.JAVA_DOT)) {
+								if (!mod.toString().startsWith(JRTUtil.JAVA_DOT)) {
 									return FileVisitResult.CONTINUE;
 								}
 								java.nio.file.Path relative = subdir.relativize(file);
@@ -352,21 +353,21 @@
 			this.packageToModule.put(packageName, module);
 		} else if(current == module || current.equals(module)) {
 			return;
-		} else if (current == JimageUtil.MULTIPLE) {
+		} else if (current == JRTUtil.MULTIPLE) {
 			List<String> list = this.packageToModules.get(packageName);
 			if (!list.contains(module)) {
-				if (JimageUtil.JAVA_BASE == module || JimageUtil.JAVA_BASE.equals(module)) {
-					list.add(0, JimageUtil.JAVA_BASE);
+				if (JRTUtil.JAVA_BASE == module || JRTUtil.JAVA_BASE.equals(module)) {
+					list.add(0, JRTUtil.JAVA_BASE);
 				} else {
 					list.add(module);
 				}
 			}
 		} else {
 			String first = (String) current;
-			this.packageToModule.put(packageName, JimageUtil.MULTIPLE);
+			this.packageToModule.put(packageName, JRTUtil.MULTIPLE);
 			List<String> list = new ArrayList<String>();
 			// Just do this as comparator might be overkill
-			if (JimageUtil.JAVA_BASE == current || JimageUtil.JAVA_BASE.equals(current)) {
+			if (JRTUtil.JAVA_BASE == current || JRTUtil.JAVA_BASE.equals(current)) {
 				list.add(first);
 				list.add(module);
 			} else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SuffixConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SuffixConstants.java
index 8ff4a3c..2b45d3e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SuffixConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/SuffixConstants.java
@@ -19,20 +19,14 @@
 	public final static String EXTENSION_CLASS = "CLASS"; //$NON-NLS-1$
 	public final static String EXTENSION_java = "java"; //$NON-NLS-1$
 	public final static String EXTENSION_JAVA = "JAVA"; //$NON-NLS-1$
-	public final static String EXTENSION_jimage = "jimage"; //$NON-NLS-1$
-	public final static String EXTENSION_JIMAGE = "JIMAGE"; //$NON-NLS-1$
 
 	public final static String SUFFIX_STRING_class = "." + EXTENSION_class; //$NON-NLS-1$
 	public final static String SUFFIX_STRING_CLASS = "." + EXTENSION_CLASS; //$NON-NLS-1$
 	public final static String SUFFIX_STRING_java = "." + EXTENSION_java; //$NON-NLS-1$
 	public final static String SUFFIX_STRING_JAVA = "." + EXTENSION_JAVA; //$NON-NLS-1$
-	public final static String SUFFIX_STRING_JIMAGE = "." + EXTENSION_JIMAGE; //$NON-NLS-1$
-	public final static String SUFFIX_STRING_jimage = "." + EXTENSION_jimage; //$NON-NLS-1$
 
 	public final static char[] SUFFIX_class = SUFFIX_STRING_class.toCharArray();
 	public final static char[] SUFFIX_CLASS = SUFFIX_STRING_CLASS.toCharArray();
 	public final static char[] SUFFIX_java = SUFFIX_STRING_java.toCharArray();
 	public final static char[] SUFFIX_JAVA = SUFFIX_STRING_JAVA.toCharArray();
-	public final static char[] SUFFIX_jimage = SUFFIX_STRING_jimage.toCharArray();
-	public final static char[] SUFFIX_JIMAGE = SUFFIX_STRING_JIMAGE.toCharArray();
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
index 455ced0..f023ce7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java
@@ -41,6 +41,7 @@
 import org.eclipse.jdt.internal.compiler.batch.FileSystem;
 import org.eclipse.jdt.internal.compiler.batch.Main;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
@@ -749,8 +750,6 @@
 	
 	public static final int ZIP_FILE = 0;
 	
-	public static final int JIMAGE_FILE = 1;
-	
 	/**
 	 * Returns whether the given name is potentially a zip archive file name
 	 * (it has a file extension and it is not ".java" nor ".class")
@@ -764,16 +763,6 @@
 		int length = name.length();
 		int extensionLength = length - lastDot - 1;
 		
-		if (extensionLength == EXTENSION_jimage.length()) {
-			for (int i = extensionLength-1; i >=0; i--) {
-				if (Character.toLowerCase(name.charAt(length - extensionLength + i)) != EXTENSION_jimage.charAt(i)) {
-					break;
-				}
-				if (i == 0) {
-					return JIMAGE_FILE;
-				}
-			}
-		}
 		if (extensionLength == EXTENSION_java.length()) {
 			for (int i = extensionLength-1; i >=0; i--) {
 				if (Character.toLowerCase(name.charAt(length - extensionLength + i)) != EXTENSION_java.charAt(i)) {
@@ -904,22 +893,11 @@
 	}
 
 	/**
-	 * Returns true iff str.toLowerCase().endsWith(".jimage")
+	 * Returns true iff str.toLowerCase().endsWith("jrt-fs.jar")
 	 * implementation is not creating extra strings.
 	 */
-	public final static boolean isJimageName(String name) {
-		if (name.endsWith(JimageUtil.JRT_FS_JAR))
-			return true;
-		int nameLength = name.length();
-		int suffixLength = SUFFIX_JIMAGE.length;
-		if (nameLength < suffixLength) return false;
-
-		for (int i = 0; i < suffixLength; i++) {
-			char c = name.charAt(nameLength - i - 1);
-			int suffixIndex = suffixLength - i - 1;
-			if (c != SUFFIX_jimage[suffixIndex] && c != SUFFIX_JIMAGE[suffixIndex]) return false;
-		}
-		return true;
+	public final static boolean isJrt(String name) {
+		return name.endsWith(JRTUtil.JRT_FS_JAR);
 	}
 
 	public static void reverseQuickSort(char[][] list, int left, int right) {
@@ -1182,6 +1160,17 @@
 		if (javaversion != null && javaversion.equalsIgnoreCase("1.1.8")) { //$NON-NLS-1$
 			throw new IllegalStateException();
 		}
+		if (javaversion.length() > 3) {
+			long jdkLevel = CompilerOptions.versionToJdkLevel(javaversion.substring(0, 3));
+			if (jdkLevel >= ClassFileConstants.JDK9) {
+				List<String> filePaths = new ArrayList<>();
+				final File javaHome = getJavaHome();
+				if (javaHome != null) {
+					filePaths.add((new File(javaHome, "/" + JRTUtil.JRT_FS_JAR)).getAbsolutePath()); //$NON-NLS-1$
+					return filePaths;
+				}
+			}
+		}
 
 		/*
 		 * Handle >= JDK 1.2.2 settings: retrieve the bootclasspath
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java
index bd5ab82..6cc57c5 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaConventions.java
@@ -413,6 +413,7 @@
 	 * @see JavaCore#VERSION_1_6
 	 * @see JavaCore#VERSION_1_7
 	 * @see JavaCore#VERSION_1_8
+	 * @see JavaCore#VERSION_9
 	 */
 	public static IStatus validateJavaTypeName(String name, String sourceLevel, String complianceLevel) {
 		if (name == null) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
index 7f1e466..b141aa1 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
@@ -5771,8 +5771,8 @@
 				break;
 			case ClassFileConstants.MAJOR_VERSION_9:
 				options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_9);
-				options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8); //TODO(BETA_JAVA9) at the moment, there's no new Java language feature
-				options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8); //TODO(BETA_JAVA9) at the moment, runtime doesn't support a new class file version
+				options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_9);
+				options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_9);
 				options.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR);
 				options.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR);
 				options.put(JavaCore.COMPILER_CODEGEN_INLINE_JSR_BYTECODE, JavaCore.ENABLED);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
index 3a2c522..97ad67c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
@@ -353,9 +353,9 @@
 private byte[] getClassFileContent(JarPackageFragmentRoot root, String className) throws CoreException, IOException {
 	byte[] contents = null;
 	String rootPath = root.getPath().toOSString();
-	if (org.eclipse.jdt.internal.compiler.util.Util.isJimageName(rootPath)) {
+	if (org.eclipse.jdt.internal.compiler.util.Util.isJrt(rootPath)) {
 			try {
-				contents = org.eclipse.jdt.internal.compiler.util.JimageUtil.getClassfileContent(
+				contents = org.eclipse.jdt.internal.compiler.util.JRTUtil.getClassfileContent(
 						new File(rootPath),
 						className,
 						root.getElementName());
@@ -384,7 +384,7 @@
 		if (contents != null) {
 			String fileName;
 			String rootPath = root.getPath().toOSString();
-			if (org.eclipse.jdt.internal.compiler.util.Util.isJimageName(rootPath)) {
+			if (org.eclipse.jdt.internal.compiler.util.Util.isJrt(rootPath)) {
 				fileName = root.getHandleIdentifier() + IDependent.JAR_FILE_ENTRY_SEPARATOR + 
 						root.getElementName() + IDependent.JAR_FILE_ENTRY_SEPARATOR + entryName;
 			} else {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java
index dadf413..62669aa 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarEntryFile.java
@@ -28,7 +28,7 @@
 import org.eclipse.jdt.core.IJavaModelStatusConstants;
 import org.eclipse.jdt.core.IPackageFragmentRoot;
 import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.internal.compiler.util.JimageUtil;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 import org.eclipse.jdt.internal.compiler.util.Util;
 
 /**
@@ -50,12 +50,12 @@
 
 	public InputStream getContents() throws CoreException {
 		IPackageFragmentRoot root = getPackageFragmentRoot();
-		if (Util.isJimageName(root.getPath().toOSString())) {
+		if (Util.isJrt(root.getPath().toOSString())) {
 			try {
 				IPath rootPath = root.getPath();
 				Object target = JavaModel.getTarget(rootPath, false);
 				if (target != null && target instanceof File) {
-					return JimageUtil.getContentFromJimage((File) target, getEntryName(), root.getElementName());
+					return JRTUtil.getContentFromJrt((File) target, getEntryName(), root.getElementName());
 				}
 			} catch (IOException e) {
 				throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java
index 8f50572..e970f65 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java
@@ -1,10 +1,14 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Terry Parker <tparker@google.com> - [performance] Low hit rates in JavaModel caches - https://bugs.eclipse.org/421165
@@ -362,7 +366,7 @@
 }
 
 public static boolean isJimage(File file) {
-	return JavaModelManager.isJimage(file.getPath());
+	return JavaModelManager.isJrt(file.getPath());
 }
 
 /**
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
index 05dcfb8..a4c26c8 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
@@ -128,7 +128,7 @@
 import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt;
-import org.eclipse.jdt.internal.compiler.util.JimageUtil;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 import org.eclipse.jdt.internal.compiler.util.ObjectVector;
 import org.eclipse.jdt.internal.core.JavaProjectElementInfo.ProjectCache;
 import org.eclipse.jdt.internal.core.builder.JavaBuilder;
@@ -316,8 +316,6 @@
 	 */
 	public static final String MAX_COMPILED_UNITS_AT_ONCE = "maxCompiledUnitsAtOnce"; //$NON-NLS-1$
 
-	public static final String JIMAGE_EXT = "jimage"; //$NON-NLS-1$
-
 	/**
 	 * Special value used for recognizing ongoing initialization and breaking initialization cycles
 	 */
@@ -1229,7 +1227,7 @@
 		public Map rootPathToRawEntries; // reverse map from a package fragment root's path to the raw entry
 		public Map rootPathToResolvedEntries; // map from a package fragment root's path to the resolved entry
 		public IPath outputLocation;
-		public Map<IPath, ObjectVector> jimageRoots; // A map between a Jimage classpath entry (as a string) and the package fragment roots found in it.
+		public Map<IPath, ObjectVector> jrtRoots; // A map between a JRT file system (as a string) and the package fragment roots found in it.
 
 		public IEclipsePreferences preferences;
 		public Hashtable options;
@@ -1339,9 +1337,9 @@
 			return setClasspath(this.rawClasspath, referencedEntries, this.outputLocation, this.rawClasspathStatus, newResolvedClasspath, newRootPathToRawEntries, newRootPathToResolvedEntries, newUnresolvedEntryStatus, addClasspathChange);
 		}
 
-		public synchronized void setJimagePackageRoots(IPath jimagePath, ObjectVector roots) {
-			if (this.jimageRoots == null) this.jimageRoots = new HashMap<>();
-			this.jimageRoots.put(jimagePath, roots);
+		public synchronized void setJrtPackageRoots(IPath jrtPath, ObjectVector roots) {
+			if (this.jrtRoots == null) this.jrtRoots = new HashMap<>();
+			this.jrtRoots.put(jrtPath, roots);
 		}
 
 		/**
@@ -1526,7 +1524,7 @@
 	public static boolean CP_RESOLVE_VERBOSE_ADVANCED = false;
 	public static boolean CP_RESOLVE_VERBOSE_FAILURE = false;
 	public static boolean ZIP_ACCESS_VERBOSE = false;
-	public static boolean JIMAGE_ACCESS_VERBOSE = false;
+	public static boolean JRT_ACCESS_VERBOSE = false;
 	
 	/**
 	 * A cache of opened zip files per thread.
@@ -2711,23 +2709,17 @@
 		return this.workspaceScope;
 	}
 
-	public static boolean isJimage(IPath path) {
-		if (path.getFileExtension() != null && path.getFileExtension().equalsIgnoreCase(JIMAGE_EXT)) {
-			return true;
-		}
-		if (path.toString().endsWith(JimageUtil.JRT_FS_JAR)) {
-			return true;
-		}
-		return false;
+	public static boolean isJrt(IPath path) {
+		return path.toString().endsWith(JRTUtil.JRT_FS_JAR);
 	}
 
-	public static boolean isJimage(String path) {
-		return isJimage(new Path(path));
+	public static boolean isJrt(String path) {
+		return isJrt(new Path(path));
 	}
 
 	public void verifyArchiveContent(IPath path) throws CoreException {
-		// TODO: We don't yet know how to open a jimage file given its path. So, simply don't attempt.
-		if (isJimage(path)) {
+		// TODO: we haven't finalized what path the JRT is represented by. Don't attempt to validate it.
+		if (isJrt(path)) {
 			return;
 		}
 		if (isInvalidArchive(path)) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
index 41e868f..0c3fc33 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
@@ -75,7 +75,7 @@
 import org.eclipse.jdt.core.compiler.CategorizedProblem;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.eval.IEvaluationContext;
-import org.eclipse.jdt.internal.compiler.util.JimageUtil;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 import org.eclipse.jdt.internal.compiler.util.ObjectVector;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo;
@@ -625,14 +625,14 @@
 					if (JavaModel.isFile(target)) {
 						if (JavaModel.isJimage((File) target)) {
 							PerProjectInfo info = getPerProjectInfo();
-							if (info.jimageRoots == null || !info.jimageRoots.containsKey(entryPath)) {
+							if (info.jrtRoots == null || !info.jrtRoots.containsKey(entryPath)) {
 								ObjectVector imageRoots = new ObjectVector();
 								loadModulesInJimage(entryPath, imageRoots, rootToResolvedEntries, resolvedEntry, referringEntry);
-								info.setJimagePackageRoots(entryPath, imageRoots);
+								info.setJrtPackageRoots(entryPath, imageRoots);
 								accumulatedRoots.addAll(imageRoots);
 								rootIDs.add(rootID);
 							} else {
-								accumulatedRoots.addAll(info.jimageRoots.get(entryPath));
+								accumulatedRoots.addAll(info.jrtRoots.get(entryPath));
 							}
 						} else {
 							root = new JarPackageFragmentRoot(entryPath, this);
@@ -687,8 +687,8 @@
 			return getPackageFragment(pkgName, null);
 		}
 		public PackageFragment getPackageFragment(String[] pkgName, String mod) {
-			PackageFragmentRoot realRoot = new ModulePackageFragmentRoot(this.jarPath,
-												mod == null ?  JimageUtil.JAVA_BASE : mod,
+			PackageFragmentRoot realRoot = new JrtPackageFragmentRoot(this.jarPath,
+												mod == null ?  JRTUtil.JAVA_BASE : mod,
 														JavaProject.this);
 			return new JarPackageFragment(realRoot, pkgName);
 		}
@@ -704,8 +704,8 @@
 	private void loadModulesInJimage(final IPath imagePath, final ObjectVector roots, final Map rootToResolvedEntries, 
 				final IClasspathEntry resolvedEntry, final IClasspathEntry referringEntry) {
 		try {
-			org.eclipse.jdt.internal.compiler.util.JimageUtil.walkModuleImage(imagePath.toFile(),
-					new org.eclipse.jdt.internal.compiler.util.JimageUtil.JimageVisitor<java.nio.file.Path>() {
+			org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(imagePath.toFile(),
+					new org.eclipse.jdt.internal.compiler.util.JRTUtil.JrtFileVisitor<java.nio.file.Path>() {
 				@Override
 				public FileVisitResult visitPackage(java.nio.file.Path dir, java.nio.file.Path mod, BasicFileAttributes attrs) throws IOException {
 					return FileVisitResult.SKIP_SIBLINGS;
@@ -718,13 +718,13 @@
 
 				@Override
 				public FileVisitResult visitModule(java.nio.file.Path mod) throws IOException {
-					ModulePackageFragmentRoot root = new ModulePackageFragmentRoot(imagePath, mod.toString(), JavaProject.this);
+					JrtPackageFragmentRoot root = new JrtPackageFragmentRoot(imagePath, mod.toString(), JavaProject.this);
 					roots.add(root);
 					if (rootToResolvedEntries != null) 
 						rootToResolvedEntries.put(root, ((ClasspathEntry)resolvedEntry).combineWith((ClasspathEntry) referringEntry));
 					return FileVisitResult.SKIP_SUBTREE;
 				}
-			}, JimageUtil.NOTIFY_MODULES);
+			}, JRTUtil.NOTIFY_MODULES);
 		} catch (IOException e) {
 			Util.log(IStatus.ERROR, "Error reading modules from " + imagePath.toOSString()); //$NON-NLS-1$
 		}
@@ -1689,7 +1689,7 @@
 				}
 				JavaElement root = (mod == null) ?
 						(JavaElement)getPackageFragmentRoot(new Path(rootPath)) :
-							new ModulePackageFragmentRoot(new Path(rootPath), mod, this);
+							new JrtPackageFragmentRoot(new Path(rootPath), mod, this);
 				if (token != null && (token.charAt(0) == JEM_PACKAGEFRAGMENT)) {
 					return root.getHandleFromMemento(token, memento, owner);
 				} else {
@@ -1922,7 +1922,7 @@
 		IFolder linkedFolder = JavaModelManager.getExternalManager().getFolder(externalLibraryPath);
 		if (linkedFolder != null)
 			return new ExternalPackageFragmentRoot(linkedFolder, externalLibraryPath, this);
-		if (JavaModelManager.isJimage(externalLibraryPath)) {
+		if (JavaModelManager.isJrt(externalLibraryPath)) {
 			return this.new JImageModuleFragmentBridge(externalLibraryPath);
 		}
 		return new JarPackageFragmentRoot(externalLibraryPath, this);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModulePackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java
similarity index 84%
rename from org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModulePackageFragmentRoot.java
rename to org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java
index 9a11b9a..9404a26 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModulePackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java
@@ -26,26 +26,26 @@
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
-import org.eclipse.jdt.internal.compiler.util.JimageUtil;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject;
 import org.eclipse.jdt.internal.core.util.Util;
 
 /**
- * A package fragment root that corresponds to a .jimage
+ * A package fragment root that corresponds to a module in a JRT file system.
  *
  * @see org.eclipse.jdt.core.IPackageFragmentRoot
  * @see org.eclipse.jdt.internal.core.JarPackageFragmentRootInfo
  */
-public class ModulePackageFragmentRoot extends JarPackageFragmentRoot {
+public class JrtPackageFragmentRoot extends JarPackageFragmentRoot {
 
 	String moduleName;
 	
 	/**
 	 * Constructs a package fragment root which represents a module
-	 * contained in a Jimage.
+	 * contained in a JRT.
 	 */
-	protected ModulePackageFragmentRoot(IPath jimagePath, String moduleName, JavaProject project) {
-		super(jimagePath, project);
+	protected JrtPackageFragmentRoot(IPath jrtPath, String moduleName, JavaProject project) {
+		super(jrtPath, project);
 		this.moduleName = moduleName;
 	}
 
@@ -57,8 +57,8 @@
 		rawPackageInfo.put(CharOperation.NO_STRINGS, new ArrayList[] { EMPTY_LIST, EMPTY_LIST });
 
 		try {
-			org.eclipse.jdt.internal.compiler.util.JimageUtil.walkModuleImage(this.jarPath.toFile(),
-					new org.eclipse.jdt.internal.compiler.util.JimageUtil.JimageVisitor<Path>() {
+			org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(this.jarPath.toFile(),
+					new org.eclipse.jdt.internal.compiler.util.JRTUtil.JrtFileVisitor<Path>() {
 				@Override
 				public FileVisitResult visitPackage(Path dir, Path mod, BasicFileAttributes attrs) throws IOException {
 					initRawPackageInfo(rawPackageInfo, dir.toString(), true, compliance);
@@ -73,12 +73,12 @@
 
 				@Override
 				public FileVisitResult visitModule(Path mod) throws IOException {
-					if (!ModulePackageFragmentRoot.this.moduleName.equals(mod.toString())) {
+					if (!JrtPackageFragmentRoot.this.moduleName.equals(mod.toString())) {
 						return FileVisitResult.SKIP_SUBTREE;
 					}
 					return FileVisitResult.CONTINUE;
 				}
-			}, JimageUtil.NOTIFY_ALL);
+			}, JRTUtil.NOTIFY_ALL);
 		} catch (IOException e) {
 			Util.log(IStatus.ERROR, "Error reading modules" + toStringWithAncestors()); //$NON-NLS-1$
 		}
@@ -90,8 +90,8 @@
 	public boolean equals(Object o) {
 		if (this == o)
 			return true;
-		if (o instanceof ModulePackageFragmentRoot) {
-			ModulePackageFragmentRoot other= (ModulePackageFragmentRoot) o;
+		if (o instanceof JrtPackageFragmentRoot) {
+			JrtPackageFragmentRoot other= (JrtPackageFragmentRoot) o;
 			return this.moduleName.equals(other.moduleName) &&
 					this.jarPath.equals(other.jarPath);
 		}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
index 700297f..facfda0 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
@@ -489,7 +489,7 @@
 	((JavaElement)getParent()).getHandleMemento(buff);
 	buff.append(getHandleMementoDelimiter());
 	escapeMementoName(buff, path.toString());
-	if (org.eclipse.jdt.internal.compiler.util.Util.isJimageName(path.toOSString())) {
+	if (org.eclipse.jdt.internal.compiler.util.Util.isJrt(path.toOSString())) {
 		buff.append(getHandleMementoDelimiter());
 		escapeMementoName(buff, getElementName());
 	}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
index 26da118..8eab38a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
@@ -66,7 +66,7 @@
 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
-import org.eclipse.jdt.internal.compiler.util.JimageUtil;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.compiler.util.Util;
 import org.eclipse.jdt.internal.core.util.ReferenceInfoAdapter;
@@ -460,7 +460,7 @@
 		return -1;
 	}
 
-	class JimagePackageNamesAdderVisitor implements JimageUtil.JimageVisitor<java.nio.file.Path> {
+	class JrtPackageNamesAdderVisitor implements JRTUtil.JrtFileVisitor<java.nio.file.Path> {
 
 		public final HashSet firstLevelPackageNames;
 		final IPackageFragmentRoot root;
@@ -469,7 +469,7 @@
 		public boolean containsADefaultPackage;
 		public boolean containsJavaSource;
 
-		JimagePackageNamesAdderVisitor(HashSet firstLevelPackageNames, String sourceLevel, String complianceLevel,
+		JrtPackageNamesAdderVisitor(HashSet firstLevelPackageNames, String sourceLevel, String complianceLevel,
 				boolean containsADefaultPackage, boolean containsJavaSource, IPackageFragmentRoot root) {
 			this.firstLevelPackageNames = firstLevelPackageNames;
 			this.root = root;
@@ -534,17 +534,20 @@
 
 		String sourceLevel = null;
 		String complianceLevel = null;
-		if (Util.isJimageName(pkgFragmentRootPath.toOSString())) {
+		if (Util.isJrt(pkgFragmentRootPath.toOSString())) {
 			try {
-				JimagePackageNamesAdderVisitor jimagePackageNamesAdderVisitor = new JimagePackageNamesAdderVisitor(firstLevelPackageNames, 
+				JrtPackageNamesAdderVisitor jrtPackageNamesAdderVisitor = new JrtPackageNamesAdderVisitor(firstLevelPackageNames, 
 						sourceLevel, complianceLevel, containsADefaultPackage, containsJavaSource, root);
-				org.eclipse.jdt.internal.compiler.util.JimageUtil.walkModuleImage(root.getPath().toFile(), jimagePackageNamesAdderVisitor, JimageUtil.NOTIFY_FILES);
-				sourceLevel = jimagePackageNamesAdderVisitor.sourceLevel;
-				complianceLevel = jimagePackageNamesAdderVisitor.complianceLevel;
-				containsADefaultPackage = jimagePackageNamesAdderVisitor.containsADefaultPackage;
-				containsJavaSource = jimagePackageNamesAdderVisitor.containsJavaSource;
+				org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(root.getPath().toFile(), jrtPackageNamesAdderVisitor, JRTUtil.NOTIFY_FILES);
+				sourceLevel = jrtPackageNamesAdderVisitor.sourceLevel;
+				complianceLevel = jrtPackageNamesAdderVisitor.complianceLevel;
+				containsADefaultPackage = jrtPackageNamesAdderVisitor.containsADefaultPackage;
+				containsJavaSource = jrtPackageNamesAdderVisitor.containsJavaSource;
 			} catch (IOException e) {
-				// We are not reading any specific Jimage file, so, move on for now
+				// We are not reading any specific file, so, move on for now
+				if (VERBOSE) {
+					e.printStackTrace();
+				}
 			}
 		} else if (root.isArchive()) {
 			JavaModelManager manager = JavaModelManager.getJavaModelManager();
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJimage.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java
similarity index 85%
rename from org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJimage.java
rename to org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java
index 381b5c2..cea35c7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJimage.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java
@@ -32,11 +32,11 @@
 import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
 import org.eclipse.jdt.internal.compiler.lookup.ModuleEnvironment;
-import org.eclipse.jdt.internal.compiler.util.JimageUtil;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 import org.eclipse.jdt.internal.compiler.util.SimpleSet;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 
-public class ClasspathJimage extends ClasspathLocation {
+public class ClasspathJrt extends ClasspathLocation {
 
 private HashMap<String, SimpleSet> packagesInModule = null;
 private static HashMap<String, HashMap<String, SimpleSet>> PackageCache = new HashMap<>();
@@ -45,7 +45,7 @@
 private String externalAnnotationPath;
 private ZipFile annotationZipFile;
 String zipFilename; // keep for equals
-public ClasspathJimage(String zipFilename, IPath externalAnnotationPath, INameEnvironment env) {
+public ClasspathJrt(String zipFilename, IPath externalAnnotationPath, INameEnvironment env) {
 	this.zipFilename = zipFilename;
 	this.env = env;
 	if (externalAnnotationPath != null)
@@ -54,11 +54,11 @@
 }
 /**
  * Calculate and cache the package list available in the zipFile.
- * @param jimage The ClasspathJar to use
+ * @param jrt The ClasspathJar to use
  * @return A SimpleSet with the all the package names in the zipFile.
  */
-static HashMap<String, SimpleSet> findPackagesInModules(final ClasspathJimage jimage) {
-	String zipFileName = jimage.zipFilename;
+static HashMap<String, SimpleSet> findPackagesInModules(final ClasspathJrt jrt) {
+	String zipFileName = jrt.zipFilename;
 	HashMap<String, SimpleSet> cache = PackageCache.get(zipFileName);
 	if (cache != null) {
 		return cache;
@@ -67,8 +67,8 @@
 	PackageCache.put(zipFileName, packagesInModule);
 	try {
 		final File imageFile = new File(zipFileName);
-		org.eclipse.jdt.internal.compiler.util.JimageUtil.walkModuleImage(imageFile, 
-				new org.eclipse.jdt.internal.compiler.util.JimageUtil.JimageVisitor<Path>() {
+		org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(imageFile, 
+				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 {
@@ -85,7 +85,7 @@
 			public FileVisitResult visitModule(Path mod) throws IOException {
 				String name = mod.toString();
 				try {
-					jimage.acceptModule(JimageUtil.getClassfileContent(imageFile, MODULE_INFO_CLASS, name));
+					jrt.acceptModule(JRTUtil.getClassfileContent(imageFile, MODULE_INFO_CLASS, name));
 				} catch (ClassFormatException e) {
 					e.printStackTrace();
 				}
@@ -94,22 +94,22 @@
 				packagesInModule.put(name, this.packageSet);
 				return FileVisitResult.CONTINUE;
 			}
-		}, JimageUtil.NOTIFY_PACKAGES | JimageUtil.NOTIFY_MODULES);
+		}, JRTUtil.NOTIFY_PACKAGES | JRTUtil.NOTIFY_MODULES);
 	} catch (IOException e) {
 		// TODO: BETA_JAVA9 Should report better
 	}
 	return packagesInModule;
 }
 
-public static void loadModules(final ClasspathJimage jimage) {
-	String zipFileName = jimage.zipFilename;
+public static void loadModules(final ClasspathJrt jrt) {
+	String zipFileName = jrt.zipFilename;
 	Set<IModule> cache = ModulesCache.get(zipFileName);
 
 	if (cache == null) {
 		try {
 			final File imageFile = new File(zipFileName);
-			org.eclipse.jdt.internal.compiler.util.JimageUtil.walkModuleImage(imageFile,
-					new org.eclipse.jdt.internal.compiler.util.JimageUtil.JimageVisitor<Path>() {
+			org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(imageFile,
+					new org.eclipse.jdt.internal.compiler.util.JRTUtil.JrtFileVisitor<Path>() {
 				SimpleSet packageSet = null;
 
 				@Override
@@ -128,13 +128,13 @@
 				@Override
 				public FileVisitResult visitModule(Path mod) throws IOException {
 					try {
-						jimage.acceptModule(JimageUtil.getClassfileContent(imageFile, MODULE_INFO_CLASS, mod.toString()));
+						jrt.acceptModule(JRTUtil.getClassfileContent(imageFile, MODULE_INFO_CLASS, mod.toString()));
 					} catch (ClassFormatException e) {
 						e.printStackTrace();
 					}
 					return FileVisitResult.SKIP_SUBTREE;
 				}
-			}, JimageUtil.NOTIFY_MODULES);
+			}, JRTUtil.NOTIFY_MODULES);
 		} catch (IOException e) {
 			// TODO: BETA_JAVA9 Should report better
 		}
@@ -177,8 +177,8 @@
 
 public boolean equals(Object o) {
 	if (this == o) return true;
-	if (!(o instanceof ClasspathJimage)) return false;
-	ClasspathJimage jar = (ClasspathJimage) o;
+	if (!(o instanceof ClasspathJrt)) return false;
+	ClasspathJrt jar = (ClasspathJrt) o;
 	return this.zipFilename.endsWith(jar.zipFilename);
 }
 
@@ -189,7 +189,7 @@
 	if (!isPackage(qualifiedPackageName)) return null; // most common case
 
 	try {
-		ClassFileReader reader = ClassFileReader.readFromJimage(new File(this.zipFilename), qualifiedBinaryFileName, mod);
+		ClassFileReader reader = ClassFileReader.readFromJrt(new File(this.zipFilename), qualifiedBinaryFileName, mod);
 		if (reader != null) {
 			if (this.externalAnnotationPath != null) {
 				String fileNameWithoutExtension = qualifiedBinaryFileName.substring(0, qualifiedBinaryFileName.length() - SuffixConstants.SUFFIX_CLASS.length);
@@ -235,7 +235,7 @@
 }
 
 public String toString() {
-	String start = "Classpath Jimage file " + this.zipFilename; //$NON-NLS-1$
+	String start = "Classpath jrt file " + this.zipFilename; //$NON-NLS-1$
 	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 d74ff82..ab1e17b 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
@@ -44,8 +44,8 @@
 										AccessRuleSet accessRuleSet, 
 										IPath annotationsPath,
 										INameEnvironment env) {
-	return Util.isJimageName(libraryPathname) ?
-			new ClasspathJimage(libraryPathname, annotationsPath, env) :
+	return Util.isJrt(libraryPathname) ?
+			new ClasspathJrt(libraryPathname, annotationsPath, env) :
 			new ClasspathJar(libraryPathname, lastModified, accessRuleSet, annotationsPath, env);
 }
 
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 2f60483..09ae30e 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
@@ -475,9 +475,9 @@
 			writeRestriction(jar.accessRuleSet, out);
 			out.writeUTF(jar.externalAnnotationPath != null ? jar.externalAnnotationPath : ""); //$NON-NLS-1$
 		} else {
-			ClasspathJimage jimage = (ClasspathJimage) c;
+			ClasspathJrt jrt = (ClasspathJrt) c;
 			out.writeByte(EXTERNAL_JAR);
-			out.writeUTF(jimage.zipFilename);
+			out.writeUTF(jrt.zipFilename);
 			out.writeLong(-1);
 			writeRestriction(null, out);
 			out.writeUTF(""); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
index 7cc9499..ab121e3 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -978,9 +978,9 @@
 				versionNumber = JavaCore.VERSION_1_7;
 			} else if (minorVersion == 0 && majorVersion == 52) {
 				versionNumber = JavaCore.VERSION_1_8;
-			}/* else if (minorVersion == 0 && majorVersion == 53) {
-				versionNumber = JavaCore.VERSION_1_9;
-			} No runtime yet supports major version 53, hence commenting out for now */
+			} else if (minorVersion == 0 && majorVersion == 53) {
+				versionNumber = JavaCore.VERSION_9;
+			}
 			buffer.append(
 				Messages.bind(Messages.classfileformat_versiondetails,
 				new String[] {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java
index 061eccc..86d4a14 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java
@@ -100,7 +100,7 @@
 			// create handle
 			String module = null;
 			String rootPath = this.lastPkgFragmentRoot.getPath().toOSString();
-			if (org.eclipse.jdt.internal.compiler.util.Util.isJimageName(rootPath)) {
+			if (org.eclipse.jdt.internal.compiler.util.Util.isJrt(rootPath)) {
 				module = resourcePath.substring(separatorIndex + 1, 
 						(separatorIndex = resourcePath.lastIndexOf(IJavaSearchScope.JAR_FILE_ENTRY_SEPARATOR)));
 			}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
index 7376220..8bfa2aa 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
@@ -850,7 +850,7 @@
 						}
 					}
 					if (path != null) {
-						if (JavaModelManager.isJimage(path)) {
+						if (JavaModelManager.isJrt(path)) {
 							return ClassFileConstants.JDK9;
 						} else {
 							jar = JavaModelManager.getJavaModelManager().getZipFile(path);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJimageFileToIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java
similarity index 85%
rename from org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJimageFileToIndex.java
rename to org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java
index 798933f..de2f5d5 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJimageFileToIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2015 IBM Corporation and others.
+ * Copyright (c) 2016 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -33,7 +33,7 @@
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
 import org.eclipse.jdt.internal.compiler.parser.Scanner;
 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
-import org.eclipse.jdt.internal.compiler.util.JimageUtil;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.compiler.util.Util;
@@ -43,7 +43,7 @@
 import org.eclipse.jdt.internal.core.search.JavaSearchDocument;
 import org.eclipse.jdt.internal.core.search.processing.JobManager;
 
-public class AddJimageFileToIndex extends IndexRequest {
+public class AddJrtToIndex extends IndexRequest {
 
 	IFile resource;
 	Scanner scanner;
@@ -56,31 +56,24 @@
 		DELETED
 	}
 
-
-	public AddJimageFileToIndex(IFile resource, IndexLocation indexFile, IndexManager manager) {
-		this(resource, indexFile, manager, false);
-	}
-	public AddJimageFileToIndex(IFile resource, IndexLocation indexFile, IndexManager manager, final boolean updateIndex) {
+	public AddJrtToIndex(IFile resource, IndexLocation indexFile, IndexManager manager, final boolean updateIndex) {
 		super(resource.getFullPath(), manager);
 		this.resource = resource;
 		this.indexFileURL = indexFile;
 		this.forceIndexUpdate = updateIndex;
 	}
-	public AddJimageFileToIndex(IPath jimagePath, IndexLocation indexFile, IndexManager manager) {
-		this(jimagePath, indexFile, manager, false);
-	}
-	public AddJimageFileToIndex(IPath jimagePath, IndexLocation indexFile, IndexManager manager, final boolean updateIndex) {
+	public AddJrtToIndex(IPath jrtPath, IndexLocation indexFile, IndexManager manager, final boolean updateIndex) {
 		// external JAR scenario - no resource
-		super(jimagePath, manager);
+		super(jrtPath, manager);
 		this.indexFileURL = indexFile;
 		this.forceIndexUpdate = updateIndex;
 	}
 	public boolean equals(Object o) {
-		if (o instanceof AddJimageFileToIndex) {
+		if (o instanceof AddJrtToIndex) {
 			if (this.resource != null)
-				return this.resource.equals(((AddJimageFileToIndex) o).resource);
+				return this.resource.equals(((AddJrtToIndex) o).resource);
 			if (this.containerPath != null)
-				return this.containerPath.equals(((AddJimageFileToIndex) o).containerPath);
+				return this.containerPath.equals(((AddJrtToIndex) o).containerPath);
 		}
 		return false;
 	}
@@ -92,12 +85,12 @@
 		return -1;
 	}
 	
-	private class JimageTraverser implements org.eclipse.jdt.internal.compiler.util.JimageUtil.JimageVisitor<java.nio.file.Path> {
+	private class JrtTraverser implements org.eclipse.jdt.internal.compiler.util.JRTUtil.JrtFileVisitor<java.nio.file.Path> {
 		
 		SimpleLookupTable indexedFileNames;
-		public JimageTraverser() {
+		public JrtTraverser() {
 		}
-		public JimageTraverser(SimpleLookupTable indexedFileNames) {
+		public JrtTraverser(SimpleLookupTable indexedFileNames) {
 			this.indexedFileNames = indexedFileNames;
 		}
 
@@ -123,16 +116,16 @@
 		}
 	}
 	
-	private class JimageIndexer extends JimageTraverser {
+	private class JrtIndexer extends JrtTraverser {
 		final SearchParticipant participant;
 		final IPath indexPath;
 		final IndexManager indexManager;
 		final IPath container;
 		final Index index;
-		final File jimage;
+		final File jrt;
 
-		public JimageIndexer(File jimage, SearchParticipant participant, Index index, IPath container, IndexManager indexManager) {
-			this.jimage = jimage;
+		public JrtIndexer(File jrt, SearchParticipant participant, Index index, IPath container, IndexManager indexManager) {
+			this.jrt = jrt;
 			this.participant = (participant != null) ? participant : SearchEngine.getDefaultSearchParticipant();
 			this.index = index;
 			IndexLocation indexLocation = index.getIndexLocation();
@@ -149,7 +142,7 @@
 				try {
 					String fullPath = path.toString();
 					byte[] classFileBytes;
-					classFileBytes = JimageUtil.getClassfileContent(this.jimage, fullPath, mod.toString());
+					classFileBytes = JRTUtil.getClassfileContent(this.jrt, fullPath, mod.toString());
 					String docFullPath =  this.container.toString() + JAR_SEPARATOR + mod.toString() + JAR_SEPARATOR + fullPath;
 					JavaSearchDocument entryDocument = new JavaSearchDocument(docFullPath, classFileBytes, this.participant);
 					this.indexManager.indexDocument(entryDocument, this.participant, this.index, this.indexPath);
@@ -201,8 +194,8 @@
 				if (this.resource != null) {
 					URI location = this.resource.getLocationURI();
 					if (location == null) return false;
-					if (JavaModelManager.JIMAGE_ACCESS_VERBOSE)
-						System.out.println("(" + Thread.currentThread() + ") [AddJimageFileToIndex.execute()] Creating ZipFile on " + location.getPath()); //$NON-NLS-1$	//$NON-NLS-2$
+					if (JavaModelManager.JRT_ACCESS_VERBOSE)
+						System.out.println("(" + Thread.currentThread() + ") [AddJrtFileToIndex.execute()] Creating ZipFile on " + location.getPath()); //$NON-NLS-1$	//$NON-NLS-2$
 					File file = null;
 					try {
 						file = org.eclipse.jdt.internal.core.util.Util.toLocalFile(location, progressMonitor);
@@ -234,7 +227,7 @@
 				if (paths != null) {
 					int max = paths.length;
 					/* check integrity of the existing index file
-					 * if the length is equal to 0, we want to index the whole jimage again
+					 * if the length is equal to 0, we want to index the whole jrt again
 					 * If not, then we want to check that there is no missing entry, if
 					 * one entry is missing then we recreate the index
 					 */
@@ -243,8 +236,8 @@
 					for (int i = 0; i < max; i++)
 						indexedFileNames.put(paths[i], FILE_INDEX_STATE.DELETED);
 					
-					org.eclipse.jdt.internal.compiler.util.JimageUtil.walkModuleImage(new File(fileName), 
-							new JimageTraverser(indexedFileNames), JimageUtil.NOTIFY_FILES);
+					org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(new File(fileName), 
+							new JrtTraverser(indexedFileNames), JRTUtil.NOTIFY_FILES);
 
 					boolean needToReindex = indexedFileNames.elementSize != max; // a new file was added
 					if (!needToReindex) {
@@ -266,7 +259,7 @@
 					}
 				}
 
-				// Index the jimage for the first time or reindex the jimage in case the previous index file has been corrupted
+				// Index the jrt for the first time or reindex the jrt in case the previous index file has been corrupted
 				// index already existed: recreate it so that we forget about previous entries
 				if (!this.manager.resetIndex(this.containerPath)) {
 					// failed to recreate index, see 73330
@@ -274,9 +267,9 @@
 					return false;
 				}
 				
-				File jimage = new File(fileName);
-				org.eclipse.jdt.internal.compiler.util.JimageUtil.walkModuleImage(jimage, 
-						new JimageIndexer(jimage, SearchEngine.getDefaultSearchParticipant(), index, container, this.manager), JimageUtil.NOTIFY_FILES);
+				File jrt = new File(fileName);
+				org.eclipse.jdt.internal.compiler.util.JRTUtil.walkModuleImage(jrt, 
+						new JrtIndexer(jrt, SearchEngine.getDefaultSearchParticipant(), index, container, this.manager), JRTUtil.NOTIFY_FILES);
 
 				if(this.forceIndexUpdate) {
 					this.manager.savePreBuiltIndex(index);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
index 5773d8b..779ad2c 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -31,9 +31,9 @@
 import org.eclipse.jdt.internal.compiler.SourceElementParser;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+import org.eclipse.jdt.internal.compiler.util.JRTUtil;
 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
 import org.eclipse.jdt.internal.compiler.util.SimpleSet;
-import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
 import org.eclipse.jdt.internal.core.*;
 import org.eclipse.jdt.internal.core.index.*;
 import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
@@ -559,13 +559,12 @@
 }
 
 private IndexRequest getRequest(Object target, IPath jPath, IndexLocation indexFile, IndexManager manager, boolean updateIndex) {
-	return isJimage(((File) target).getName()) ? new AddJimageFileToIndex(jPath, indexFile, this, updateIndex) :
+	return isJrt(((File) target).getName()) ? new AddJrtToIndex(jPath, indexFile, this, updateIndex) :
 		new AddJarFileToIndex(jPath, indexFile, this, updateIndex);
 }
 
-private boolean isJimage(String fileName) {
-	return fileName != null && 
-			fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length()).equals(SuffixConstants.EXTENSION_jimage);
+private boolean isJrt(String fileName) {
+	return fileName != null && fileName.endsWith(JRTUtil.JRT_FS_JAR);
 }
 /**
  * Trigger addition of a library to an index
@@ -593,8 +592,8 @@
 	IndexRequest request = null;
 	Object target = JavaModel.getTarget(path, true);
 	if (target instanceof IFile) {
-		request = isJimage(((IFile) target).getFullPath().toOSString()) ? 
-				new AddJimageFileToIndex((IFile) target, indexFile, this, forceIndexUpdate) :
+		request = isJrt(((IFile) target).getFullPath().toOSString()) ? 
+				new AddJrtToIndex((IFile) target, indexFile, this, forceIndexUpdate) :
 					new AddJarFileToIndex((IFile) target, indexFile, this, forceIndexUpdate);
 	} else if (target instanceof File) {
 		request = getRequest(target, path, indexFile, this, forceIndexUpdate);
@@ -701,8 +700,8 @@
 	} else if (target instanceof IFolder) {
 		request = new IndexBinaryFolder((IFolder) target, this);
 	} else if (target instanceof IFile) {
-		request = isJimage(((IFile) target).getFullPath().toOSString()) ? 
-				new AddJimageFileToIndex((IFile) target, null, this, updateIndex) :
+		request = isJrt(((IFile) target).getFullPath().toOSString()) ? 
+				new AddJrtToIndex((IFile) target, null, this, updateIndex) :
 					new AddJarFileToIndex((IFile) target, null, this, updateIndex);
 	} else if (target instanceof File) {
 		request = getRequest(target, containerPath, null, this, updateIndex);
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 d769442..031ee46 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
@@ -39,7 +39,7 @@
 import org.eclipse.jdt.internal.core.JavaProject;
 import org.eclipse.jdt.internal.core.PackageFragmentRoot;
 import org.eclipse.jdt.internal.core.builder.ClasspathJar;
-import org.eclipse.jdt.internal.core.builder.ClasspathJimage;
+import org.eclipse.jdt.internal.core.builder.ClasspathJrt;
 import org.eclipse.jdt.internal.core.builder.ClasspathLocation;
 import org.eclipse.jdt.internal.core.util.Util;
 
@@ -110,8 +110,8 @@
 	try {
 		if (root.isArchive()) {
 			ClasspathEntry rawClasspathEntry = (ClasspathEntry) root.getRawClasspathEntry();
-			cp = JavaModelManager.isJimage(path) ? 
-					new ClasspathJimage(path.toOSString(), 
+			cp = JavaModelManager.isJrt(path) ? 
+					new ClasspathJrt(path.toOSString(), 
 							ClasspathEntry.getExternalAnnotationPath(rawClasspathEntry, ((IJavaProject)root.getParent()).getProject(), true), this) :
 			new ClasspathJar(manager.getZipFile(path), rawClasspathEntry.getAccessRuleSet(), ClasspathEntry.getExternalAnnotationPath(rawClasspathEntry, ((IJavaProject)root.getParent()).getProject(), true), this);
 		} else {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
index 7ba9ea6..c0940e3 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
@@ -255,10 +255,10 @@
 			return Util.newClassFileReader(((JavaElement) type).resource());
 
 		String rootPath = root.getPath().toOSString();
-		if (org.eclipse.jdt.internal.compiler.util.Util.isJimageName(rootPath)) {
+		if (org.eclipse.jdt.internal.compiler.util.Util.isJrt(rootPath)) {
 			String classFileName = classFile.getElementName();
 			String path = Util.concatWith(pkg.names, classFileName, '/');
-			return ClassFileReader.readFromJimage(new File(rootPath), path, null);
+			return ClassFileReader.readFromJrt(new File(rootPath), path, null);
 		} else {
 			ZipFile zipFile = null;
 			try {