8131317: Image writer throws NPE when creating compact profile images
authorjfdenise
Wed, 15 Jul 2015 14:44:52 +0200
changeset 31686 d3da32009b1d
parent 31685 6a6e995cf912
child 31717 df77f0dce68c
8131317: Image writer throws NPE when creating compact profile images Summary: Metadata added to jimage was not handling empty jimage correctly. Reviewed-by: alanb
jdk/src/java.base/share/classes/jdk/internal/jimage/ImageModuleDataWriter.java
jdk/src/java.base/share/classes/jdk/internal/jimage/ImageResourcesTree.java
--- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageModuleDataWriter.java	Wed Jul 15 12:10:03 2015 +0800
+++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageModuleDataWriter.java	Wed Jul 15 14:44:52 2015 +0200
@@ -101,6 +101,13 @@
             PerfectHashBuilder<List<String>> moduleToPackages) {
         ImageStream stream = new ImageStream(writer.getByteOrder());
 
+        // Empty jimage
+        if (packageToModule.getCount() == 0) {
+            stream.putInt(0);
+            stream.putInt(0);
+            return stream.toArray();
+        }
+
         int[] ptmRedirect = packageToModule.getRedirect();
         int[] mtpRedirect = moduleToPackages.getRedirect();
         PerfectHashBuilder.Entry<String>[] ptmOrder = packageToModule.getOrder();
--- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageResourcesTree.java	Wed Jul 15 12:10:03 2015 +0800
+++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageResourcesTree.java	Wed Jul 15 14:44:52 2015 +0200
@@ -61,6 +61,7 @@
         private final Map<String, Node> children = new TreeMap<>();
         private final Node parent;
         private ImageLocationWriter loc;
+        private boolean isResource;
 
         private Node(String name, Node parent) {
             this.name = name;
@@ -141,6 +142,7 @@
                         if (n == null) {
                             n = new Node(s, current);
                             if (i == split.length - 1) { // Leaf
+                                n.isResource = true;
                                 String pkg = toPackageName(n.parent);
                                 if (pkg != null && !pkg.startsWith("META-INF")) {
                                     Set<String> pkgs = moduleToPackage.get(module);
@@ -241,13 +243,6 @@
         public Map<String, Node> getMap() {
             return directAccess;
         }
-
-        private boolean isPackageNode(Node node) {
-            if (!node.children.isEmpty()) {
-                throw new RuntimeException("Node is not a package");
-            }
-            return node.getPath().startsWith("/" + PACKAGES);
-        }
     }
 
     private static final class LocationsAdder {
@@ -271,7 +266,7 @@
                 ret[i] = addLocations(entry.getValue());
                 i += 1;
             }
-            if (current != tree.getRoot() && (ret.length > 0 || tree.isPackageNode(current))) {
+            if (current != tree.getRoot() && !current.isResource) {
                 int size = ret.length * 4;
                 writer.addLocation(current.getPath(), offset, 0, size);
                 offset += size;
@@ -313,11 +308,13 @@
                 byte[] arr = buff.array();
                 content.add(arr);
             } else {
-                if (tree.isPackageNode(current)) {
-                    current.loc = outLocations.get(current.getPath());
-                } else {
+                if (current.isResource) {
+                    // A resource location, remove "/modules"
                     String s = tree.toResourceName(current);
                     current.loc = outLocations.get(s);
+                } else {
+                    // "/packages" leaf node, empty "/packages" or empty "/modules" paths
+                    current.loc = outLocations.get(current.getPath());
                 }
             }
             return current == tree.getRoot() ? 0 : current.loc.getLocationOffset();