src/share/classes/org/openjdk/jigsaw/ModuleFile.java
Print this page
@@ -56,10 +56,13 @@
}
}
public final static class Reader implements Closeable {
+ // The library where this module is to be installed, or null if
+ // simply extracting ( jmod Extract, or jsign )
+ private SimpleLibrary lib;
private DataInputStream stream;
private File destination;
private boolean deflate;
private HashType hashtype;
@@ -121,10 +124,15 @@
this.stream =
new DataInputStream(new BufferedInputStream(stream));
}
}
+ public Reader(DataInputStream stream, SimpleLibrary lib) {
+ this(stream);
+ this.lib = lib;
+ }
+
private void checkHashMatch(byte[] expected, byte[] computed)
throws IOException
{
if (!MessageDigest.isEqual(expected, computed))
throw new IOException("Expected hash "
@@ -258,10 +266,11 @@
return contentStream;
}
public void close() throws IOException {
try {
+ try {
if (contentStream != null) {
contentStream.close();
contentStream = null;
}
} finally {
@@ -268,12 +277,19 @@
if (fileIn != null) {
fileIn.close();
fileIn = null;
}
}
+ } finally {
+ if (oomFilesWriter != null) {
+ oomFilesWriter.close();
+ oomFilesWriter = null;
}
+ }
+ }
+
public void readModule() throws IOException {
extract = false;
readStart();
readRest();
}
@@ -381,10 +397,12 @@
public void readClasses(DataInputStream in) throws IOException {
unpack200gzip(in);
}
private File currentPath = null;
+ // true if currentPath points a path outside the module directory
+ private boolean oomPath; // false
private OutputStream openOutputStream(SectionType type,
String path)
throws IOException
{
@@ -427,13 +445,16 @@
try (GZIPInputStream gin = new GZIPInputStream(bain);
OutputStream out = openOutputStream(type, header.getPath())) {
copyStream(gin, out);
}
- if (extract)
+ if (extract) {
markNativeCodeExecutable(type, currentPath);
+ if (oomPath)
+ trackOutOfModuleContent(currentPath);
}
+ }
public void readUncompressedFile(DataInputStream in,
SectionType type,
int csize)
throws IOException
@@ -446,12 +467,16 @@
byte[] buf = new byte[8192];
int n;
while ((n = cin.read(buf)) >= 0)
out.write(buf, 0, n);
}
+ if (extract) {
markNativeCodeExecutable(type, currentPath);
+ if (oomPath)
+ trackOutOfModuleContent(currentPath);
}
+ }
public byte[] readModuleInfo(DataInputStream in, int csize)
throws IOException
{
CountingInputStream cin = new CountingInputStream(in, csize);
@@ -467,10 +492,60 @@
throws IOException
{
return readModuleInfo(in, csize); // signature has the same format
}
+ // Returns the path for the section type, if the library
+ // has one configured.
+ private File librarySectionPath(SectionType type) {
+ if (lib != null && type == SectionType.NATIVE_LIBS
+ && lib.natlibs() != null)
+ return lib.natlibs();
+ if (lib != null && type == SectionType.NATIVE_CMDS
+ && lib.natcmds() != null)
+ return lib.natcmds();
+
+ return null;
+ }
+
+ // Track files installed outside the module library. For later removal.
+ private PrintWriter oomFilesWriter;
+
+ private void trackOutOfModuleContent(File file)
+ throws IOException
+ {
+ if (file == null)
+ return;
+
+ // Lazy construction, not all modules will need this.
+ if (oomFilesWriter == null) {
+ oomFilesWriter = new PrintWriter(computeRealPath("oomfiles"));
+ }
+ oomFilesWriter.println(file);
+ oomFilesWriter.flush();
+ }
+
+ void remove() throws IOException {
+ ModuleFile.Reader.remove(destination);
+ }
+
+ // Removes a module, given its module install directory
+ static void remove(File moduleDir) throws IOException {
+ // Firstly remove any files installed outside of the module dir
+ File oomfiles = new File(moduleDir, "oomfiles");
+ if (oomfiles.exists()) {
+ try (FileInputStream fis = new FileInputStream(oomfiles);
+ BufferedReader in = new BufferedReader(new InputStreamReader(fis))) {
+ String filename;
+ while ((filename = in.readLine()) != null)
+ Files.delete(new File(filename));
+ }
+ }
+
+ Files.deleteTree(moduleDir);
+ }
+
private File computeRealPath(String storedpath) throws IOException {
String convertedpath = storedpath.replace('/', File.separatorChar);
File path = new File(convertedpath);
@@ -487,10 +562,31 @@
private File computeRealPath(SectionType type,
String storedpath)
throws IOException
{
+ File lsp = librarySectionPath(type);
+ if (lsp != null) {
+ // The library has a configured path for this section
+ File realpath = new File(lsp, storedpath);
+
+ if (realpath.exists()) {
+ // conflict, for now just fail
+ throw new IOException("File " + realpath + " already exists");
+ }
+
+ // Create the parent directories if necessary
+ File parent = realpath.getParentFile();
+ if (!parent.exists())
+ Files.mkdirs(parent, realpath.getName());
+
+ oomPath = true;
+ return realpath;
+ }
+
+ // reset since the path must be within the module directory
+ oomPath = false;
String dir = getSubdirOfSection(type);
return computeRealPath(dir + File.separatorChar + storedpath);
}
private static void markNativeCodeExecutable(SectionType type,