Bug 573287 - fix unclosed zipfile handle in ArchiveFileObject

if a resource is put into a map the previous instance has to be closed

enabled resource warnings in apt

Change-Id: Icf512d590e66814df4dc243375d8cbf79224d96e
Signed-off-by: Joerg Kubitz <jkubitz-eclipse@gmx.de>
Reviewed-on: https://git.eclipse.org/r/c/jdt/eclipse.jdt.core/+/182836
Tested-by: JDT Bot <jdt-bot@eclipse.org>
Reviewed-by: Jay Arthanareeswaran <jarthana@in.ibm.com>
diff --git a/org.eclipse.jdt.compiler.apt/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jdt.compiler.apt/.settings/org.eclipse.jdt.core.prefs
index 09d8d01..6d1cc04 100644
--- a/org.eclipse.jdt.compiler.apt/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jdt.compiler.apt/.settings/org.eclipse.jdt.core.prefs
@@ -67,7 +67,7 @@
 org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
 org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
 org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
-org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning
 org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
 org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
 org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
@@ -84,7 +84,7 @@
 org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
 org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
 org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
 org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
 org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
 org.eclipse.jdt.core.compiler.problem.uninternedIdentityComparison=enabled
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java
index 36a2c2e..9976019 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BaseAnnotationProcessorManager.java
@@ -161,8 +161,9 @@
 			}
 		}
 		RoundEnvImpl roundEnv = new RoundEnvImpl(units, referenceBindings, isLastRound, _processingEnv);
-		PrintWriter traceProcessorInfo = _printProcessorInfo ? _out : null;
-		PrintWriter traceRounds = _printRounds ? _out : null;
+		PrintWriter out = _out; // closable resource not manages in this class
+		PrintWriter traceProcessorInfo = _printProcessorInfo ? out : null;
+		PrintWriter traceRounds = _printRounds ? out : null;
 		if (traceRounds != null) {
 			traceRounds.println("Round " + ++_round + ':'); //$NON-NLS-1$
 		}
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java
index 93b1979..ebc85e1 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java
@@ -78,6 +78,7 @@
 		}
 		BatchProcessingEnvImpl processingEnv = new BatchProcessingEnvImpl(this, (Main) batchCompiler, commandLineArguments);
 		_processingEnv = processingEnv;
+		@SuppressWarnings("resource") // fileManager is not opened here
 		JavaFileManager fileManager = processingEnv.getFileManager();
 		if (fileManager instanceof StandardJavaFileManager) {
 			Iterable<? extends File> location = null;
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/HookedJavaFileObject.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/HookedJavaFileObject.java
index a5fbbcd..b06e9f9 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/HookedJavaFileObject.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/HookedJavaFileObject.java
@@ -209,11 +209,13 @@
 		_typeName = typeName;
 	}
 
+	@SuppressWarnings("resource") // ForwardingOutputStream forwards close() too
 	@Override
 	public OutputStream openOutputStream() throws IOException {
 		return new ForwardingOutputStream(super.openOutputStream());
 	}
 
+	@SuppressWarnings("resource") // ForwardingWriter forwards close() too
 	@Override
 	public Writer openWriter() throws IOException {
 		return new ForwardingWriter(super.openWriter());
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/Archive.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/Archive.java
index 94f0d8e..6ac73de 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/Archive.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/Archive.java
@@ -109,11 +109,11 @@
 
 	@Override
 	public void close() {
+		this.packagesCache = null;
 		try {
 			if (this.zipFile != null) {
 				this.zipFile.close();
 			}
-			this.packagesCache = null;
 		} catch (IOException e) {
 			// ignore
 		}
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java
index be3844b..c7acf86 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/EclipseFileManager.java
@@ -114,7 +114,9 @@
 	protected void initialize(File javahome) throws IOException {
 		if (this.isOnJvm9) {
 			this.jrtSystem = new JrtFileSystem(javahome);
-			this.archivesCache.put(javahome, this.jrtSystem);
+			try (Archive previous = this.archivesCache.put(javahome, this.jrtSystem)) {
+				// nothing. Only theoretically autoclose the previous instance - which does not exist at this time
+			}
 			this.jrtHome = javahome;
 			this.locationHandler.newSystemLocation(StandardLocation.SYSTEM_MODULES, this.jrtSystem);
 		} else {
@@ -154,34 +156,37 @@
 				}
 			}
 		} else if (isArchive(file)) {
+			@SuppressWarnings("resource") // cached archive is closed in EclipseFileManager.close()
 			Archive archive = this.getArchive(file);
-			if (archive == Archive.UNKNOWN_ARCHIVE) return;
-			String key = normalizedPackageName;
-			if (!normalizedPackageName.endsWith("/")) {//$NON-NLS-1$
-				key += '/';
-			}
-			// we have an archive file
-			if (recurse) {
-				for (String packageName : archive.allPackages()) {
-					if (packageName.startsWith(key)) {
-						List<String[]> types = archive.getTypes(packageName);
-						if (types != null) {
-							for (String[] entry : types) {
-								final Kind kind = getKind(getExtension(entry[0]));
-								if (kinds.contains(kind)) {
-									collector.add(archive.getArchiveFileObject(packageName + entry[0], entry[1], this.charset));
+			if (archive != Archive.UNKNOWN_ARCHIVE) {
+				String key = normalizedPackageName;
+				if (!normalizedPackageName.endsWith("/")) {//$NON-NLS-1$
+					key += '/';
+				}
+				// we have an archive file
+				if (recurse) {
+					for (String packageName : archive.allPackages()) {
+						if (packageName.startsWith(key)) {
+							List<String[]> types = archive.getTypes(packageName);
+							if (types != null) {
+								for (String[] entry : types) {
+									final Kind kind = getKind(getExtension(entry[0]));
+									if (kinds.contains(kind)) {
+										collector.add(archive.getArchiveFileObject(packageName + entry[0], entry[1],
+												this.charset));
+									}
 								}
 							}
 						}
 					}
-				}
-			} else {
-				List<String[]> types = archive.getTypes(key);
-				if (types != null) {
-					for (String[] entry : types) {
-						final Kind kind = getKind(getExtension(entry[0]));
-						if (kinds.contains(kind)) {
-							collector.add(archive.getArchiveFileObject(key + entry[0], entry[1], this.charset));
+				} else {
+					List<String[]> types = archive.getTypes(key);
+					if (types != null) {
+						for (String[] entry : types) {
+							final Kind kind = getKind(getExtension(entry[0]));
+							if (kinds.contains(kind)) {
+								collector.add(archive.getArchiveFileObject(key + entry[0], entry[1], this.charset));
+							}
 						}
 					}
 				}
@@ -240,23 +245,23 @@
 
 	private Archive getArchive(File f) {
 		// check the archive (jar/zip) cache
-		Archive archive = this.archivesCache.get(f);
-		if (archive == null) {
-			archive = Archive.UNKNOWN_ARCHIVE;
-			// create a new archive
-			if (f.exists()) {
-				try {
-					archive = new Archive(f);
-				} catch (ZipException e) {
-					// ignore
-				} catch (IOException e) {
-					// ignore
-				}
-				if (archive != null) {
-					this.archivesCache.put(f, archive);
-				}
+		Archive existing = this.archivesCache.get(f);
+		if (existing != null) {
+			return existing;
+		}
+		Archive archive = Archive.UNKNOWN_ARCHIVE;
+		// create a new archive
+		if (f.exists()) {
+			try {
+				archive = new Archive(f);
+			} catch (ZipException e) {
+				// ignore
+			} catch (IOException e) {
+				// ignore
 			}
-			this.archivesCache.put(f, archive);
+		}
+		try (Archive previous = this.archivesCache.put(f, archive)) {
+			// Nothing but closing previous instance - which should not exist at this time
 		}
 		return archive;
 	}
@@ -285,7 +290,11 @@
 			}
 			URL[] result = new URL[allURLs.size()];
 			cl = new URLClassLoader(allURLs.toArray(result), getClass().getClassLoader());
-			this.classloaders.put(location, cl);
+			try (URLClassLoader previous = this.classloaders.put(location, cl)) {
+				// Nothing but closing previous instance - which should not exist at this time
+			} catch (IOException e) {
+				//ignore
+			}
 		}
 		return cl;
 	}
@@ -403,17 +412,37 @@
 				}
 			} else if (isArchive(file)) {
 				// handle archive file
-				Archive archive = getArchive(file);
-				if (archive != Archive.UNKNOWN_ARCHIVE) {
-					if (archive.contains(normalizedFileName)) {
-						return archive.getArchiveFileObject(normalizedFileName, null, this.charset);
-					}
+				ArchiveFileObject fileObject = getFileObject(file, normalizedFileName);
+				if (fileObject!=null) {
+					return fileObject;
 				}
 			}
 		}
 		return null;
 	}
 
+	@SuppressWarnings("resource") // cached archive is closed in EclipseFileManager.close()
+	private ArchiveFileObject getFileObject(File archiveFile, String normalizedFileName) {
+		Archive archive = getArchive(archiveFile);
+		if (archive == Archive.UNKNOWN_ARCHIVE) {
+			return null;
+		}
+		if (archive.contains(normalizedFileName)) {
+			return archive.getArchiveFileObject(normalizedFileName, null, this.charset);
+		}
+		return null;
+	}
+
+	@SuppressWarnings("resource") // cached archive is closed in EclipseFileManager.close()
+	private Boolean containsFileObject(File archiveFile, String normalizedFileName) {
+		Archive archive = getArchive(archiveFile);
+		if (archive == Archive.UNKNOWN_ARCHIVE) {
+			return null;
+		}
+		return archive.contains(normalizedFileName);
+	}
+
+
 	private String normalizedFileName(String packageName, String relativeName) {
 		StringBuilder sb = new StringBuilder();
 		sb.append(normalized(packageName));
@@ -472,11 +501,9 @@
 				}
 			} else if (isArchive(file)) {
 				// handle archive file
-				Archive archive = getArchive(file);
-				if (archive != Archive.UNKNOWN_ARCHIVE) {
-					if (archive.contains(normalizedFileName)) {
-						return archive.getArchiveFileObject(normalizedFileName, null, this.charset);
-					}
+				ArchiveFileObject fileObject = getFileObject(file, normalizedFileName);
+				if (fileObject!=null) {
+					return fileObject;
 				}
 			}
 		}
@@ -1380,11 +1407,9 @@
 				}
 			} else if (isArchive(file)) {
 				if (fo instanceof ArchiveFileObject) {
-					Archive archive = getArchive(file);
-					if (archive != Archive.UNKNOWN_ARCHIVE) {
-						if (archive.contains(((ArchiveFileObject) fo ).entryName)) {
-							return true;
-						}
+					Boolean contains = containsFileObject(file, ((ArchiveFileObject) fo).entryName);
+					if (contains != null) {
+						return contains;
 					}
 				}
 			}
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/ModuleLocationHandler.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/ModuleLocationHandler.java
index eee15f6..2f231b7 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/ModuleLocationHandler.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/ModuleLocationHandler.java
@@ -14,8 +14,6 @@
 import javax.tools.JavaFileManager.Location;
 import javax.tools.StandardLocation;
 
-import org.eclipse.jdt.internal.compiler.batch.ClasspathJrt;
-
 public class ModuleLocationHandler {
 
 	Map<Location, LocationContainer> containers;
@@ -24,10 +22,6 @@
 		this.containers = new HashMap<>();
 	}
 
-	public void newSystemLocation(Location loc, ClasspathJrt cp) throws IOException {
-		SystemLocationContainer systemLocationWrapper = new SystemLocationContainer(StandardLocation.SYSTEM_MODULES, cp);
-		this.containers.put(loc, systemLocationWrapper);
-	}
 	public void newSystemLocation(Location loc, JrtFileSystem jrt) throws IOException {
 		SystemLocationContainer systemLocationWrapper = new SystemLocationContainer(StandardLocation.SYSTEM_MODULES, jrt);
 		this.containers.put(loc, systemLocationWrapper);
@@ -159,9 +153,6 @@
 				this.locationPaths.put(path, wrapper);
 			}
 		}
-		public SystemLocationContainer(Location loc, ClasspathJrt cp) throws IOException {
-			this(loc, new JrtFileSystem(cp.file));
-		}
 	}
 
 	class LocationWrapper implements Location {
diff --git a/org.eclipse.jdt.compiler.tool/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jdt.compiler.tool/.settings/org.eclipse.jdt.core.prefs
index 5b9a641..8deba0e 100644
--- a/org.eclipse.jdt.compiler.tool/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jdt.compiler.tool/.settings/org.eclipse.jdt.core.prefs
@@ -97,7 +97,7 @@
 org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
 org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
 org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
-org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error
 org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
 org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
 org.eclipse.jdt.core.compiler.problem.uninternedIdentityComparison=enabled
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/Archive.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/Archive.java
index 558ca5b..4405aa1 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/Archive.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/Archive.java
@@ -30,7 +30,7 @@
 /**
  * Used as a zip file cache.
  */
-public class Archive implements Closeable{
+public class Archive implements Closeable {
 
 	public static final Archive UNKNOWN_ARCHIVE = new Archive();
 
@@ -121,11 +121,11 @@
 
 	@Override
 	public void close() {
+		this.packagesCache = null;
 		try {
 			if (this.zipFile != null) {
 				this.zipFile.close();
 			}
-			this.packagesCache = null;
 		} catch (IOException e) {
 			// ignore
 		}
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java
index 00cbf09..5384f70 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java
@@ -528,9 +528,14 @@
 							if (platformLocations.size() == 1) {
 								Classpath jrt = platformLocations.get(0);
 								if (jrt instanceof ClasspathJrt) {
+									ClasspathJrt classpathJrt = (ClasspathJrt) jrt;
 									// TODO: double check, should it be platform or system module?
 									try {
-										((EclipseFileManager) standardJavaFileManager).locationHandler.newSystemLocation(StandardLocation.SYSTEM_MODULES, (ClasspathJrt) jrt);
+										EclipseFileManager efm = (EclipseFileManager) standardJavaFileManager;
+										@SuppressWarnings("resource") // XXX EclipseFileManager should close jrtfs but it looks like standardJavaFileManager is never closed
+										// Was leaking new JrtFileSystem(classpathJrt.file):
+										JrtFileSystem jrtfs = efm.getJrtFileSystem(classpathJrt.file);
+										efm.locationHandler.newSystemLocation(StandardLocation.SYSTEM_MODULES, jrtfs);
 									} catch (IOException e) {
 										e.printStackTrace();
 									}
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 a4bbecc..b6879b7 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
@@ -114,7 +114,9 @@
 	protected void initialize(File javahome) throws IOException {
 		if (this.isOnJvm9) {
 			this.jrtSystem = new JrtFileSystem(javahome);
-			this.archivesCache.put(javahome, this.jrtSystem);
+			try (Archive previous = this.archivesCache.put(javahome, this.jrtSystem)) {
+				// nothing. Only theoretically autoclose the previous instance - which does not exist at this time
+			}
 			this.jrtHome = javahome;
 			this.locationHandler.newSystemLocation(StandardLocation.SYSTEM_MODULES, this.jrtSystem);
 		} else {
@@ -153,34 +155,37 @@
 				}
 			}
 		} else if (isArchive(file)) {
+			@SuppressWarnings("resource") // cached archive is closed in EclipseFileManager.close()
 			Archive archive = this.getArchive(file);
-			if (archive == Archive.UNKNOWN_ARCHIVE) return;
-			String key = normalizedPackageName;
-			if (!normalizedPackageName.endsWith("/")) {//$NON-NLS-1$
-				key += '/';
-			}
-			// we have an archive file
-			if (recurse) {
-				for (String packageName : archive.allPackages()) {
-					if (packageName.startsWith(key)) {
-						List<String[]> types = archive.getTypes(packageName);
-						if (types != null) {
-							for (String[] entry : types) {
-								final Kind kind = getKind(getExtension(entry[0]));
-								if (kinds.contains(kind)) {
-									collector.add(archive.getArchiveFileObject(packageName + entry[0], entry[1], this.charset));
+			if (archive != Archive.UNKNOWN_ARCHIVE) {
+				String key = normalizedPackageName;
+				if (!normalizedPackageName.endsWith("/")) {//$NON-NLS-1$
+					key += '/';
+				}
+				// we have an archive file
+				if (recurse) {
+					for (String packageName : archive.allPackages()) {
+						if (packageName.startsWith(key)) {
+							List<String[]> types = archive.getTypes(packageName);
+							if (types != null) {
+								for (String[] entry : types) {
+									final Kind kind = getKind(getExtension(entry[0]));
+									if (kinds.contains(kind)) {
+										collector.add(archive.getArchiveFileObject(packageName + entry[0], entry[1],
+												this.charset));
+									}
 								}
 							}
 						}
 					}
-				}
-			} else {
-				List<String[]> types = archive.getTypes(key);
-				if (types != null) {
-					for (String[] entry : types) {
-						final Kind kind = getKind(getExtension(entry[0]));
-						if (kinds.contains(kind)) {
-							collector.add(archive.getArchiveFileObject(key + entry[0], entry[1], this.charset));
+				} else {
+					List<String[]> types = archive.getTypes(key);
+					if (types != null) {
+						for (String[] entry : types) {
+							final Kind kind = getKind(getExtension(entry[0]));
+							if (kinds.contains(kind)) {
+								collector.add(archive.getArchiveFileObject(key + entry[0], entry[1], this.charset));
+							}
 						}
 					}
 				}
@@ -237,29 +242,33 @@
 		}
 	}
 
+	JrtFileSystem getJrtFileSystem(File f){
+		return (JrtFileSystem) getArchive(f);
+	}
+
 	private Archive getArchive(File f) {
 		// check the archive (jar/zip) cache
-		Archive archive = this.archivesCache.get(f);
-		if (archive == null) {
-			archive = Archive.UNKNOWN_ARCHIVE;
-			// create a new archive
-			if (f.exists()) {
-				try {
-					if (isJrt(f)) {
-						archive = new JrtFileSystem(f);
-					} else {
-						archive = new Archive(f);
-					}
-				} catch (ZipException e) {
-					// ignore
-				} catch (IOException e) {
-					// ignore
+		Archive existing = this.archivesCache.get(f);
+		if (existing != null) {
+			return existing;
+		}
+		Archive archive = Archive.UNKNOWN_ARCHIVE;
+		// create a new archive
+		if (f.exists()) {
+			try {
+				if (isJrt(f)) {
+					archive = new JrtFileSystem(f);
+				} else {
+					archive = new Archive(f);
 				}
-				if (archive != null) {
-					this.archivesCache.put(f, archive);
-				}
+			} catch (ZipException e) {
+				// ignore
+			} catch (IOException e) {
+				// ignore
 			}
-			this.archivesCache.put(f, archive);
+		}
+		try (Archive previous = this.archivesCache.put(f, archive)) {
+			// Nothing but closing previous instance - which should not exist at this time
 		}
 		return archive;
 	}
@@ -267,7 +276,6 @@
 	/* (non-Javadoc)
 	 * @see javax.tools.JavaFileManager#getClassLoader(javax.tools.JavaFileManager.Location)
 	 */
-	@SuppressWarnings("resource") // URLClassLoader is closed in EclipseFileManager.close()
 	@Override
 	public ClassLoader getClassLoader(Location location) {
 		validateNonModuleLocation(location);
@@ -289,7 +297,11 @@
 			}
 			URL[] result = new URL[allURLs.size()];
 			cl = new URLClassLoader(allURLs.toArray(result), getClass().getClassLoader());
-			this.classloaders.put(location, cl);
+			try (URLClassLoader previous = this.classloaders.put(location, cl)) {
+				// Nothing but closing previous instance - which should not exist at this time
+			} catch (IOException e) {
+				//ignore
+			}
 		}
 		return cl;
 	}
@@ -407,17 +419,36 @@
 				}
 			} else if (isArchive(file)) {
 				// handle archive file
-				Archive archive = getArchive(file);
-				if (archive != Archive.UNKNOWN_ARCHIVE) {
-					if (archive.contains(normalizedFileName)) {
-						return archive.getArchiveFileObject(normalizedFileName, null, this.charset);
-					}
+				ArchiveFileObject fileObject = getFileObject(file, normalizedFileName);
+				if (fileObject!=null) {
+					return fileObject;
 				}
 			}
 		}
 		return null;
 	}
 
+	@SuppressWarnings("resource") // cached archive is closed in EclipseFileManager.close()
+	private ArchiveFileObject getFileObject(File archiveFile, String normalizedFileName) {
+		Archive archive = getArchive(archiveFile);
+		if (archive == Archive.UNKNOWN_ARCHIVE) {
+			return null;
+		}
+		if (archive.contains(normalizedFileName)) {
+			return archive.getArchiveFileObject(normalizedFileName, null, this.charset);
+		}
+		return null;
+	}
+
+	@SuppressWarnings("resource") // cached archive is closed in EclipseFileManager.close()
+	private Boolean containsFileObject(File archiveFile, String normalizedFileName) {
+		Archive archive = getArchive(archiveFile);
+		if (archive == Archive.UNKNOWN_ARCHIVE) {
+			return null;
+		}
+		return archive.contains(normalizedFileName);
+	}
+
 	/* (non-Javadoc)
 	 * @see javax.tools.JavaFileManager#getFileForOutput(javax.tools.JavaFileManager.Location, java.lang.String, java.lang.String, javax.tools.FileObject)
 	 */
@@ -474,11 +505,9 @@
 				}
 			} else if (isArchive(file)) {
 				// handle archive file
-				Archive archive = getArchive(file);
-				if (archive != Archive.UNKNOWN_ARCHIVE) {
-					if (archive.contains(normalizedFileName)) {
-						return archive.getArchiveFileObject(normalizedFileName, null, this.charset);
-					}
+				ArchiveFileObject fileObject = getFileObject(file, normalizedFileName);
+				if (fileObject!=null) {
+					return fileObject;
 				}
 			}
 		}
@@ -1407,11 +1436,9 @@
 				}
 			} else if (isArchive(file)) {
 				if (fo instanceof ArchiveFileObject) {
-					Archive archive = getArchive(file);
-					if (archive != Archive.UNKNOWN_ARCHIVE) {
-						if (archive.contains(((ArchiveFileObject) fo ).entryName)) {
-							return true;
-						}
+					Boolean contains = containsFileObject(file, ((ArchiveFileObject) fo).entryName);
+					if (contains != null) {
+						return contains;
 					}
 				}
 			}
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/ModuleLocationHandler.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/ModuleLocationHandler.java
index 35fd2fb..92b2c73 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/ModuleLocationHandler.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/ModuleLocationHandler.java
@@ -27,8 +27,6 @@
 import javax.tools.JavaFileManager.Location;
 import javax.tools.StandardLocation;
 
-import org.eclipse.jdt.internal.compiler.batch.ClasspathJrt;
-
 public class ModuleLocationHandler {
 
 	Map<Location, LocationContainer> containers;
@@ -37,10 +35,6 @@
 		this.containers = new HashMap<>();
 	}
 
-	public void newSystemLocation(Location loc, ClasspathJrt cp) throws IOException {
-		SystemLocationContainer systemLocationWrapper = new SystemLocationContainer(StandardLocation.SYSTEM_MODULES, cp);
-		this.containers.put(loc, systemLocationWrapper);
-	}
 	public void newSystemLocation(Location loc, JrtFileSystem jrt) throws IOException {
 		SystemLocationContainer systemLocationWrapper = new SystemLocationContainer(StandardLocation.SYSTEM_MODULES, jrt);
 		this.containers.put(loc, systemLocationWrapper);
@@ -180,9 +174,6 @@
 				this.locationPaths.put(path, wrapper);
 			}
 		}
-		public SystemLocationContainer(Location loc, ClasspathJrt cp) throws IOException {
-			this(loc, new JrtFileSystem(cp.file));
-		}
 	}
 	class OutputLocationContainer extends LocationContainer {
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
index 981828d..7ebf982 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
@@ -371,9 +371,10 @@
 		JRTUtil.MODULE_TO_LOAD = System.getProperty("modules.to.load"); //$NON-NLS-1$
 		String javaVersion = System.getProperty("java.version"); //$NON-NLS-1$
 		if (javaVersion != null && javaVersion.startsWith("1.8")) { //$NON-NLS-1$
-			URLClassLoader loader = new URLClassLoader(new URL[] { jrtPath });
-			HashMap<String, ?> env = new HashMap<>();
-			this.fs = FileSystems.newFileSystem(JRTUtil.JRT_URI, env, loader);
+			try (URLClassLoader loader = new URLClassLoader(new URL[] { jrtPath })) {
+				HashMap<String, ?> env = new HashMap<>();
+				this.fs = FileSystems.newFileSystem(JRTUtil.JRT_URI, env, loader);
+			}
 		} else {
 			HashMap<String, String> env = new HashMap<>();
 			env.put("java.home", this.jdkHome); //$NON-NLS-1$
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 dfffd3a..1339133 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
@@ -223,13 +223,16 @@
 		}
 
 		public void setCache(IPath path, ZipFile zipFile) {
-			ZipFile old = this.map.put(path, zipFile);
-			if(old != null) {
-				if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
-					Thread currentThread = Thread.currentThread();
-					System.out.println("(" + currentThread + ") [ZipCache[" + this.owner //$NON-NLS-1$//$NON-NLS-2$
-							+ "].setCache()] leaked ZipFile on " + old.getName() + " for path: " + path); //$NON-NLS-1$ //$NON-NLS-2$
+			try (ZipFile old = this.map.put(path, zipFile)) {
+				if (old != null) {
+					if (JavaModelManager.ZIP_ACCESS_VERBOSE) {
+						Thread currentThread = Thread.currentThread();
+						System.out.println("(" + currentThread + ") [ZipCache[" + this.owner //$NON-NLS-1$//$NON-NLS-2$
+								+ "].setCache()] leaked ZipFile on " + old.getName() + " for path: " + path); //$NON-NLS-1$ //$NON-NLS-2$
+					}
 				}
+			} catch (IOException e) {
+				e.printStackTrace();
 			}
 		}
 	}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
index ba153df..d607b4c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
@@ -405,9 +405,11 @@
 	if (!scanContent()) // ensure zipFile is initialized
 		return null;
 	ZipEntry entry = this.zipFile.getEntry(TypeConstants.META_INF_MANIFEST_MF);
-	try(InputStream is = entry != null ? this.zipFile.getInputStream(entry) : null) {
-		if (is != null)
-			return new Manifest(is);
+	if (entry == null) {
+		return null;
+	}
+	try(InputStream is = this.zipFile.getInputStream(entry)) {
+		return new Manifest(is);
 	} catch (IOException e) {
 		// cannot use manifest
 	}