changeset 14290:b9faea9a4ea2

No need to keep copy of packages when adding packages for dyanmic proxies Contributed: claes.redestad@oracle.com, alan.bateman@oracle.com
author alanb
date Mon, 19 Oct 2015 15:20:07 +0100
parents 8e9e10f00315
children 6c27e92c5b03
files src/java.base/share/classes/java/lang/reflect/Module.java
diffstat 1 files changed, 45 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/reflect/Module.java	Mon Oct 19 14:04:34 2015 +0100
+++ b/src/java.base/share/classes/java/lang/reflect/Module.java	Mon Oct 19 15:20:07 2015 +0100
@@ -107,18 +107,15 @@
         this.loader = loader;
         this.descriptor = descriptor;
 
-        Set<String> packages = descriptor.packages();
-        this.packages = packages;
-
         // define module to VM
 
+        Set<String> packages = descriptor.packages();
         int n = packages.size();
         String[] array = new String[n];
         int i = 0;
         for (String pn : packages) {
             array[i++] = pn.replace('.', '/');
         }
-
         Version version = descriptor.version().orElse(null);
         String vs = Objects.toString(version, "");
         String loc = Objects.toString(uri, null);
@@ -153,7 +150,6 @@
         this.name = descriptor.name();
         this.loader = loader;
         this.descriptor = descriptor;
-        this.packages = descriptor.packages();
     }
 
 
@@ -589,9 +585,9 @@
         if (!isNamed())
             return;
 
-        if (!packages.contains(pn)) {
-            throw new IllegalArgumentException("exported package " + pn +
-                " not in contents");
+        if (!containsPackage(pn)) {
+            throw new IllegalArgumentException("package " + pn
+                                               + " not in contents");
         }
 
         synchronized (this) {
@@ -732,9 +728,19 @@
 
     // -- packages --
 
-    // The set of packages in the module if this is a named module.
+    // Additional packages that are added to the module at run-time.
     // The field is volatile as it may be replaced at run-time
-    private volatile Set<String> packages;
+    private volatile Set<String> extraPackages;
+
+    private boolean containsPackage(String pn) {
+        if (descriptor.packages().contains(pn))
+            return true;
+        Set<String> extraPackages = this.extraPackages;
+        if (extraPackages != null && extraPackages.contains(pn))
+            return true;
+        return false;
+    }
+
 
     /**
      * Returns an array of the package names of the packages in this module.
@@ -757,7 +763,17 @@
      */
     public String[] getPackages() {
         if (isNamed()) {
-            return packages.toArray(new String[0]);
+
+            Set<String> packages = descriptor.packages();
+            Set<String> extraPackages = this.extraPackages;
+            if (extraPackages == null) {
+                return packages.toArray(new String[0]);
+            } else {
+                return Stream.concat(packages.stream(),
+                                     extraPackages.stream())
+                        .toArray(String[]::new);
+            }
+
         } else {
             // unnamed module
             Stream<Package> packages;
@@ -802,19 +818,32 @@
             throw new IllegalArgumentException("<unnamed> package not allowed");
 
         synchronized (this) {
-            // copy set
-            Set<String> pns = new HashSet<>(this.packages);
-            if (!pns.add(pn)) {
-                // already has this package
+
+            if (descriptor.packages().contains(pn)) {
+                // already in module
                 return;
             }
 
+            Set<String> extraPackages = this.extraPackages;
+            if (extraPackages != null) {
+                if (extraPackages.contains(pn)) {
+                    // already added
+                    return;
+                }
+
+                // copy the set
+                extraPackages = new HashSet<>(extraPackages);
+                extraPackages.add(pn);
+            } else {
+                extraPackages = Collections.singleton(pn);
+            }
+
             // update VM first, just in case it fails
             if (syncVM)
                 addPackage0(this, pn.replace('.', '/'));
 
             // replace with new set
-            this.packages = pns; // volatile write
+            this.extraPackages = extraPackages; // volatile write
         }
     }