Use Lucene's unmapping code inside AccessController.doPrivileged() for unmapping mapped byte buffers.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1713350 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Uwe Schindler 2015-11-09 09:06:01 +00:00
parent 77a586d4a2
commit 8c3cd70589

View File

@ -22,21 +22,27 @@ import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel; import java.nio.channels.WritableByteChannel;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.poi.util.IOUtils; import org.apache.poi.util.IOUtils;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.SuppressForbidden;
/** /**
* A POIFS {@link DataSource} backed by a File * A POIFS {@link DataSource} backed by a File
*/ */
public class FileBackedDataSource extends DataSource { public class FileBackedDataSource extends DataSource {
private final static POILogger logger = POILogFactory.getLogger( FileBackedDataSource.class );
private FileChannel channel; private FileChannel channel;
private boolean writable; private boolean writable;
// remember file base, which needs to be closed too // remember file base, which needs to be closed too
@ -155,26 +161,23 @@ public class FileBackedDataSource extends DataSource {
// need to use reflection to avoid depending on the sun.nio internal API // need to use reflection to avoid depending on the sun.nio internal API
// unfortunately this might break silently with newer/other Java implementations, // unfortunately this might break silently with newer/other Java implementations,
// but we at least have unit-tests which will indicate this when run on Windows // but we at least have unit-tests which will indicate this when run on Windows
private static void unmap(ByteBuffer bb) { private static void unmap(final ByteBuffer buffer) {
Class<?> fcClass = bb.getClass(); AccessController.doPrivileged(new PrivilegedAction<Void>() {
try { @Override
// invoke bb.cleaner().clean(), but do not depend on sun.nio @SuppressForbidden("Java 9 Jigsaw whitelists access to sun.misc.Cleaner, so setAccessible works")
// interfaces public Void run() {
Method cleanerMethod = fcClass.getDeclaredMethod("cleaner"); try {
cleanerMethod.setAccessible(true); final Method getCleanerMethod = buffer.getClass().getMethod("cleaner");
Object cleaner = cleanerMethod.invoke(bb); getCleanerMethod.setAccessible(true);
Method cleanMethod = cleaner.getClass().getDeclaredMethod("clean"); final Object cleaner = getCleanerMethod.invoke(buffer);
cleanMethod.invoke(cleaner); if (cleaner != null) {
} catch (NoSuchMethodException e) { cleaner.getClass().getMethod("clean").invoke(cleaner);
// e.printStackTrace(); }
} catch (SecurityException e) { } catch (Exception e) {
// e.printStackTrace(); logger.log(POILogger.WARN, "Unable to unmap memory mapped ByteBuffer.", e);
} catch (IllegalAccessException e) { }
// e.printStackTrace(); return null; // Void
} catch (IllegalArgumentException e) { }
// e.printStackTrace(); });
} catch (InvocationTargetException e) {
// e.printStackTrace();
}
} }
} }