8162782: jlink ResourcePool.releaseProperties should be removed
authorsundar
Tue, 02 Aug 2016 07:19:06 +0530
changeset 39894 cd4f403f9618
parent 39893 56745139718c
child 39895 7cbf99c673d8
8162782: jlink ResourcePool.releaseProperties should be removed Reviewed-by: jlaskey, alanb
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolManager.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePool.java
jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolEntry.java
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java	Tue Aug 02 10:31:05 2016 +0900
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java	Tue Aug 02 07:19:06 2016 +0530
@@ -34,6 +34,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.UncheckedIOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.UncheckedIOException;
@@ -60,6 +61,7 @@
 import jdk.tools.jlink.internal.ExecutableImage;
 import jdk.tools.jlink.plugin.ResourcePool;
 import jdk.tools.jlink.plugin.ResourcePoolEntry;
+import jdk.tools.jlink.plugin.ResourcePoolModule;
 import jdk.tools.jlink.plugin.PluginException;
 
 /**
@@ -144,14 +146,12 @@
         Files.createDirectories(mdir);
     }
 
-    private void storeFiles(Set<String> modules, Map<String, String> release) throws IOException {
+    private void storeFiles(Set<String> modules, Properties release) throws IOException {
         if (release != null) {
-            Properties props = new Properties();
-            props.putAll(release);
-            addModules(props, modules);
+            addModules(release, modules);
             File r = new File(root.toFile(), "release");
             try (FileOutputStream fo = new FileOutputStream(r)) {
-                props.store(fo, null);
+                release.store(fo, null);
             }
         }
     }
@@ -191,7 +191,7 @@
                     modules.add(m.name());
                 }
             });
-            storeFiles(modules, files.releaseProperties());
+            storeFiles(modules, releaseProperties(files));
 
             if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
                 // launchers in the bin directory need execute permission
@@ -219,6 +219,27 @@
         }
     }
 
+    private Properties releaseProperties(ResourcePool pool) throws IOException {
+        Properties props = new Properties();
+        Optional<ResourcePoolModule> javaBase = pool.moduleView().findModule("java.base");
+        javaBase.ifPresent(mod -> {
+            // fill release information available from transformed "java.base" module!
+            ModuleDescriptor desc = mod.descriptor();
+            desc.osName().ifPresent(s -> props.setProperty("OS_NAME", s));
+            desc.osVersion().ifPresent(s -> props.setProperty("OS_VERSION", s));
+            desc.osArch().ifPresent(s -> props.setProperty("OS_ARCH", s));
+        });
+
+        Optional<ResourcePoolEntry> release = pool.findEntry("/java.base/release");
+        if (release.isPresent()) {
+            try (InputStream is = release.get().content()) {
+                props.load(is);
+            }
+        }
+
+        return props;
+    }
+
     /**
      * Generates launcher scripts.
      *
@@ -317,6 +338,8 @@
                 case CONFIG:
                     writeEntry(in, destFile("conf", filename));
                     break;
+                case TOP:
+                    break;
                 case OTHER:
                     if (file instanceof SymImageFile) {
                         SymImageFile sym = (SymImageFile) file;
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java	Tue Aug 02 10:31:05 2016 +0900
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java	Tue Aug 02 07:19:06 2016 +0530
@@ -279,6 +279,8 @@
         private class LastModule implements ResourcePoolModule {
 
             final ResourcePoolModule module;
+            // lazily initialized
+            ModuleDescriptor descriptor;
 
             LastModule(ResourcePoolModule module) {
                 this.module = module;
@@ -297,7 +299,10 @@
 
             @Override
             public ModuleDescriptor descriptor() {
-                return module.descriptor();
+                if (descriptor == null) {
+                    descriptor = ResourcePoolManager.readModuleDescriptor(this);
+                }
+                return descriptor;
             }
 
             @Override
@@ -420,11 +425,6 @@
             return pool.byteOrder();
         }
 
-        @Override
-        public Map<String, String> releaseProperties() {
-            return pool.releaseProperties();
-        }
-
         private ResourcePoolEntry getUncompressed(ResourcePoolEntry res) {
             if (res != null) {
                 if (res instanceof ResourcePoolManager.CompressedModuleData) {
@@ -458,18 +458,6 @@
             throws Exception {
         Objects.requireNonNull(original);
         Objects.requireNonNull(transformed);
-        Optional<ResourcePoolModule> javaBase = transformed.moduleView().findModule("java.base");
-        javaBase.ifPresent(mod -> {
-            try {
-                Map<String, String> release = transformed.releaseProperties();
-                // fill release information available from transformed "java.base" module!
-                ModuleDescriptor desc = mod.descriptor();
-                desc.osName().ifPresent(s -> release.put("OS_NAME", s));
-                desc.osVersion().ifPresent(s -> release.put("OS_VERSION", s));
-                desc.osArch().ifPresent(s -> release.put("OS_ARCH", s));
-            } catch (Exception ignored) {}
-        });
-
         imageBuilder.storeFiles(new LastPoolManager(transformed).resourcePool());
     }
 
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolManager.java	Tue Aug 02 10:31:05 2016 +0900
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolManager.java	Tue Aug 02 07:19:06 2016 +0530
@@ -50,10 +50,22 @@
  * A manager for pool of resources.
  */
 public class ResourcePoolManager {
+    // utility to read ModuleDescriptor of the given ResourcePoolModule
+    static ModuleDescriptor readModuleDescriptor(ResourcePoolModule mod) {
+        String p = "/" + mod.name() + "/module-info.class";
+        Optional<ResourcePoolEntry> content = mod.findEntry(p);
+        if (!content.isPresent()) {
+              throw new PluginException("No module-info for " + mod.name()
+                      + " module");
+        }
+        ByteBuffer bb = ByteBuffer.wrap(content.get().contentBytes());
+        return ModuleDescriptor.read(bb);
+    }
 
     class ResourcePoolModuleImpl implements ResourcePoolModule {
 
         final Map<String, ResourcePoolEntry> moduleContent = new LinkedHashMap<>();
+        // lazily initialized
         private ModuleDescriptor descriptor;
         final String name;
 
@@ -80,14 +92,7 @@
         @Override
         public ModuleDescriptor descriptor() {
             if (descriptor == null) {
-                String p = "/" + name + "/module-info.class";
-                Optional<ResourcePoolEntry> content = findEntry(p);
-                if (!content.isPresent()) {
-                    throw new PluginException("No module-info for " + name
-                            + " module");
-                }
-                ByteBuffer bb = ByteBuffer.wrap(content.get().contentBytes());
-                descriptor = ModuleDescriptor.read(bb);
+                descriptor = readModuleDescriptor(this);
             }
             return descriptor;
         }
@@ -166,11 +171,6 @@
             return ResourcePoolManager.this.byteOrder();
         }
 
-        @Override
-        public Map<String, String> releaseProperties() {
-            return ResourcePoolManager.this.releaseProperties();
-        }
-
         public StringTable getStringTable() {
             return ResourcePoolManager.this.getStringTable();
         }
@@ -214,7 +214,6 @@
     private final Map<String, ResourcePoolEntry> resources = new LinkedHashMap<>();
     private final Map<String, ResourcePoolModule> modules = new LinkedHashMap<>();
     private final ResourcePoolModuleImpl fileCopierModule = new ResourcePoolModuleImpl(FileCopierPlugin.FAKE_MODULE);
-    private Map<String, String> releaseProps = new HashMap<>();
     private final ByteOrder order;
     private final StringTable table;
     private final ResourcePool poolImpl;
@@ -391,10 +390,6 @@
         return order;
     }
 
-    public Map<String, String> releaseProperties() {
-        return releaseProps;
-    }
-
     public StringTable getStringTable() {
         return table;
     }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java	Tue Aug 02 10:31:05 2016 +0900
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java	Tue Aug 02 07:19:06 2016 +0530
@@ -24,17 +24,23 @@
  */
 package jdk.tools.jlink.internal.plugins;
 
+import java.io.ByteArrayOutputStream;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.lang.module.ModuleDescriptor;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Properties;
 import java.util.Set;
 import java.util.function.Function;
 import jdk.tools.jlink.internal.Utils;
 import jdk.tools.jlink.plugin.ResourcePool;
 import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry;
+import jdk.tools.jlink.plugin.ResourcePoolModule;
 import jdk.tools.jlink.plugin.Plugin.Category;
 import jdk.tools.jlink.plugin.Plugin.State;
 import jdk.tools.jlink.plugin.Plugin;
@@ -119,7 +125,23 @@
 
     @Override
     public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
-        in.releaseProperties().putAll(release);
-        return in;
+        in.transformAndCopy(Function.identity(), out);
+
+        // create a TOP level ResourcePoolEntry for "release" file.
+        out.add(ResourcePoolEntry.create("/java.base/release",
+            ResourcePoolEntry.Type.TOP, releaseFileContent()));
+        return out.build();
+    }
+
+    private byte[] releaseFileContent() {
+        Properties props = new Properties();
+        props.putAll(release);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            props.store(baos, "");
+            return baos.toByteArray();
+        } catch (IOException ex) {
+            throw new UncheckedIOException(ex);
+        }
     }
 }
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePool.java	Tue Aug 02 10:31:05 2016 +0900
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePool.java	Tue Aug 02 07:19:06 2016 +0530
@@ -95,13 +95,6 @@
     public ByteOrder byteOrder();
 
     /**
-     * Release properties such as OS, CPU name, version etc.
-     *
-     * @return the release properties
-     */
-    public Map<String, String> releaseProperties();
-
-    /**
      * Visit each ResourcePoolEntry in this ResourcePool to transform it and copy
      * the transformed ResourcePoolEntry to the output ResourcePoolBuilder.
      *
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolEntry.java	Tue Aug 02 10:31:05 2016 +0900
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolEntry.java	Tue Aug 02 07:19:06 2016 +0530
@@ -41,6 +41,7 @@
  * <ul>
  * <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
  * name}</li>
+ * <li>For top-level files:/{module name}/{file name}</li>
  * <li>For other files (shared lib, launchers, config, ...):/{module name}/
  * {@literal bin|conf|native}/{dir1}/.../{dirN}/{file name}</li>
  * </ul>
@@ -54,6 +55,7 @@
      * <ul>CONFIG: A configuration file.</ul>
      * <ul>NATIVE_CMD: A native process launcher.</ul>
      * <ul>NATIVE_LIB: A native library.</ul>
+     * <ul>TOP: A top-level file in the jdk run-time image directory.</ul>
      * <ul>OTHER: Other kind of file.</ul>
      * </li>
      */
@@ -62,6 +64,7 @@
         CONFIG,
         NATIVE_CMD,
         NATIVE_LIB,
+        TOP,
         OTHER
     }