src/share/classes/org/openjdk/jigsaw/SimpleLibrary.java

Print this page

        

@@ -37,11 +37,11 @@
 import java.util.jar.*;
 import java.util.zip.*;
 
 import static java.nio.file.StandardCopyOption.*;
 import static java.nio.file.StandardOpenOption.*;
-import org.openjdk.jigsaw.Repository.ModuleType;
+import org.openjdk.jigsaw.Repository.ModuleFileType;
 
 /**
  * A simple module library which stores data directly in the filesystem
  *
  * @see Library

@@ -156,15 +156,21 @@
         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;
+        // target Operating System of this library
+        private String os;
+        // target Architecture of this library
+        private String arch;
 
         public File parent()  { return parent;  }
         public File natlibs() { return natlibs; }
         public File natcmds() { return natcmds; }
         public File configs() { return configs; }
+        public String os()    { return os; }
+        public String arch()  { return arch; }
         public boolean isDeflated() {
             return opts.contains(StorageOption.DEFLATED);
         }
 
         private Header(File root) {

@@ -172,16 +178,19 @@
                   FileConstants.Type.LIBRARY_HEADER,
                   new File(root, FILE));
         }
 
         private Header(File root, File parent, File natlibs, File natcmds,
-                       File configs, Set<StorageOption> opts) {
+                       File configs, Set<StorageOption> opts, String os,
+                       String arch) {
             this(root);
             this.parent = parent;
             this.natlibs = natlibs;
             this.natcmds = natcmds;
             this.configs = configs;
+            this.os = os;
+            this.arch = arch;
             this.opts = new HashSet<>(opts);
         }
 
         private void storePath(File p, DataOutputStream out) throws IOException {
             if (p != null) {

@@ -190,10 +199,20 @@
             } else {
                 out.write(0);
             }
         }
 
+        private void storeUTF(String s, DataOutputStream out) throws IOException {
+            if (s != null) {
+                out.writeByte(1);
+                out.writeUTF(s);
+            } else {
+                out.write(0);
+            }
+        }
+
+        @Override
         protected void storeRest(DataOutputStream out) throws IOException {
             int flags = 0;
             if (isDeflated())
                 flags |= DEFLATED;
             out.writeShort(flags);

@@ -200,27 +219,38 @@
 
             storePath(parent, out);
             storePath(natlibs, out);
             storePath(natcmds, out);
             storePath(configs, out);
+            storeUTF(os, out);
+            storeUTF(arch, out);
         }
 
         private File loadPath(DataInputStream in) throws IOException {
             if (in.readByte() != 0)
                 return new File(Files.platformSeparator(in.readUTF()));
             return null;
         }
 
+        private String loadUTF(DataInputStream in) throws IOException {
+            if (in.readByte() != 0)
+                return in.readUTF();
+            return null;
+        }
+
+        @Override
         protected void loadRest(DataInputStream in) throws IOException {
             opts = new HashSet<StorageOption>();
             int flags = in.readShort();
             if ((flags & DEFLATED) == DEFLATED)
                 opts.add(StorageOption.DEFLATED);
             parent = loadPath(in);
             natlibs = loadPath(in);
             natcmds = loadPath(in);
             configs = loadPath(in);
+            os = loadUTF(in);
+            arch = loadUTF(in);
         }
 
         private static Header load(File f) throws IOException {
             Header h = new Header(f);
             h.load();

@@ -232,10 +262,11 @@
     private final File canonicalRoot;
     private final File parentPath;
     private final File natlibs;
     private final File natcmds;
     private final File configs;
+    private final ModuleArchitecture modArch;
     private final SimpleLibrary parent;
     private final Header hd;
     private final ModuleDictionary moduleDictionary;
     private final File lockf;
     private final File trash;

@@ -246,10 +277,11 @@
     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 ModuleArchitecture architecture() { return modArch; }
     public boolean isDeflated() { return hd.isDeflated(); }
 
     private URI location = null;
     public URI location() {
         if (location == null)

@@ -297,19 +329,21 @@
             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();
+        modArch = ModuleArchitecture.create(hd.os(), hd.arch());
 
         lockf = new File(root, FileConstants.META_PREFIX + "lock");
         trash = new File(root, TRASH);
         moduleDictionary = new ModuleDictionary(root);
     }
 
     // Creates a new library
     private SimpleLibrary(File path, File parentPath, File natlibs, File natcmds,
-                          File configs, Set<StorageOption> opts)
+                          File configs, Set<StorageOption> opts,
+                          ModuleArchitecture modArch)
         throws IOException
     {
         root = path;
         canonicalRoot = root.getCanonicalFile();
         if (root.exists()) {

@@ -324,13 +358,15 @@
         this.parentPath = parentPath != null ? this.parent.root() : null;
 
         this.natlibs = resolveAndEnsurePath(natlibs);
         this.natcmds = resolveAndEnsurePath(natcmds);
         this.configs = resolveAndEnsurePath(configs);
+        this.modArch = modArch;
 
         hd = new Header(canonicalRoot, this.parentPath, relativize(this.natlibs),
-                        relativize(this.natcmds), relativize(this.configs), opts);
+                        relativize(this.natcmds), relativize(this.configs),
+                        opts, modArch.os(), modArch.arch());
         hd.store();
 
         lockf = new File(root, FileConstants.META_PREFIX + "lock");
         lockf.createNewFile();
         trash = new File(root, TRASH);

@@ -339,20 +375,23 @@
         moduleDictionary.store();
     }
 
     public static SimpleLibrary create(File path, File parent, File natlibs,
                                        File natcmds, File configs,
-                                       Set<StorageOption> opts)
+                                       Set<StorageOption> opts,
+                                       ModuleArchitecture modArch)
         throws IOException
     {
-        return new SimpleLibrary(path, parent, natlibs, natcmds, configs, opts);
+        return new SimpleLibrary(path, parent, natlibs, natcmds, configs,
+                                 opts, modArch);
     }
 
     public static SimpleLibrary create(File path, File parent, Set<StorageOption> opts)
         throws IOException
     {
-        return new SimpleLibrary(path, parent, null, null, null, opts);
+        return new SimpleLibrary(path, parent, null, null, null, opts,
+                                 ModuleArchitecture.ANY);
     }
 
     public static SimpleLibrary create(File path, File parent)
         throws IOException
     {

@@ -1185,12 +1224,12 @@
         throws ConfigurationException, IOException
     {
         installFromManifests(mfs, false);
     }
 
-    private ModuleId installWhileLocked(ModuleType type, InputStream is, boolean verifySignature,
-                                        boolean strip) 
+    private ModuleId installWhileLocked(ModuleFileType type, InputStream is,
+                                        boolean verifySignature, boolean strip)
         throws ConfigurationException, IOException, SignatureException
     {
         switch (type) {
             case JAR:
                 Path jf = java.nio.file.Files.createTempFile(null, null);

@@ -1213,10 +1252,17 @@
         BufferedInputStream bin = new BufferedInputStream(is);
         DataInputStream in = new DataInputStream(bin);
         ModuleInfo mi = null;
         try (ModuleFile.Reader mr = new ModuleFile.Reader(in)) {
             ModuleInfo moduleInfo = jms.parseModuleInfo(mr.getModuleInfoBytes());
+
+            // Installee must have the same architecture as the library
+            if (!mr.getArchitecture().matches(architecture()))
+                throw new IOException("Module architecture [" + mr.getArchitecture()
+                                      + "] does not match library ["
+                                      + architecture() + "]");  // ## exception type??
+
             File md = moduleDictionary.add(moduleInfo);
             mi = moduleInfo;
             if (verifySignature && mr.hasSignature()) {
                 // Verify the module signature
                 SignedModule sm = new SignedModule(mr);

@@ -1513,11 +1559,17 @@
             for (ModuleId mid : res.modulesNeeded()) {
                 URI u = res.locationForName.get(mid.name());
                 assert u != null;
                 RemoteRepository rr = repositoryList().firstRepository();
                 assert rr != null;
-                installWhileLocked(rr.fetchMetaData(mid).getType(), 
+                Repository.ModuleFileMetaData mfmd = rr.fetchMetaData(mid);
+                // Installee must have the same architecture as the library
+                if (!mfmd.architecture().matches(architecture()))
+                    throw new IOException("Module architecture [" + mfmd.architecture()
+                                          + "] does not match library ["
+                                          + architecture() + "]");  // ## exception type??
+                installWhileLocked(mfmd.getType(),
                                    rr.fetch(mid), 
                                    verifySignature, 
                                    strip);
                 res.locationForName.put(mid.name(), location());
                 // ## If something goes wrong, delete all our modules