[SCM] jigsaw packaging branch, master, updated. 9a0746ae2d69d820c9f643eee5c22e5ad6768601

Guillaume Mazoyer respawneral at gmail.com
Thu Jan 26 23:10:25 UTC 2012


The following commit has been merged in the master branch:
commit 9a0746ae2d69d820c9f643eee5c22e5ad6768601
Author: Alan Bateman <alan.bateman at oracle.com>
Date:   Fri Jan 27 00:09:49 2012 +0100

    Sync with lastest upstream.

diff --git a/jdk/.hg/cache/branchheads b/jdk/.hg/cache/branchheads
index 26d3058..5fd821b 100644
--- a/jdk/.hg/cache/branchheads
+++ b/jdk/.hg/cache/branchheads
@@ -1,2 +1,2 @@
-8c6429c279e7dcc24102c2e2c69a40997018f946 5000
-8c6429c279e7dcc24102c2e2c69a40997018f946 default
+a22f65ac0b9a462bb7108595db720b4326d337a6 5001
+a22f65ac0b9a462bb7108595db720b4326d337a6 default
diff --git a/jdk/.hg/dirstate b/jdk/.hg/dirstate
index 0191fda..5f3dca8 100644
Binary files a/jdk/.hg/dirstate and b/jdk/.hg/dirstate differ
diff --git a/jdk/.hg/store/00changelog.d b/jdk/.hg/store/00changelog.d
index 228b579..7631017 100644
Binary files a/jdk/.hg/store/00changelog.d and b/jdk/.hg/store/00changelog.d differ
diff --git a/jdk/.hg/store/00changelog.i b/jdk/.hg/store/00changelog.i
index d4a370c..e7375d7 100644
Binary files a/jdk/.hg/store/00changelog.i and b/jdk/.hg/store/00changelog.i differ
diff --git a/jdk/.hg/store/00manifest.d b/jdk/.hg/store/00manifest.d
index 58b7f08..06c6f62 100644
Binary files a/jdk/.hg/store/00manifest.d and b/jdk/.hg/store/00manifest.d differ
diff --git a/jdk/.hg/store/00manifest.i b/jdk/.hg/store/00manifest.i
index 297014f..b720b6f 100644
Binary files a/jdk/.hg/store/00manifest.i and b/jdk/.hg/store/00manifest.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_files.java.i b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_files.java.i
index 5ab311e..d8d0dad 100644
Binary files a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_files.java.i and b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_files.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_module_file.java.i b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_module_file.java.i
index c7b19ed..5e515c6 100644
Binary files a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_module_file.java.i and b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_module_file.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_simple_library.java.i b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_simple_library.java.i
index b7f4144..c3c3112 100644
Binary files a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_simple_library.java.i and b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/_simple_library.java.i differ
diff --git a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/cli/_librarian.java.i b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/cli/_librarian.java.i
index f0553d4..c10919b 100644
Binary files a/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/cli/_librarian.java.i and b/jdk/.hg/store/data/src/share/classes/org/openjdk/jigsaw/cli/_librarian.java.i differ
diff --git a/jdk/.hg/store/data/test/java/lang/reflect/_module/_module_annotation_test.java.i b/jdk/.hg/store/data/test/java/lang/reflect/_module/_module_annotation_test.java.i
index 3f43333..cb3070c 100644
Binary files a/jdk/.hg/store/data/test/java/lang/reflect/_module/_module_annotation_test.java.i and b/jdk/.hg/store/data/test/java/lang/reflect/_module/_module_annotation_test.java.i differ
diff --git a/jdk/.hg/store/data/test/org/openjdk/jigsaw/hello-native.sh.i b/jdk/.hg/store/data/test/org/openjdk/jigsaw/hello-native.sh.i
index 25c20ac..67405b1 100644
Binary files a/jdk/.hg/store/data/test/org/openjdk/jigsaw/hello-native.sh.i and b/jdk/.hg/store/data/test/org/openjdk/jigsaw/hello-native.sh.i differ
diff --git a/jdk/.hg/store/undo b/jdk/.hg/store/undo
index 34785b7..fa033b7 100644
Binary files a/jdk/.hg/store/undo and b/jdk/.hg/store/undo differ
diff --git a/jdk/.hg/undo.desc b/jdk/.hg/undo.desc
index e39fa08..b2060d0 100644
--- a/jdk/.hg/undo.desc
+++ b/jdk/.hg/undo.desc
@@ -1,3 +1,3 @@
-4998
+5001
 pull
 http://hg.openjdk.java.net/jigsaw/jigsaw/jdk
diff --git a/jdk/.hg/undo.dirstate b/jdk/.hg/undo.dirstate
index 93c4205..0191fda 100644
Binary files a/jdk/.hg/undo.dirstate and b/jdk/.hg/undo.dirstate differ
diff --git a/jdk/src/share/classes/org/openjdk/jigsaw/Files.java b/jdk/src/share/classes/org/openjdk/jigsaw/Files.java
index e02e8eb..099c35d 100644
--- a/jdk/src/share/classes/org/openjdk/jigsaw/Files.java
+++ b/jdk/src/share/classes/org/openjdk/jigsaw/Files.java
@@ -26,18 +26,34 @@
 package org.openjdk.jigsaw;
 
 import java.io.*;
-import java.util.*;
 import java.util.jar.*;
 import java.util.zip.*;
 
-
 public final class Files {
 
     private Files() { }
 
-    private static void ensureIsDirectory(File path)
-        throws IOException
-    {
+    // paths are stored with a platform agnostic separator, '/'
+    static String convertSeparator(String path) {
+        return path.replace(File.separatorChar, '/');
+    }
+    
+    static String platformSeparator(String path) {
+        return path.replace('/', File.separatorChar);
+    }
+
+    static void ensureWriteable(File path) throws IOException {
+        if (!path.canWrite())
+            throw new IOException(path + ": is not writeable.");
+    }
+
+    static String ensureNonAbsolute(String path) throws IOException {
+        if ((new File(path)).isAbsolute())
+            throw new IOException("Abolute path instead of relative: " + path);
+        return path;
+    }
+
+    static void ensureIsDirectory(File path) throws IOException {
         if (!path.exists() || !path.isDirectory())
             throw new IOException(path + ": Not a directory");
     }
diff --git a/jdk/src/share/classes/org/openjdk/jigsaw/ModuleFile.java b/jdk/src/share/classes/org/openjdk/jigsaw/ModuleFile.java
index 235fa3c..535660b 100644
--- a/jdk/src/share/classes/org/openjdk/jigsaw/ModuleFile.java
+++ b/jdk/src/share/classes/org/openjdk/jigsaw/ModuleFile.java
@@ -62,6 +62,9 @@ public final class ModuleFile {
         private File destination;
         private boolean deflate;
         private HashType hashtype;
+        private File natlibs;
+        private File natcmds;
+        private File configs;
 
         private static class CountingInputStream extends FilterInputStream {
             int count;
@@ -180,12 +183,22 @@ public final class ModuleFile {
 
         public void readRest() throws IOException {
             extract = false;
-            readRest(null, false);
+            readRest(null, false, null, null, null);
         }
 
         public void readRest(File dst, boolean deflate) throws IOException {
-            this.destination = dst;
+            readRest(dst, deflate, null, null, null);
+        }
+
+        public void readRest(File dst, boolean deflate, File natlibs,
+                             File natcmds, File configs)
+                throws IOException
+        {
             this.deflate = deflate;
+            this.destination = dst != null ? dst.getCanonicalFile() : null;
+            this.natlibs = natlibs != null ? natlibs : new File(destination, "lib");
+            this.natcmds = natcmds != null ? natcmds : new File(destination, "bin");
+            this.configs = configs != null ? configs : new File(destination, "etc");
             try {
                 if (extract)
                     Files.store(moduleInfoBytes, computeRealPath("info"));
@@ -260,14 +273,21 @@ public final class ModuleFile {
 
         public void close() throws IOException {
             try {
-                if (contentStream != null) {
-                    contentStream.close();
-                    contentStream = null;
+                try {
+                    if (contentStream != null) {
+                        contentStream.close();
+                        contentStream = null;
+                    }
+                } finally {
+                    if (fileIn != null) {
+                        fileIn.close();
+                        fileIn = null;
+                    }
                 }
             } finally {
-                if (fileIn != null) {
-                    fileIn.close();
-                    fileIn = null;
+                if (filesWriter != null) {
+                    filesWriter.close();
+                    filesWriter = null;
                 }
             }
         }
@@ -430,7 +450,7 @@ public final class ModuleFile {
             }
 
             if (extract)
-                markNativeCodeExecutable(type, currentPath);
+                postExtract(type, currentPath);
         }
 
         public void readUncompressedFile(DataInputStream in,
@@ -448,7 +468,9 @@ public final class ModuleFile {
                 while ((n = cin.read(buf)) >= 0)
                     out.write(buf, 0, n);
             }
-            markNativeCodeExecutable(type, currentPath);
+            if (extract) {
+                postExtract(type, currentPath);
+            }
          }
 
         public byte[] readModuleInfo(DataInputStream in, int csize)
@@ -469,28 +491,78 @@ public final class ModuleFile {
             return readModuleInfo(in, csize); // signature has the same format
         }
 
-        private File computeRealPath(String storedpath) throws IOException {
+        // Track files installed outside the module library. For later removal.
+        // files are relative to the modules directory.
+        private PrintWriter filesWriter;
 
-            String convertedpath = storedpath.replace('/', File.separatorChar);
-            File path = new File(convertedpath);
+        private void trackFiles(SectionType type, File file)
+            throws IOException
+        {
+            if (file == null || file.toPath().startsWith(destination.toPath()))
+                return;
 
-            // Absolute path names are not permitted.
-            ensureNonAbsolute(path);
-            path = resolveAndNormalize(destination, convertedpath);
-            // Create the parent directories if necessary
-            File parent = path.getParentFile();
-            if (!parent.exists())
-                Files.mkdirs(parent, path.getName());
+            // Lazy construction, not all modules will need this.
+            if (filesWriter == null)
+                filesWriter = new PrintWriter(computeRealPath("files"), "UTF-8");
 
-            return path;
+            filesWriter.println(Files.convertSeparator(relativize(destination, file)));
+            filesWriter.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 files = new File(moduleDir, "files");
+            if (files.exists()) {
+                try (FileInputStream fis = new FileInputStream(files);
+                     InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
+                     BufferedReader in = new BufferedReader(isr)) {
+                    String filename;
+                    while ((filename = in.readLine()) != null)
+                        Files.delete(new File(moduleDir,
+                                              Files.platformSeparator(filename)));
+                }
+            }
+
+            Files.deleteTree(moduleDir);
+        }
+
+        // Returns the absolute path of the given section type.
+        private File getDirOfSection(SectionType type) {
+            if (type == SectionType.NATIVE_LIBS)
+                return natlibs; 
+            else if (type == SectionType.NATIVE_CMDS)
+                return natcmds;
+            else if (type == SectionType.CONFIG)
+                return configs;
+
+            // resolve sub dir section paths against the modules directory
+            return new File(destination, ModuleFile.getSubdirOfSection(type));
         }
 
-        private File computeRealPath(SectionType type,
-                                     String storedpath)
+        private File computeRealPath(String path) throws IOException {
+            return resolveAndNormalize(destination, path);
+        }
+
+        private File computeRealPath(SectionType type, String storedpath)
             throws IOException
         {
-            String dir = getSubdirOfSection(type);
-            return computeRealPath(dir + File.separatorChar + storedpath);
+            File sectionPath = getDirOfSection(type);
+            File realpath = new File(sectionPath,
+                 Files.ensureNonAbsolute(Files.platformSeparator(storedpath)));
+
+            validatePath(sectionPath, realpath);
+
+            // Create the parent directories if necessary
+            File parent = realpath.getParentFile();
+            if (!parent.exists())
+                Files.mkdirs(parent, realpath.getName());
+
+            return realpath;
         }
 
         private static void markNativeCodeExecutable(SectionType type,
@@ -504,6 +576,13 @@ public final class ModuleFile {
                 }
         }
 
+        private void postExtract(SectionType type, File path)
+            throws IOException
+        {
+            markNativeCodeExecutable(type, path);
+            trackFiles(type, path);
+        }
+
         private void unpack200gzip(DataInputStream in) throws IOException {
             GZIPInputStream gis = new GZIPInputStream(in) {
                     public void close() throws IOException {}
@@ -579,11 +658,6 @@ public final class ModuleFile {
         copyStream(in, (DataOutput) new DataOutputStream(out), count);
     }
 
-    private static void ensureNonAbsolute(File path) throws IOException {
-        if (path.isAbsolute())
-            throw new IOException("Abolute path instead of relative: " + path);
-    }
-
     private static void ensureNonNegativity(long size, String parameter) {
         if (size < 0)
             throw new IllegalArgumentException(parameter + "<0: " + size);
@@ -676,6 +750,22 @@ public final class ModuleFile {
         return realpath;
     }
 
+
+    private static String relativize(File directory, File path) throws IOException {
+        return (directory.toPath().relativize(path.toPath().toRealPath())).toString();
+    }
+
+    private static void validatePath(File parent, File child)
+        throws IOException
+    {
+        if (!child.toPath().startsWith(parent.toPath()) )
+            throw new IOException("Bogus relative path: " + child);
+        if (child.exists()) {
+            // conflict, for now just fail
+            throw new IOException("File " + child + " already exists");
+        }
+    }
+
     private static short readHashLength(DataInputStream in) throws IOException {
         final short hashLength = in.readShort();
         ensureNonNegativity(hashLength, "hashLength");
diff --git a/jdk/src/share/classes/org/openjdk/jigsaw/SimpleLibrary.java b/jdk/src/share/classes/org/openjdk/jigsaw/SimpleLibrary.java
index db16870..fc64a37 100644
--- a/jdk/src/share/classes/org/openjdk/jigsaw/SimpleLibrary.java
+++ b/jdk/src/share/classes/org/openjdk/jigsaw/SimpleLibrary.java
@@ -28,6 +28,7 @@ package org.openjdk.jigsaw;
 import java.lang.module.*;
 import java.io.*;
 import java.net.URI;
+import java.nio.file.*;
 import java.security.*;
 import java.security.cert.*;
 import java.util.*;
@@ -70,8 +71,8 @@ public final class SimpleLibrary
         protected final int maxMinorVersion;
         protected int majorVersion;
         protected int minorVersion;
-        private FileConstants.Type type;
-        private File file;
+        private final FileConstants.Type type;
+        private final File file;
 
         protected MetaData(int maxMajor, int maxMinor,
                            FileConstants.Type t, File f)
@@ -86,17 +87,14 @@ public final class SimpleLibrary
             throws IOException;
 
         void store() throws IOException {
-            OutputStream fo = new FileOutputStream(file);
-            DataOutputStream out
-                = new DataOutputStream(new BufferedOutputStream(fo));
-            try {
+            try (OutputStream fos = new FileOutputStream(file);
+                 BufferedOutputStream bos = new BufferedOutputStream(fos);
+                 DataOutputStream out = new DataOutputStream(bos)) {
                 out.writeInt(FileConstants.MAGIC);
                 out.writeShort(type.value());
                 out.writeShort(majorVersion);
                 out.writeShort(minorVersion);
                 storeRest(out);
-            } finally {
-                out.close();
             }
         }
 
@@ -104,15 +102,12 @@ public final class SimpleLibrary
             throws IOException;
 
         protected void load() throws IOException {
-            InputStream fi = new FileInputStream(file);
-            try {
-                DataInputStream in
-                    = new DataInputStream(new BufferedInputStream(fi));
-                int m = in.readInt();
-                if (m != FileConstants.MAGIC)
+            try (InputStream fis = new FileInputStream(file);
+                 BufferedInputStream bis = new BufferedInputStream(fis);
+                 DataInputStream in = new DataInputStream(fis)) {
+                if (in.readInt() != FileConstants.MAGIC)
                     throw new IOException(file + ": Invalid magic number");
-                int typ = in.readShort();
-                if (typ != type.value())
+                if (in.readShort() != type.value())
                     throw new IOException(file + ": Invalid file type");
                 int maj = in.readShort();
                 int min = in.readShort();
@@ -125,13 +120,9 @@ public final class SimpleLibrary
                 minorVersion = min;
                 loadRest(in);
             } catch (EOFException x) {
-                throw new IOException(file + ": Invalid library metadata",
-                                      x);
-            } finally {
-                fi.close();
+                throw new IOException(file + ": Invalid library metadata", x);
             }
         }
-
     }
 
     /**
@@ -153,63 +144,93 @@ public final class SimpleLibrary
         private static final int DEFLATED = 1 << 0;
 
         private File parent;
+        // location of native libs for this library (may be outside the library)
+        // null:default, to use a per-module 'lib' directory
+        private File natlibs;
+        // location of native cmds for this library (may be outside the library)
+        // null:default, to use a per-module 'bin' directory
+        private File natcmds;
+        // location of config files for this library (may be outside the library)
+        // null:default, to use a per-module 'etc' directory
+        private File configs;
         private Set<StorageOption> opts;
 
-        public File parent() { return parent; }
+        public File parent()  { return parent;  }
+        public File natlibs() { return natlibs; }
+        public File natcmds() { return natcmds; }
+        public File configs() { return configs; }
         public boolean isDeflated() {
-           return opts.contains(StorageOption.DEFLATED);
+            return opts.contains(StorageOption.DEFLATED);
         }
 
-        private Header(File root, File p, Set<StorageOption> opts) {
-            super(MAJOR_VERSION, MINOR_VERSION,
+        private Header(File root) {
+             super(MAJOR_VERSION, MINOR_VERSION,
                   FileConstants.Type.LIBRARY_HEADER,
                   new File(root, FILE));
-            this.parent = p;
+        }
+
+        private Header(File root, File parent, File natlibs, File natcmds,
+                       File configs, Set<StorageOption> opts) {
+            this(root);
+            this.parent = parent;
+            this.natlibs = natlibs;
+            this.natcmds = natcmds;
+            this.configs = configs;
             this.opts = new HashSet<>(opts);
         }
 
-        private Header(File root) {
-            this(root, null, Collections.<StorageOption>emptySet());
+        private void storePath(File p, DataOutputStream out) throws IOException {  
+            if (p != null) {
+                out.writeByte(1);
+                out.writeUTF(Files.convertSeparator(p.toString()));
+            } else {
+                out.write(0);
+            }
         }
 
-        protected void storeRest(DataOutputStream out)
-            throws IOException
-        {
+        protected void storeRest(DataOutputStream out) throws IOException {
             int flags = 0;
             if (isDeflated())
                 flags |= DEFLATED;
             out.writeShort(flags);
-            out.writeByte((parent != null) ? 1 : 0);
-            if (parent != null)
-                out.writeUTF(parent.toString());
+            
+            storePath(parent, out);
+            storePath(natlibs, out);
+            storePath(natcmds, out);
+            storePath(configs, out);
+        }
+        
+        private File loadPath(DataInputStream in) throws IOException {  
+            if (in.readByte() != 0)
+                return new File(Files.platformSeparator(in.readUTF()));
+            return null;
         }
 
-        protected void loadRest(DataInputStream in)
-            throws IOException
-        {
+        protected void loadRest(DataInputStream in) throws IOException {
             opts = new HashSet<StorageOption>();
             int flags = in.readShort();
             if ((flags & DEFLATED) == DEFLATED)
                 opts.add(StorageOption.DEFLATED);
-            int b = in.readByte();
-            if (b != 0)
-                parent = new File(in.readUTF());
+            parent = loadPath(in);
+            natlibs = loadPath(in);
+            natcmds = loadPath(in);
+            configs = loadPath(in);
         }
 
-        private static Header load(File f)
-            throws IOException
-        {
+        private static Header load(File f) throws IOException {
             Header h = new Header(f);
             h.load();
             return h;
         }
-
     }
 
     private final File root;
     private final File canonicalRoot;
-    private File parentPath = null;
-    private SimpleLibrary parent = null;
+    private final File parentPath;
+    private final File natlibs;
+    private final File natcmds;
+    private final File configs;
+    private final SimpleLibrary parent;
     private final Header hd;
 
     public String name() { return root.toString(); }
@@ -217,6 +238,9 @@ public final class SimpleLibrary
     public int majorVersion() { return hd.majorVersion; }
     public int minorVersion() { return hd.minorVersion; }
     public SimpleLibrary parent() { return parent; }
+    public File natlibs() { return natlibs; }
+    public File natcmds() { return natcmds; }
+    public File configs() { return configs; }
     public boolean isDeflated() { return hd.isDeflated(); }
 
     private URI location = null;
@@ -233,56 +257,102 @@ public final class SimpleLibrary
                 + ", v" + hd.majorVersion + "." + hd.minorVersion + "]");
     }
 
-    private SimpleLibrary(File path, boolean create, File parentPath, Set<StorageOption> opts)
+
+    private static File resolveAndEnsurePath(File path) throws IOException {
+        if (path == null) { return null; }
+        
+        File p = path.getCanonicalFile();
+        if (!p.exists()) {
+            Files.mkdirs(p, p.toString());
+        } else {
+            Files.ensureIsDirectory(p);
+            Files.ensureWriteable(p);
+        }
+        return p;
+    }
+
+    private File relativize(File path) throws IOException {
+        if (path == null) { return null; }
+        // Return the path relative to the canonical root
+        return (canonicalRoot.toPath().relativize(path.toPath().toRealPath())).toFile();
+    }
+
+    // Opens an existing library
+    private SimpleLibrary(File path) throws IOException {
+        root = path;
+        canonicalRoot = root.getCanonicalFile();
+        Files.ensureIsDirectory(root);
+        hd = Header.load(root);
+        
+        parentPath = hd.parent();
+        parent = parentPath != null ? open(parentPath) : null;
+
+        natlibs = hd.natlibs() == null ? null :
+            new File(canonicalRoot, hd.natlibs().toString()).getCanonicalFile();
+        natcmds = hd.natcmds() == null ? null :
+            new File(canonicalRoot, hd.natcmds().toString()).getCanonicalFile();
+        configs = hd.configs() == null ? null :
+            new File(canonicalRoot, hd.configs().toString()).getCanonicalFile();
+    }
+
+    // Creates a new library
+    private SimpleLibrary(File path, File parentPath, File natlibs, File natcmds,
+                          File configs, Set<StorageOption> opts)
         throws IOException
     {
         root = path;
         canonicalRoot = root.getCanonicalFile();
         if (root.exists()) {
-            if (!root.isDirectory())
-                throw new IOException(root + ": Exists but is not a directory");
-            hd = Header.load(root);
-            if (hd.parent() != null) {
-                parent = open(hd.parent());
-                parentPath = hd.parent();
-            }
-            return;
-        }
-        if (!create)
-            throw new FileNotFoundException(root.toString());
-        if (parentPath != null) {
-            this.parent = open(parentPath);
-            this.parentPath = this.parent.root();
-        }
-        if (!root.mkdirs())
-            throw new IOException(root + ": Cannot create library directory");
-        hd = new Header(canonicalRoot, this.parentPath, opts);
+            Files.ensureIsDirectory(root);
+            if (root.list().length != 0)
+                throw new IOException(root + ": Already Exists");
+            Files.ensureWriteable(root);
+        } else
+            Files.mkdirs(root, root.toString());
+
+        this.parent = parentPath != null ? open(parentPath) : null;
+        this.parentPath = parentPath != null ? this.parent.root() : null;
+
+        this.natlibs = resolveAndEnsurePath(natlibs);
+        this.natcmds = resolveAndEnsurePath(natcmds);
+        this.configs = resolveAndEnsurePath(configs);
+
+        hd = new Header(canonicalRoot, this.parentPath, relativize(this.natlibs),
+                        relativize(this.natcmds), relativize(this.configs), opts);
         hd.store();
     }
 
+    public static SimpleLibrary create(File path, File parent, File natlibs,
+                                       File natcmds, File configs,
+                                       Set<StorageOption> opts)
+        throws IOException
+    {
+        return new SimpleLibrary(path, parent, natlibs, natcmds, configs, opts);
+    }
+
     public static SimpleLibrary create(File path, File parent, Set<StorageOption> opts)
         throws IOException
     {
-        return new SimpleLibrary(path, true, parent, opts);
+        return new SimpleLibrary(path, parent, null, null, null, opts);
     }
 
     public static SimpleLibrary create(File path, File parent)
-        throws IOException 
+        throws IOException
     {
-	return new SimpleLibrary(path, true, parent, Collections.<StorageOption>emptySet());
+	return SimpleLibrary.create(path, parent, Collections.<StorageOption>emptySet());
     }
 
     public static SimpleLibrary create(File path, Set<StorageOption> opts)
         throws IOException
     {
         // ## Should default parent to $JAVA_HOME/lib/modules
-        return new SimpleLibrary(path, true, null, opts);
+        return SimpleLibrary.create(path, null, opts);
     }
 
     public static SimpleLibrary open(File path)
         throws IOException
     {
-        return new SimpleLibrary(path, false, null, Collections.<StorageOption>emptySet());
+        return new SimpleLibrary(path);
     }
 
     private static final JigsawModuleSystem jms
@@ -829,11 +899,11 @@ public final class SimpleLibrary
      * directory.
      */
     private void strip(File md) throws IOException {
-        File classes = new File(md, "classes"); 
+        File classes = new File(md, "classes");
         if (classes.isFile()) {
             File pf = new File(md, "classes.pack");
             try (JarFile jf = new JarFile(classes);
-                FileOutputStream out = new FileOutputStream(pf)) 
+                FileOutputStream out = new FileOutputStream(pf))
             {
                 Pack200.Packer packer = Pack200.newPacker();
                 Map<String,String> p = packer.properties();
@@ -998,13 +1068,13 @@ public final class SimpleLibrary
                 new Signers(md, signers).store();
 
                 // Read and verify the rest of the hashes
-                mr.readRest(md, isDeflated());
+                mr.readRest(md, isDeflated(), natlibs(), natcmds(), configs());
                 mfv.verifyHashesRest(mfvParams);
             } else {
-                mr.readRest(md, isDeflated());
+                mr.readRest(md, isDeflated(), natlibs(), natcmds(), configs());
             }
- 
-            if (strip) 
+
+            if (strip)
                 strip(md);
             reIndex(mid);         // ## Could do this while reading module file
             return mid;
@@ -1012,7 +1082,7 @@ public final class SimpleLibrary
         } catch (IOException | SignatureException x) {
             if (md != null && md.exists()) {
                 try {
-                    Files.deleteTree(md);
+                   ModuleFile.Reader.remove(md);
                 } catch (IOException y) {
                     y.initCause(x);
                     throw y;
@@ -1186,6 +1256,7 @@ public final class SimpleLibrary
         if (mf.getName().endsWith(".jar"))
             mid = installFromJarFile(mf, verifySignature, strip);
         else {
+            // Assume jmod file
             try (FileInputStream in = new FileInputStream(mf)) {
                 mid = install(in, verifySignature, strip);
             }
@@ -1338,10 +1409,14 @@ public final class SimpleLibrary
     public File findLocalNativeLibrary(ModuleId mid, String name)
         throws IOException
     {
-        File md = findModuleDir(mid);
-        if (md == null)
-            return null;
-        File f = new File(new File(md, "lib"), name);
+        File f = natlibs();
+        if (f == null) {
+            f = findModuleDir(mid);
+            if (f == null)
+                return null;
+            f = new File(f, "lib");
+        }
+        f = new File(f, name);
         if (!f.exists())
             return null;
         return f;
diff --git a/jdk/src/share/classes/org/openjdk/jigsaw/cli/Librarian.java b/jdk/src/share/classes/org/openjdk/jigsaw/cli/Librarian.java
index 28cc660..a094c11 100644
--- a/jdk/src/share/classes/org/openjdk/jigsaw/cli/Librarian.java
+++ b/jdk/src/share/classes/org/openjdk/jigsaw/cli/Librarian.java
@@ -32,7 +32,6 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.security.*;
 import java.util.*;
-import java.util.regex.*;
 
 import static java.lang.System.out;
 import static java.lang.System.err;
@@ -47,12 +46,41 @@ public class Librarian {
     private static JigsawModuleSystem jms
         = JigsawModuleSystem.instance();
 
+    private static final File homeLibrary = Library.systemLibraryPath();
+
     static class Create extends Command<SimpleLibrary> {
         protected void go(SimpleLibrary lib)
             throws Command.Exception
         {
             noDry();
             finishArgs();
+            File lp = libPath(opts);
+            File pp = null;
+            if (opts.has(parentPath))
+                pp = opts.valueOf(parentPath);
+            else if (!opts.has("N"))
+                pp = homeLibrary;
+
+            File natlibs = null;
+            if (opts.has(nativeLibs))
+                natlibs = opts.valueOf(nativeLibs);
+            File natcmds = null;
+            if (opts.has(nativeCmds))
+                natcmds = opts.valueOf(nativeCmds);
+            File configs = null;
+            if (opts.has(configFiles))
+                configs = opts.valueOf(configFiles);
+
+            Set<StorageOption> createOpts = new HashSet<>();
+            if (opts.has("z"))
+                createOpts.add(StorageOption.DEFLATED);
+
+            try {
+                lib = SimpleLibrary.create(lp, pp, natlibs, natcmds,
+                                           configs, createOpts);
+            } catch (IOException x) {
+                throw new Command.Exception(x);
+            }
         }
     }
 
@@ -104,6 +132,12 @@ public class Librarian {
             out.format("path %s%n", lib.root());
             out.format("version %d.%d%n",
                        lib.majorVersion(), lib.minorVersion());
+            if (lib.natlibs() != null)
+                out.format("natlibs %s%n", lib.natlibs());
+            if (lib.natcmds() != null)
+                out.format("natcmds %s%n", lib.natcmds());
+            if (lib.configs() != null)
+                out.format("configs %s%n", lib.configs());
             SimpleLibrary plib = lib.parent();
             while (plib != null) {
                 out.format("parent %s%n", plib.root());
@@ -119,23 +153,23 @@ public class Librarian {
             noDry();
             while (hasArg()) {
                 File module = new File(takeArg());
-                File classes = null;
+                File destination = null;
                 try (FileInputStream fis = new FileInputStream(module);
-                     DataInputStream dis = new DataInputStream(fis);
-                     ModuleFile.Reader reader = new ModuleFile.Reader(dis)) {
+                    DataInputStream dis = new DataInputStream(fis);
+                    ModuleFile.Reader reader = new ModuleFile.Reader(dis)) {
 
                     ModuleInfo mi = jms.parseModuleInfo(reader.readStart());
-                    classes = new File(mi.id().name());
-                    Path path = classes.toPath();
+                    destination = new File(mi.id().name());
+                    Path path = destination.toPath();
                     Files.deleteIfExists(path);
                     Files.createDirectory(path);
-                    reader.readRest(classes, false);
+                    reader.readRest(destination, false);
                 }
                 catch (IOException x) {
                     // Try to cleanup if an exception is thrown
-                    if (classes != null && classes.exists())
+                    if (destination != null && destination.exists())
                         try {
-                            FilePaths.deleteTree(classes.toPath());
+                            FilePaths.deleteTree(destination.toPath());
                         }
                         catch (IOException y) {
                             throw (Command.Exception)
@@ -447,7 +481,7 @@ public class Librarian {
             }
         }
     }
-    
+
     private static Map<String,Class<? extends Command<SimpleLibrary>>> commands
         = new HashMap<>();
 
@@ -473,13 +507,19 @@ public class Librarian {
     private OptionParser parser;
 
     private static OptionSpec<Integer> repoIndex; // ##
+    private static OptionSpec<File> libPath;
+    private static OptionSpec<File> parentPath;
+    private static OptionSpec<File> nativeLibs;
+    private static OptionSpec<File> nativeCmds;
+    private static OptionSpec<File> configFiles;
 
     private void usage() {
         out.format("%n");
         out.format("usage: jmod add-repo [-i <index>] URL%n");
         out.format("       jmod extract <module-file> ...%n");
         out.format("       jmod config [<module-id> ...]%n");
-        out.format("       jmod create [-L <library>] [-P <parent>]%n");
+        out.format("       jmod create [-L <library>] [-P <parent>]" +
+                " [--natlib <natlib>] [--natcmd <natcmd>] [--config <config>]%n");
         out.format("       jmod del-repo URL%n");
         out.format("       jmod dump-class <module-id> <class-name> <output-file>%n");
         out.format("       jmod dump-config <module-id>%n");
@@ -510,19 +550,34 @@ public class Librarian {
         parser = new OptionParser();
 
         // ## Need subcommand-specific option parsing
-        OptionSpec<File> libPath
+        libPath
             = (parser.acceptsAll(Arrays.asList("L", "library"),
                                  "Module-library location"
                                  + " (default $JAVA_MODULES)")
                .withRequiredArg()
                .describedAs("path")
                .ofType(File.class));
-        OptionSpec<File> parentPath
+        parentPath
             = (parser.acceptsAll(Arrays.asList("P", "parent-path"),
                                  "Parent module-library location")
                .withRequiredArg()
                .describedAs("path")
                .ofType(File.class));
+        nativeLibs
+            = (parser.accepts("natlib", "Directory to store native libs")
+               .withRequiredArg()
+               .describedAs("dir")
+               .ofType(File.class));
+        nativeCmds
+            = (parser.accepts("natcmd", "Directory to store native launchers")
+               .withRequiredArg()
+               .describedAs("dir")
+               .ofType(File.class));
+        configFiles
+            = (parser.accepts("config", "Directory to store config files")
+               .withRequiredArg()
+               .describedAs("dir")
+               .ofType(File.class));
         parser.acceptsAll(Arrays.asList("N", "no-parent"),
                           "Use no parent library when creating");
         parser.acceptsAll(Arrays.asList("v", "verbose"),
@@ -550,13 +605,10 @@ public class Librarian {
                           + "Treat as unsigned.");
         parser.acceptsAll(Arrays.asList("G", "strip-debug"),
                           "Strip debug attributes during installation");
-        
+
         if (args.length == 0)
             usage();
 
-        File homeLibrary = new File(System.getProperty("java.home"),
-                                    "lib/modules");
-
         OptionSet opts = parser.parse(args);
         if (opts.has("h"))
             usage();
@@ -567,47 +619,30 @@ public class Librarian {
         Class<? extends Command<SimpleLibrary>> cmd = commands.get(verb);
         if (cmd == null)
             throw new Command.Exception("%s: unknown command", verb);
-        File lp = null;
-        if (opts.has(libPath)) {
-            lp = opts.valueOf(libPath);
-        } else {
-            String jm = System.getenv("JAVA_MODULES");
-            if (jm != null)
-                lp = new File(jm);
-            else
-                lp = homeLibrary;
-        }
-        File pp = null;
-        if (opts.has(parentPath)) {
-            pp = opts.valueOf(parentPath);
-        } else if (!opts.has("N")) {
-            pp = homeLibrary;
-        }
+
+        // Every command, except 'create' and 'extract', needs
+        // to have a valid reference to the library
         SimpleLibrary lib = null;
-        try {
-            if (verb.equals("create")) {
-                Set<StorageOption> createOpts = new HashSet<>();
-                if (opts.has("z"))
-                    createOpts.add(StorageOption.DEFLATED);
-                lib = SimpleLibrary.create(lp, pp, createOpts);
-            } else {
-                lib = SimpleLibrary.open(lp);
-            }
-        } catch (FileNotFoundException x) {
-            String msg = null;
-            File f = new File(x.getMessage());
+        if (!(verb.equals("create") || verb.equals("extract"))) {
+            File lp = libPath(opts);
             try {
-                f = f.getCanonicalFile();
-                if (lp.getCanonicalFile().equals(f))
-                    msg = "No such library";
-                else
-                    msg = "Cannot open parent library " + f;
-            } catch (IOException y) {
-                throw new Command.Exception(y);
+                lib = SimpleLibrary.open(lp);
+            } catch (FileNotFoundException x) {
+                String msg = null;
+                File f = new File(x.getMessage());
+                try {
+                    f = f.getCanonicalFile();
+                    if (lp.getCanonicalFile().equals(f))
+                        msg = "No such library";
+                    else
+                        msg = "Cannot open parent library " + f;
+                } catch (IOException y) {
+                    throw new Command.Exception(y);
+                }
+                throw new Command.Exception("%s: %s", lp, msg);
+            } catch (IOException x) {
+                throw new Command.Exception(x);
             }
-            throw new Command.Exception("%s: %s", lp, msg);
-        } catch (IOException x) {
-            throw new Command.Exception(x);
         }
         try {
             cmd.newInstance().run(lib, opts);
@@ -618,6 +653,18 @@ public class Librarian {
         }
     }
 
+    private static File libPath(OptionSet opts) {
+        if (opts.has(libPath)) {
+            return opts.valueOf(libPath);
+        } else {
+            String jm = System.getenv("JAVA_MODULES");
+            if (jm != null)
+                return new File(jm);
+            else
+                return homeLibrary;
+        }
+    }
+
     private Librarian() { }
 
     public static void main(String[] args) {
diff --git a/jdk/test/java/lang/reflect/Module/ModuleAnnotationTest.java b/jdk/test/java/lang/reflect/Module/ModuleAnnotationTest.java
index e0935ee..cebe424 100644
--- a/jdk/test/java/lang/reflect/Module/ModuleAnnotationTest.java
+++ b/jdk/test/java/lang/reflect/Module/ModuleAnnotationTest.java
@@ -53,7 +53,7 @@ public class ModuleAnnotationTest {
 
     public static void main(String[] argv) throws Exception {
         File libPath = new File(argv[0]);
-        Library lb = SimpleLibrary.open(libPath, false);
+        Library lb = SimpleLibrary.open(libPath);
 
         List<ModuleId> mids = lb.findModuleIds("test.foo.bar");
         if (mids.size() != 1)
diff --git a/jdk/test/org/openjdk/jigsaw/hello-native.sh b/jdk/test/org/openjdk/jigsaw/hello-native.sh
index 52f0878..cf97b28 100644
--- a/jdk/test/org/openjdk/jigsaw/hello-native.sh
+++ b/jdk/test/org/openjdk/jigsaw/hello-native.sh
@@ -89,6 +89,9 @@ $BIN/jpkg -d z.test/module-files -m z.test/modules/org.astro \
 $BIN/jmod -L z.lib create
 $BIN/jmod -L z.lib install z.test/module-files/*
 $BIN/java -L z.lib -m com.greetings
+$BIN/jmod -L z.libImageLib create --natlib z.libSpecifyLib_libs
+$BIN/jmod -L z.libImageLib install z.test/module-files/*
+$BIN/java -L z.libImageLib -m com.greetings
 
 exit 0
 

-- 
jigsaw packaging



More information about the pkg-java-commits mailing list