changeset 7706:9ddaf93af7e6

Enhance error messages, add some access tests, minor changes
author hseigel
date Fri, 16 Jan 2015 11:33:05 -0500
parents ab477cad991a
children 8b04c6444f29
files src/share/vm/ci/ciEnv.cpp src/share/vm/classfile/classFileParser.cpp src/share/vm/classfile/modules.cpp src/share/vm/classfile/packageEntry.cpp src/share/vm/classfile/packageEntry.hpp src/share/vm/interpreter/linkResolver.cpp src/share/vm/prims/methodHandles.cpp src/share/vm/runtime/reflection.cpp src/share/vm/runtime/reflection.hpp test/runtime/modules/AccessCheckExp.java test/runtime/modules/AccessCheckRead.java test/runtime/modules/AccessCheckSuper.java test/runtime/modules/AccessCheckToUnnamed.java test/runtime/modules/AccessCheckUnnamed.java test/runtime/modules/AccessCheckWorks.java test/runtime/modules/ExportTwice.java test/runtime/modules/p1/c1.java test/runtime/modules/p2/c2.java
diffstat 18 files changed, 817 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/ci/ciEnv.cpp	Mon Jan 12 16:24:19 2015 -0500
+++ b/src/share/vm/ci/ciEnv.cpp	Fri Jan 16 11:33:05 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -370,9 +370,9 @@
     resolved_klass = ObjArrayKlass::cast(resolved_klass)->bottom_klass();
   }
   if (resolved_klass->oop_is_instance()) {
-    return Reflection::verify_class_access(accessing_klass->get_Klass(),
-                                           resolved_klass,
-                                           true);
+    return (Reflection::verify_class_access(accessing_klass->get_Klass(),
+                                            resolved_klass,
+                                            true) == Reflection::ACCESS_OK);
   }
   return true;
 }
--- a/src/share/vm/classfile/classFileParser.cpp	Mon Jan 12 16:24:19 2015 -0500
+++ b/src/share/vm/classfile/classFileParser.cpp	Fri Jan 16 11:33:05 2015 -0500
@@ -4646,17 +4646,29 @@
 
 void ClassFileParser::check_super_class_access(instanceKlassHandle this_klass, TRAPS) {
   Klass* super = this_klass->super();
-  if ((super != NULL) &&
-      (!Reflection::verify_class_access(this_klass(), super, false))) {
-    ResourceMark rm(THREAD);
-    Exceptions::fthrow(
-      THREAD_AND_LOCATION,
-      vmSymbols::java_lang_IllegalAccessError(),
-      "class %s cannot access its superclass %s",
-      this_klass->external_name(),
-      InstanceKlass::cast(super)->external_name()
-    );
-    return;
+  if (super != NULL) {
+    Reflection::VerifyClassAccessResults vca_result =
+      Reflection::verify_class_access(this_klass(), super, false);
+    if (vca_result != Reflection::ACCESS_OK) {
+      ResourceMark rm(THREAD);
+      char* msg =  Reflection::verify_class_access_msg(this_klass(), super, vca_result);
+      if (msg == NULL) {
+        Exceptions::fthrow(
+          THREAD_AND_LOCATION,
+          vmSymbols::java_lang_IllegalAccessError(),
+          "class %s cannot access its superclass %s",
+          this_klass->external_name(),
+          InstanceKlass::cast(super)->external_name());
+      } else {
+        // Add additional message content.
+        Exceptions::fthrow(
+          THREAD_AND_LOCATION,
+          vmSymbols::java_lang_IllegalAccessError(),
+          "superclass access check failed: %s",
+          msg);
+      }
+      return;
+    }
   }
 }
 
@@ -4667,15 +4679,26 @@
   for (int i = lng - 1; i >= 0; i--) {
     Klass* k = local_interfaces->at(i);
     assert (k != NULL && k->is_interface(), "invalid interface");
-    if (!Reflection::verify_class_access(this_klass(), k, false)) {
+    Reflection::VerifyClassAccessResults vca_result =
+      Reflection::verify_class_access(this_klass(), k, false);
+    if (vca_result != Reflection::ACCESS_OK) {
       ResourceMark rm(THREAD);
-      Exceptions::fthrow(
-        THREAD_AND_LOCATION,
-        vmSymbols::java_lang_IllegalAccessError(),
-        "class %s cannot access its superinterface %s",
-        this_klass->external_name(),
-        InstanceKlass::cast(k)->external_name()
-      );
+      char* msg =  Reflection::verify_class_access_msg(this_klass(), k, vca_result);
+      if (msg == NULL) {
+        Exceptions::fthrow(
+          THREAD_AND_LOCATION,
+          vmSymbols::java_lang_IllegalAccessError(),
+          "class %s cannot access its superinterface %s",
+          this_klass->external_name(),
+          InstanceKlass::cast(k)->external_name());
+      } else {
+        // Add additional message content.
+        Exceptions::fthrow(
+          THREAD_AND_LOCATION,
+          vmSymbols::java_lang_IllegalAccessError(),
+          "superinterface check failed: %s",
+          msg);
+      }
       return;
     }
   }
--- a/src/share/vm/classfile/modules.cpp	Mon Jan 12 16:24:19 2015 -0500
+++ b/src/share/vm/classfile/modules.cpp	Fri Jan 16 11:33:05 2015 -0500
@@ -369,10 +369,10 @@
   }
 
   // If this is a qualified export, make sure the entry has not already been exported
-  // unqualifically.
+  // unqualifiedly.
   if (to_module_entry != NULL && package_entry->is_unqual_exported()) {
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-              err_msg("Bad qualifed export, package %s in module %s is already unqualifically exported",
+              err_msg("Bad qualifed export, package %s in module %s is already unqualifiedly exported",
                       package_entry->name()->as_C_string(),
                       from_module_entry->name()->as_C_string()));
   }
--- a/src/share/vm/classfile/packageEntry.cpp	Mon Jan 12 16:24:19 2015 -0500
+++ b/src/share/vm/classfile/packageEntry.cpp	Fri Jan 16 11:33:05 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,22 +65,22 @@
   }
 
   if (m == NULL) {
-    // NULL indicates the package is being unqualifically exported
+    // NULL indicates the package is being unqualifiedly exported
     if (_is_exported && _qualified_exports != NULL) {
-      // Legit to transition a package from being qualifically exported
+      // Legit to transition a package from being qualifiedly exported
       // to unqualified.  Clean up the qualified lists at the next
       // safepoint.
       _exported_pending_delete = _qualified_exports;
     }
 
-    // Mark package as unqualifically exported
+    // Mark package as unqualifiedly exported
     _is_exported = true;
     _qualified_exports = NULL;
 
   } else {
     if (_is_exported && _qualified_exports == NULL) {
       // An exception could be thrown, but choose to simply ignore.
-      // Illegal to convert an unqualified exported package to be qualifically exported
+      // Illegal to convert an unqualified exported package to be qualifiedly exported
       return;
     }
 
@@ -168,7 +168,7 @@
   if (module == NULL) {
     // Indicates the unnamed module.
     // Set the exported state to true because all packages
-    // within the unnamed module are unqualifically exported
+    // within the unnamed module are unqualifiedly exported
     entry->set_exported(true);
   } else {
     entry->set_module(module);
--- a/src/share/vm/classfile/packageEntry.hpp	Mon Jan 12 16:24:19 2015 -0500
+++ b/src/share/vm/classfile/packageEntry.hpp	Fri Jan 16 11:33:05 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,8 +36,8 @@
 //     NULL if the package was defined within the unnamed module.
 //   - a growable array containing other module entries that this
 //     package is exported to.
-//   - a flag indicating if package is exported, either qualifically or
-//     unqualifically.
+//   - a flag indicating if package is exported, either qualifiedly or
+//     unqualifiedly.
 //
 // Packages that are:
 //   - not exported:        _qualified_exports = NULL  && _is_exported is false
@@ -68,7 +68,7 @@
   void               set_module(ModuleEntry* m) { _module = m; }
 
   // package's export state
-  bool               is_exported() const                 { return _is_exported; } // qualifically or unqualifically exported
+  bool               is_exported() const                 { return _is_exported; } // qualifiedly or unqualifiedly exported
   bool               is_qual_exported() const            { return (_is_exported && (_qualified_exports != NULL)); }
   bool               is_unqual_exported() const          { return (_is_exported && (_qualified_exports == NULL)); }
   bool               exported_pending_delete() const     { return (_exported_pending_delete != NULL); }
--- a/src/share/vm/interpreter/linkResolver.cpp	Mon Jan 12 16:24:19 2015 -0500
+++ b/src/share/vm/interpreter/linkResolver.cpp	Fri Jan 16 11:33:05 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -215,18 +215,25 @@
 // Klass resolution
 
 void LinkResolver::check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS) {
-  if (!Reflection::verify_class_access(ref_klass(),
-                                       sel_klass(),
-                                       true)) {
+  Reflection::VerifyClassAccessResults vca_result =
+    Reflection::verify_class_access(ref_klass(), sel_klass(), true);
+  if (vca_result != Reflection::ACCESS_OK) {
     ResourceMark rm(THREAD);
-    Exceptions::fthrow(
-      THREAD_AND_LOCATION,
-      vmSymbols::java_lang_IllegalAccessError(),
-      "tried to access class %s from class %s",
-      sel_klass->external_name(),
-      ref_klass->external_name()
-    );
-    return;
+    char* msg = Reflection::verify_class_access_msg(ref_klass(), sel_klass(), vca_result);
+    if (msg == NULL) {
+      Exceptions::fthrow(
+        THREAD_AND_LOCATION,
+        vmSymbols::java_lang_IllegalAccessError(),
+        "failed to access class %s from class %s",
+        sel_klass->external_name(),
+        ref_klass->external_name());
+    } else {
+      // Use module specific message returned by verify_class_access_msg().
+      Exceptions::fthrow(
+        THREAD_AND_LOCATION,
+        vmSymbols::java_lang_IllegalAccessError(),
+        "%s", msg);
+    }
   }
 }
 
--- a/src/share/vm/prims/methodHandles.cpp	Mon Jan 12 16:24:19 2015 -0500
+++ b/src/share/vm/prims/methodHandles.cpp	Fri Jan 16 11:33:05 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1104,9 +1104,9 @@
     if (reference_klass != NULL && reference_klass->oop_is_instance()) {
       // Emulate LinkResolver::check_klass_accessability.
       Klass* caller = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh));
-      if (!Reflection::verify_class_access(caller,
-                                           reference_klass,
-                                           true)) {
+      if (Reflection::verify_class_access(caller,
+                                          reference_klass,
+                                          true) != Reflection::ACCESS_OK) {
         THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), reference_klass->external_name());
       }
     }
--- a/src/share/vm/runtime/reflection.cpp	Mon Jan 12 16:24:19 2015 -0500
+++ b/src/share/vm/runtime/reflection.cpp	Fri Jan 16 11:33:05 2015 -0500
@@ -411,19 +411,21 @@
   return result;
 }
 
-bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, bool classloader_only) {
+Reflection::VerifyClassAccessResults Reflection::verify_class_access(
+  Klass* current_class, Klass* new_class, bool classloader_only) {
+
   // Verify that current_class can access new_class.  If the classloader_only
   // flag is set, we automatically allow any accesses in which current_class
   // doesn't have a classloader.
   if ((current_class == NULL) ||
       (current_class == new_class) ||
       is_same_class_package(current_class, new_class)) {
-    return true;
+    return ACCESS_OK;
   }
   // Allow all accesses from sun/reflect/MagicAccessorImpl subclasses to
   // succeed trivially.
   if (current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) {
-    return true;
+    return ACCESS_OK;
   }
 
   // module boundaries
@@ -431,7 +433,7 @@
     // Ignore modules for DumpSharedSpaces because we do not have any package
     // or module information for modules other than java.base.
     if (!UseModules || DumpSharedSpaces) {
-      return true;
+      return ACCESS_OK;
     }
 
     // Find the module entry for current_class, the accessor
@@ -448,63 +450,132 @@
 
     // both in same module or unnamed module.
     if (module_from == module_to)
-      return true;
+      return ACCESS_OK;
 
     // Acceptable access to a type in the unamed module.
     if (module_to == NULL)
-      return true;
+      return ACCESS_OK;
 
     // Establish readability, check if module_from is allowed to read module_to.
     if (module_from != NULL && !module_from->can_read(module_to)) {
       if (TraceAccessControlErrors) {
         ResourceMark rm;
-        tty->print_cr("Type in module %s (%s) cannot access type in module %s (%s), not readable",
+        tty->print_cr("Type in module %s (%s) can not access type in module %s (%s), not readable",
           module_from->name()->as_C_string(), current_class->external_name(),
           module_to->name()->as_C_string(), new_class->external_name());
       }
-      return false;
+      return MODULE_NOT_READABLE;
     }
 
     PackageEntry* package_to = InstanceKlass::cast(new_class)->package();
-    assert(package_to != NULL, "cannot obtain new_class' package");
+    assert(package_to != NULL, "can not obtain new_class' package");
 
-    // Once readability is established, if module_to exports T unqualifically,
+    // Once readability is established, if module_to exports T unqualifiedly,
     // (to all modules), than whether module_from is in the unnamed module
     // or not does not matter, access is allowed.
     if (package_to->is_unqual_exported()) {
-      return true;
+      return ACCESS_OK;
     }
 
     if (module_from != NULL) {
       // Check the case where module_from, the requester, is in a named module.
       // Access is allowed if both 1 & 2 hold:
       //   1. Readability, module_from can read module_to (established above).
-      //   2. Either module_to exports T to module_from qualifically.
+      //   2. Either module_to exports T to module_from qualifiedly.
       //      or
-      //      module_to exports T unqualifically to all modules (checked above).
+      //      module_to exports T unqualifiedly to all modules (checked above).
       bool okay = package_to->is_qexported_to(module_from);
-      if (!okay && TraceAccessControlErrors) {
-        ResourceMark rm;
-        tty->print_cr("Type in module %s (%s) cannot access type in module %s (%s), not exported",
-          module_from->name()->as_C_string(), current_class->external_name(),
-          module_to->name()->as_C_string(), new_class->external_name());
+      if (!okay) {
+        if (TraceAccessControlErrors) {
+          ResourceMark rm;
+          tty->print_cr("Type in module %s (%s) can not access type in module %s (%s), not exported",
+            module_from->name()->as_C_string(), current_class->external_name(),
+            module_to->name()->as_C_string(), new_class->external_name());
+        }
+        return TYPE_NOT_EXPORTED;
       }
-      return okay;
+      return ACCESS_OK;
     } else {
       // Check the case where module_from, the requester, is in the unnamed module.
       // Access is allowed if both 1 & 2 hold:
       //   1. Readability, unnamed module can read all modules.
-      //   2. module_to exports T unqualifically to all modules (checked above).
+      //   2. module_to exports T unqualifiedly to all modules (checked above).
       if (TraceAccessControlErrors) {
         ResourceMark rm;
-        tty->print_cr("Type in the unnamed module (%s) cannot access type in module %s (%s), not unqualifically exported",
+        tty->print_cr("Type in the unnamed module (%s) can not access type in module %s (%s), not unqualifiedly exported",
           current_class->external_name(), module_to->name()->as_C_string(), new_class->external_name());
       }
-      return false;
+      return TYPE_NOT_UNQ_EXPORTED;
     }
   }
 
-  return can_relax_access_check_for(current_class, new_class, classloader_only);
+  if (can_relax_access_check_for(current_class, new_class, classloader_only)) {
+    return ACCESS_OK;
+  }
+  return OTHER_PROBLEM;
+}
+
+// Return an error message specific to the specified Klass*'s and result.
+// This function must be called from within a block containing a ResourceMark.
+char* Reflection::verify_class_access_msg(Klass* current_class,
+                                          Klass* new_class,
+                                          VerifyClassAccessResults result) {
+  assert(result != ACCESS_OK, "must be failure result");
+  char * msg = NULL;
+  if (result != OTHER_PROBLEM && new_class != NULL && current_class != NULL) {
+    ModuleEntry* module_to = InstanceKlass::cast(new_class)->module();
+    if (module_to != NULL) {
+      const char * new_class_name = new_class->external_name();
+      const char * current_class_name = current_class->external_name();
+      char * module_to_name = module_to->name()->as_C_string();
+      size_t len = 120 + strlen(current_class_name) + strlen(new_class_name) +
+        strlen(module_to_name);
+
+      if (result == TYPE_NOT_UNQ_EXPORTED) {
+        if (InstanceKlass::cast(new_class)->package() != NULL) {
+          const char * package_name =
+            InstanceKlass::cast(new_class)->package()->name()->as_klass_external_name();
+          len = len + strlen(package_name);
+          msg = NEW_RESOURCE_ARRAY(char, len);
+          jio_snprintf(msg, len - 1,
+            "class %s (in module: unnamed), can not access class %s (in module: %s), %s is not exported to the unnamed module",
+            current_class_name, new_class_name, module_to_name, package_name);
+        }
+
+      } else {
+        ModuleEntry* module_from = InstanceKlass::cast(current_class)->module();
+        if (module_from != NULL) {
+          char * module_from_name = module_from->name()->as_C_string();
+          len = len + 2 * strlen(module_from_name);
+
+          if (result == MODULE_NOT_READABLE) {
+            len = len + strlen(module_to_name);
+            msg = NEW_RESOURCE_ARRAY(char, len);
+            jio_snprintf(msg, len - 1,
+              "class %s in module %s can not access class %s in module %s, %s can not read %s",
+              current_class_name, module_from_name, new_class_name,
+              module_to_name, module_from_name, module_to_name);
+
+          } else if (result == TYPE_NOT_EXPORTED) {
+            if (InstanceKlass::cast(new_class)->package() != NULL) {
+              const char * package_name =
+                InstanceKlass::cast(new_class)->package()->name()->as_klass_external_name();
+              len = len + strlen(package_name);
+              msg = NEW_RESOURCE_ARRAY(char, len);
+              jio_snprintf(msg, len - 1,
+                "class %s (in module: %s), can not access class %s (in module: %s), %s is not exported to %s",
+                current_class_name, module_from_name, new_class_name,
+                module_to_name, package_name, module_from_name);
+            }
+
+          } else {
+            ShouldNotReachHere();
+          }
+        }  // module_from != NULL
+      }
+    }  // module_to != NULL
+  }  // result != OTHER_PROBLEM...
+  return msg;
 }
 
 static bool under_host_klass(InstanceKlass* ik, Klass* host_klass) {
--- a/src/share/vm/runtime/reflection.hpp	Mon Jan 12 16:24:19 2015 -0500
+++ b/src/share/vm/runtime/reflection.hpp	Fri Jan 16 11:33:05 2015 -0500
@@ -63,6 +63,15 @@
     MAX_DIM           = 255
   };
 
+  // Results returned by verify_class_access()
+  enum VerifyClassAccessResults {
+    ACCESS_OK = 0,
+    MODULE_NOT_READABLE = 1,
+    TYPE_NOT_EXPORTED = 2,
+    TYPE_NOT_UNQ_EXPORTED = 3,
+    OTHER_PROBLEM = 4
+  };
+
   // Boxing. Returns boxed value of appropriate type. Throws IllegalArgumentException.
   static oop box(jvalue* v, BasicType type, TRAPS);
   // Unboxing. Returns type code and sets value.
@@ -83,7 +92,15 @@
   static arrayOop reflect_new_multi_array(oop element_mirror, typeArrayOop dimensions, TRAPS);
 
   // Verification
-  static bool     verify_class_access(Klass* current_class, Klass* new_class, bool classloader_only);
+  static VerifyClassAccessResults verify_class_access(Klass* current_class,
+                                                      Klass* new_class,
+                                                      bool classloader_only);
+
+  // Return an error message specific to the specified Klass*'s and result.
+  // This function must be called from within a block containing a ResourceMark.
+  static char*    verify_class_access_msg(Klass* current_class,
+                                          Klass* new_class,
+                                          VerifyClassAccessResults result);
 
   static bool     verify_field_access(Klass* current_class,
                                       Klass* resolved_class,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/AccessCheckExp.java	Fri Jan 16 11:33:05 2015 -0500
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /testlibrary /../../test/lib /compiler/whitebox ..
+ * @compile p2/c2.java
+ * @compile p1/c1.java
+ * @build AccessCheckExp
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI AccessCheckExp
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.lang.reflect.Module;
+import sun.hotspot.WhiteBox;
+import static com.oracle.java.testlibrary.Asserts.*;
+
+public class AccessCheckExp {
+
+    // Test that if module1 can read module2, but package p2 in module2 is not
+    // exported then class p1.c1 in module1 can not read p2.c2 in module2.
+    public static void main(String args[]) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        Object m1, m2;
+
+        // Get the java.lang.reflect.Module object for module java.base.
+        Class jlObject = Class.forName("java.lang.Object");
+        Object jlObject_jlrM = jlObject.getModule();
+        assertNotNull(jlObject_jlrM, "jlrModule object of java.lang.Object should not be null");
+
+        // Get the class loader for AccessCheckExp and assume it's also used to
+        // load classes p1.c1 and p2.c2.
+        ClassLoader this_cldr = AccessCheckExp.class.getClassLoader();
+
+        // Define a module for p1.
+        m1 = wb.DefineModule("module1", this_cldr, new String[] { "p1" });
+        assertNotNull(m1, "Module should not be null");
+        wb.AddReadsModule(m1, jlObject_jlrM);
+
+        // Define a module for p2.
+        m2 = wb.DefineModule("module2", this_cldr, new String[] { "p2" });
+        assertNotNull(m2, "Module should not be null");
+        wb.AddReadsModule(m2, jlObject_jlrM);
+
+        // Make package p1 in m1 visible to everyone.
+        wb.AddModuleExports(m1, "p1", null);
+
+        // p1.c1's ctor tries to call a method in p2.c2, but p2.c2 is not
+        // exported.  So should get IllegalAccessError.
+        wb.AddReadsModule(m1, m2);
+
+        Class p1_c1_class = Class.forName("p1.c1");
+        try {
+            p1_c1_class.newInstance();
+            throw new RuntimeException("Failed to get IAE (p2 in m2 is not exported");
+        } catch (IllegalAccessError f) {
+            System.out.println(f.getMessage());
+            if (!f.getMessage().contains("not exported")) {
+                throw new RuntimeException("Wrong message: " + f.getMessage());
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/AccessCheckRead.java	Fri Jan 16 11:33:05 2015 -0500
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /testlibrary /../../test/lib /compiler/whitebox ..
+ * @compile p2/c2.java
+ * @compile p1/c1.java
+ * @build AccessCheckRead
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI AccessCheckRead
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.lang.reflect.Module;
+import sun.hotspot.WhiteBox;
+import static com.oracle.java.testlibrary.Asserts.*;
+
+public class AccessCheckRead {
+
+    // Test that a class in a package in module1 can not access a class in
+    // a package n module2 if module1 can not read module2.
+    public static void main(String args[]) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        Object m1, m2;
+
+        // Get the java.lang.reflect.Module object for module java.base.
+        Class jlObject = Class.forName("java.lang.Object");
+        Object jlObject_jlrM = jlObject.getModule();
+        assertNotNull(jlObject_jlrM, "jlrModule object of java.lang.Object should not be null");
+
+        // Get the class loader for AccessCheckRead and assume it's also used to
+        // load classes p1.c1 and p2.c2.
+        ClassLoader this_cldr = AccessCheckRead.class.getClassLoader();
+
+        // Define a module for p1.
+        m1 = wb.DefineModule("module1", this_cldr, new String[] { "p1" });
+        assertNotNull(m1, "Module should not be null");
+        wb.AddReadsModule(m1, jlObject_jlrM);
+
+        // Define a module for p2.
+        m2 = wb.DefineModule("module2", this_cldr, new String[] { "p2" });
+        assertNotNull(m2, "Module should not be null");
+        wb.AddReadsModule(m2, jlObject_jlrM);
+
+        // Make package p1 in m1 visible to everyone.
+        wb.AddModuleExports(m1, "p1", null);
+
+        Class p1_c1_class = Class.forName("p1.c1");
+
+        // p1.c1's ctor tries to call a method in p2.c2, but p1's module
+        // can not read p2's module.  So should get IllegalAccessError.
+        try {
+            p1_c1_class.newInstance();
+            throw new RuntimeException("Failed to get IAE (m1 can't read m2)");
+        } catch (IllegalAccessError e) {
+            System.out.println(e.getMessage());
+            if (!e.getMessage().contains("can not read")) {
+                throw new RuntimeException("Wrong message: " + e.getMessage());
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/AccessCheckSuper.java	Fri Jan 16 11:33:05 2015 -0500
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /testlibrary /../../test/lib /compiler/whitebox ..
+ * @compile p2/c2.java
+ * @build AccessCheckSuper
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI AccessCheckSuper
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.lang.reflect.Module;
+import sun.hotspot.WhiteBox;
+import static com.oracle.java.testlibrary.Asserts.*;
+
+public class AccessCheckSuper {
+
+    // Test that when a class cannot access its super class the message
+    // contains  both "superclass" text and module text.
+    public static void main(String args[]) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        Object m2;
+
+        // Get the class loader for AccessCheckSuper and assume it's also used to
+        // load class p2.c2.
+        ClassLoader this_cldr = AccessCheckSuper.class.getClassLoader();
+
+        // Define a module for p2.
+        m2 = wb.DefineModule("module2", this_cldr, new String[] { "p2" });
+        assertNotNull(m2, "Module should not be null");
+
+        // p2.c2 cannot read its superclass java.lang.Object
+        try {
+            Class p2_c2_class = Class.forName("p2.c2");
+            throw new RuntimeException("Failed to get IAE (can't read superclass)");
+        } catch (IllegalAccessError e) {
+            if (!e.getMessage().contains("superclass access check failed") ||
+                !e.getMessage().contains("can not read")) {
+                throw new RuntimeException("Wrong message: " + e.getMessage());
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/AccessCheckToUnnamed.java	Fri Jan 16 11:33:05 2015 -0500
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /testlibrary /../../test/lib /compiler/whitebox ..
+ * @compile p2/c2.java
+ * @compile p1/c1.java
+ * @build AccessCheckToUnnamed
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI AccessCheckToUnnamed
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.lang.reflect.Module;
+import sun.hotspot.WhiteBox;
+import static com.oracle.java.testlibrary.Asserts.*;
+
+public class AccessCheckToUnnamed {
+
+    // Check that a class in a package in module1 can successfully access a
+    // class that is in the unnamed module.
+    // has been exported.
+    public static void main(String args[]) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        Object m1;
+
+        // Get the java.lang.reflect.Module object for module java.base.
+        Class jlObject = Class.forName("java.lang.Object");
+        Object jlObject_jlrM = jlObject.getModule();
+        assertNotNull(jlObject_jlrM, "jlrModule object of java.lang.Object should not be null");
+
+        // Get the class loader for AccessCheckToUnnamed and assume it's also used to
+        // load class p1.c1.
+        ClassLoader this_cldr = AccessCheckToUnnamed.class.getClassLoader();
+
+        // Define a module for p1.
+        m1 = wb.DefineModule("module1", this_cldr, new String[] { "p1" });
+        assertNotNull(m1, "Module should not be null");
+        wb.AddReadsModule(m1, jlObject_jlrM);
+
+        // Make package p1 in m1 visible to everyone.
+        wb.AddModuleExports(m1, "p1", null);
+
+        // p1.c1's ctor tries to call a method in p2.c2.  This should work because
+        // p2 is in the unnamed module.
+        Class p1_c1_class = Class.forName("p1.c1");
+        p1_c1_class.newInstance();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/AccessCheckUnnamed.java	Fri Jan 16 11:33:05 2015 -0500
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.lang.reflect.Module;
+import sun.hotspot.WhiteBox;
+import static com.oracle.java.testlibrary.Asserts.*;
+
+/*
+ * @test
+ * @library /testlibrary /../../test/lib /compiler/whitebox ..
+ * @compile p2/c2.java
+ * @compile p1/c1.java
+ * @build AccessCheckUnnamed
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI AccessCheckUnnamed
+ */
+
+public class AccessCheckUnnamed {
+
+    // Test that a class in the unnamed module can not access a package in a
+    // named module that has not been unqualifiedly exported.
+    public static void main(String args[]) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        Object m1, m2;
+
+        // Get the java.lang.reflect.Module object for module java.base.
+        Class jlObject = Class.forName("java.lang.Object");
+        Object jlObject_jlrM = jlObject.getModule();
+        assertNotNull(jlObject_jlrM, "jlrModule object of java.lang.Object should not be null");
+
+        // Get the class loader for AccessCheckWorks and assume it's also used to
+        // load class p2.c2.
+        ClassLoader this_cldr = AccessCheckUnnamed.class.getClassLoader();
+
+        // Define a module for p2.
+        m2 = wb.DefineModule("module2", this_cldr, new String[] { "p2" });
+        assertNotNull(m2, "Module should not be null");
+        wb.AddReadsModule(m2, jlObject_jlrM);
+
+        // p1.c1's ctor tries to call a method in p2.c2.  This should fail because
+        // p1 is in the unnamed module and p2.c2 is not unqualifiedly exported.
+        Class p1_c1_class = Class.forName("p1.c1");
+        try {
+            Object c1_obj = p1_c1_class.newInstance();
+            throw new RuntimeException("Failed to get IAE (p2 in m2 is not exported to unnamed module)");
+        } catch (IllegalAccessError f) {
+            System.out.println(f.getMessage());
+            if (!f.getMessage().contains("p2 is not exported to the unnamed module")) {
+                throw new RuntimeException("Wrong message: " + f.getMessage());
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/AccessCheckWorks.java	Fri Jan 16 11:33:05 2015 -0500
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /testlibrary /../../test/lib /compiler/whitebox ..
+ * @compile p2/c2.java
+ * @compile p1/c1.java
+ * @build AccessCheckWorks
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI AccessCheckWorks
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.lang.reflect.Module;
+import sun.hotspot.WhiteBox;
+import static com.oracle.java.testlibrary.Asserts.*;
+
+public class AccessCheckWorks {
+
+    // Check that a class in a package in module1 can successfully access a
+    // class in module2 when module1 can read module2 and the class's package
+    // has been exported.
+    public static void main(String args[]) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        Object m1, m2;
+
+        // Get the java.lang.reflect.Module object for module java.base.
+        Class jlObject = Class.forName("java.lang.Object");
+        Object jlObject_jlrM = jlObject.getModule();
+        assertNotNull(jlObject_jlrM, "jlrModule object of java.lang.Object should not be null");
+
+        // Get the class loader for AccessCheckWorks and assume it's also used to
+        // load classes p1.c1 and p2.c2.
+        ClassLoader this_cldr = AccessCheckWorks.class.getClassLoader();
+
+        // Define a module for p1.
+        m1 = wb.DefineModule("module1", this_cldr, new String[] { "p1" });
+        assertNotNull(m1, "Module should not be null");
+        wb.AddReadsModule(m1, jlObject_jlrM);
+
+        // Define a module for p2.
+        m2 = wb.DefineModule("module2", this_cldr, new String[] { "p2" });
+        assertNotNull(m2, "Module should not be null");
+        wb.AddReadsModule(m2, jlObject_jlrM);
+
+        // Make package p1 in m1 visible to everyone.
+        wb.AddModuleExports(m1, "p1", null);
+
+        // p1.c1's ctor tries to call a method in p2.c2.  This should work because
+        // p1's module can read p2's module and p2 is exported to p1's module.
+        wb.AddReadsModule(m1, m2);
+        wb.AddModuleExports(m2, "p2", m1);
+        Class p1_c1_class = Class.forName("p1.c1");
+        p1_c1_class.newInstance();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/ExportTwice.java	Fri Jan 16 11:33:05 2015 -0500
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /testlibrary /../../test/lib /compiler/whitebox ..
+ * @compile p2/c2.java
+ * @compile p1/c1.java
+ * @build ExportTwice
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ExportTwice
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.lang.reflect.Module;
+import sun.hotspot.WhiteBox;
+import static com.oracle.java.testlibrary.Asserts.*;
+
+public class ExportTwice {
+
+    // Check that a package can not be exported unqualifiedly, and then exported
+    // to a specific package.
+    // Also, check that a package can be exported to a specific package and then
+    // exported unqualifiedly.
+    public static void main(String args[]) throws Exception {
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        Object m1, m2, m3;
+
+        // Get the java.lang.reflect.Module object for module java.base.
+        Class jlObject = Class.forName("java.lang.Object");
+        Object jlObject_jlrM = jlObject.getModule();
+        assertNotNull(jlObject_jlrM, "jlrModule object of java.lang.Object should not be null");
+
+        // Get the class loader for ExportTwice and assume it's also used to
+        // load classes p1.c1 and p2.c2.
+        ClassLoader this_cldr = ExportTwice.class.getClassLoader();
+
+        // Define a module for p1.
+        m1 = wb.DefineModule("module1", this_cldr, new String[] { "p1" });
+        assertNotNull(m1, "Module should not be null");
+        wb.AddReadsModule(m1, jlObject_jlrM);
+
+        // Define a module for p2.
+        m2 = wb.DefineModule("module2", this_cldr, new String[] { "p2" });
+        assertNotNull(m2, "Module should not be null");
+        wb.AddReadsModule(m2, jlObject_jlrM);
+
+        // Define a module for p3.
+        m3 = wb.DefineModule("module3", this_cldr, new String[] { "p3" });
+        assertNotNull(m3, "Module should not be null");
+        wb.AddReadsModule(m3, jlObject_jlrM);
+
+        // Make package p1 in m1 visible to everyone.
+        wb.AddModuleExports(m1, "p1", null);
+
+        // Try to export p1 only to m2 after it was exported unqualifiedly.
+        try {
+            wb.AddModuleExports(m1, "p1", m2);
+            throw new RuntimeException("Failed to get IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            if (!e.getMessage().contains("package p1 in module module1 is already unqualifiedly exported")) {
+               throw new RuntimeException("Wrong message: " + e.getMessage());
+            }
+        }
+
+        // Export p2 to m3 then export it again unqualifiedly.
+        wb.AddModuleExports(m2, "p2", m3);
+        wb.AddModuleExports(m2, "p2", null);
+
+        // p1.c1's ctor tries to call a method in p2.c2.  This should work because
+        // p1's module can read p2's module and p2 is now exported unqualifiedly.
+        wb.AddReadsModule(m1, m2);
+        Class p1_c1_class = Class.forName("p1.c1");
+        p1_c1_class.newInstance();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/p1/c1.java	Fri Jan 16 11:33:05 2015 -0500
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// Small class used by multiple hotspot/runtime/modules/AccessCheck* tests.
+package p1;
+
+import p2.c2;
+
+public class c1 {
+
+    public c1 () {
+        p2.c2 c2_obj = new p2.c2();
+        c2_obj.method2();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/modules/p2/c2.java	Fri Jan 16 11:33:05 2015 -0500
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// Small class used by multiple hotspot/runtime/modules/AccessCheck* tests.
+package p2;
+
+public class c2 {
+    public void method2() { }
+}