8147588: Jar file and Zip file not removed in spite of the OPEN_DELETE flag
Reviewed-by: alanb
--- a/jdk/src/java.base/share/classes/java/io/RandomAccessFile.java Mon May 23 12:57:40 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/io/RandomAccessFile.java Mon May 23 12:53:56 2016 -0700
@@ -27,6 +27,8 @@
import java.nio.channels.FileChannel;
import java.util.concurrent.atomic.AtomicBoolean;
+import jdk.internal.misc.JavaIORandomAccessFileAccess;
+import jdk.internal.misc.SharedSecrets;
import sun.nio.ch.FileChannelImpl;
@@ -75,6 +77,7 @@
private static final int O_RDWR = 2;
private static final int O_SYNC = 4;
private static final int O_DSYNC = 8;
+ private static final int O_TEMPORARY = 16;
/**
* Creates a random access file stream to read from, and optionally
@@ -203,6 +206,12 @@
public RandomAccessFile(File file, String mode)
throws FileNotFoundException
{
+ this(file, mode, false);
+ }
+
+ private RandomAccessFile(File file, String mode, boolean openAndDelete)
+ throws FileNotFoundException
+ {
String name = (file != null ? file.getPath() : null);
int imode = -1;
if (mode.equals("r"))
@@ -219,6 +228,8 @@
imode = -1;
}
}
+ if (openAndDelete)
+ imode |= O_TEMPORARY;
if (imode < 0)
throw new IllegalArgumentException("Illegal mode \"" + mode
+ "\" must be one of "
@@ -1165,5 +1176,15 @@
static {
initIDs();
+ SharedSecrets.setJavaIORandomAccessFileAccess(new JavaIORandomAccessFileAccess()
+ {
+ // This is for j.u.z.ZipFile.OPEN_DELETE. The O_TEMPORARY flag
+ // is only implemented/supported on windows.
+ public RandomAccessFile openAndDelete(File file, String mode)
+ throws IOException
+ {
+ return new RandomAccessFile(file, mode, true);
+ }
+ });
}
}
--- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java Mon May 23 12:57:40 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java Mon May 23 12:53:56 2016 -0700
@@ -54,6 +54,8 @@
import java.util.stream.StreamSupport;
import jdk.internal.misc.JavaUtilZipFileAccess;
import jdk.internal.misc.SharedSecrets;
+import jdk.internal.misc.JavaIORandomAccessFileAccess;
+import jdk.internal.misc.VM;
import jdk.internal.perf.PerfCounter;
import static java.util.zip.ZipConstants.*;
@@ -805,19 +807,6 @@
}
}
- static {
- SharedSecrets.setJavaUtilZipFileAccess(
- new JavaUtilZipFileAccess() {
- public boolean startsWithLocHeader(ZipFile zip) {
- return zip.zsrc.startsWithLoc;
- }
- public String[] getMetaInfEntryNames(ZipFile zip) {
- return zip.getMetaInfEntryNames();
- }
- }
- );
- }
-
/**
* Returns an array of strings representing the names of all entries
* that begin with "META-INF/" (case ignored). This method is used
@@ -842,6 +831,21 @@
}
}
+ private static boolean isWindows;
+ static {
+ SharedSecrets.setJavaUtilZipFileAccess(
+ new JavaUtilZipFileAccess() {
+ public boolean startsWithLocHeader(ZipFile zip) {
+ return zip.zsrc.startsWithLoc;
+ }
+ public String[] getMetaInfEntryNames(ZipFile zip) {
+ return zip.getMetaInfEntryNames();
+ }
+ }
+ );
+ isWindows = VM.getSavedProperty("os.name").contains("Windows");
+ }
+
private static class Source {
private final Key key; // the key in files
private int refs = 1;
@@ -956,9 +960,16 @@
private Source(Key key, boolean toDelete) throws IOException {
this.key = key;
- this.zfile = new RandomAccessFile(key.file, "r");
if (toDelete) {
- key.file.delete();
+ if (isWindows) {
+ this.zfile = SharedSecrets.getJavaIORandomAccessFileAccess()
+ .openAndDelete(key.file, "r");
+ } else {
+ this.zfile = new RandomAccessFile(key.file, "r");
+ key.file.delete();
+ }
+ } else {
+ this.zfile = new RandomAccessFile(key.file, "r");
}
try {
initCEN(-1);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaIORandomAccessFileAccess.java Mon May 23 12:53:56 2016 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.misc;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+public interface JavaIORandomAccessFileAccess {
+ public RandomAccessFile openAndDelete(File file, String mode)
+ throws IOException;
+}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Mon May 23 12:57:40 2016 +0100
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Mon May 23 12:53:56 2016 -0700
@@ -30,6 +30,7 @@
import java.io.Console;
import java.io.FileDescriptor;
import java.io.ObjectInputStream;
+import java.io.RandomAccessFile;
import java.security.ProtectionDomain;
import java.security.AccessController;
@@ -64,6 +65,7 @@
private static JavaAWTFontAccess javaAWTFontAccess;
private static JavaBeansAccess javaBeansAccess;
private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
+ private static JavaIORandomAccessFileAccess javaIORandomAccessFileAccess;
public static JavaUtilJarAccess javaUtilJarAccess() {
if (javaUtilJarAccess == null) {
@@ -274,4 +276,15 @@
public static void setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access) {
javaObjectInputStreamAccess = access;
}
+
+ public static void setJavaIORandomAccessFileAccess(JavaIORandomAccessFileAccess jirafa) {
+ javaIORandomAccessFileAccess = jirafa;
+ }
+
+ public static JavaIORandomAccessFileAccess getJavaIORandomAccessFileAccess() {
+ if (javaIORandomAccessFileAccess == null) {
+ unsafe.ensureClassInitialized(RandomAccessFile.class);
+ }
+ return javaIORandomAccessFileAccess;
+ }
}
--- a/jdk/src/java.base/share/native/libjava/RandomAccessFile.c Mon May 23 12:57:40 2016 +0100
+++ b/jdk/src/java.base/share/native/libjava/RandomAccessFile.c Mon May 23 12:53:56 2016 -0700
@@ -60,6 +60,10 @@
else if (mode & java_io_RandomAccessFile_O_DSYNC)
flags |= O_DSYNC;
}
+#ifdef WIN32
+ if (mode & java_io_RandomAccessFile_O_TEMPORARY)
+ flags |= O_TEMPORARY;
+#endif
fileOpen(env, this, path, raf_fd, flags);
}