8162782: jlink ResourcePool.releaseProperties should be removed
Reviewed-by: jlaskey, alanb
--- 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
}