1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @modules java.base/jdk.internal.misc
  27  * @library /testlibrary  /test/lib /compiler/whitebox ..
  28  * @build sun.hotspot.WhiteBox
  29  * @compile/module=java.base java/lang/reflect/ModuleHelper.java
  30  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  31  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  32  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI JVMDefineModule
  33  */
  34 
  35 import static jdk.test.lib.Asserts.*;
  36 
  37 public class JVMDefineModule {
  38 
  39     public static void main(String args[]) throws Throwable {
  40         MyClassLoader cl = new MyClassLoader();
  41         Object m;
  42 
  43         // NULL classloader argument, expect success
  44         m = ModuleHelper.ModuleObject("mymodule", null, new String[] { "mypackage" });
  45         assertNotNull(m, "Module should not be null");
  46         ModuleHelper.DefineModule(m, "9.0", "mymodule/here", new String[] { "mypackage" });
  47 
  48 /* Invalid test, won't compile.
  49         // Invalid classloader argument, expect an IAE
  50         try {
  51             m = ModuleHelper.ModuleObject("mymodule1", new Object(), new String[] { "mypackage1" });
  52             ModuleHelper.DefineModule(m,  "9.0", "mymodule/here", new String[] { "mypackage1" });
  53             throw new RuntimeException("Failed to get expected IAE for bad loader");
  54         } catch(IllegalArgumentException e) {
  55             // Expected
  56         }
  57 */
  58 
  59         // NULL package argument, should not throw an exception
  60         m = ModuleHelper.ModuleObject("mymodule2", cl, new String[] { "nullpkg" });
  61         assertNotNull(m, "Module should not be null");
  62         ModuleHelper.DefineModule(m, "9.0", "mymodule2/here", null);
  63 
  64         // Null module argument, expect an NPE
  65         try {
  66             ModuleHelper.DefineModule(null,  "9.0", "mymodule/here", new String[] { "mypackage1" });
  67             throw new RuntimeException("Failed to get expected NPE for null module");
  68         } catch(NullPointerException e) {
  69             if (!e.getMessage().contains("Null module object")) {
  70               throw new RuntimeException("Failed to get expected IAE message for null module: " + e.getMessage());
  71             }
  72             // Expected
  73         }
  74 
  75         // Invalid module argument, expect an IAE
  76         try {
  77             ModuleHelper.DefineModule(new Object(),  "9.0", "mymodule/here", new String[] { "mypackage1" });
  78             throw new RuntimeException("Failed to get expected IAE or NPE for bad module");
  79         } catch(IllegalArgumentException e) {
  80             if (!e.getMessage().contains("module is not an instance of type java.lang.reflect.Module")) {
  81               throw new RuntimeException("Failed to get expected IAE message for bad module: " + e.getMessage());
  82             }
  83         }
  84 
  85         // NULL module name, expect an IAE or NPE
  86         try {
  87             m = ModuleHelper.ModuleObject(null, cl, new String[] { "mypackage2" });
  88             ModuleHelper.DefineModule(m, "9.0", "mymodule/here", new String[] { "mypackage2" });
  89             throw new RuntimeException("Failed to get expected NPE for NULL module");
  90         } catch(IllegalArgumentException e) {
  91             // Expected
  92         } catch(NullPointerException e) {
  93             // Expected
  94         }
  95 
  96         // module name is java.base, expect an IAE
  97         m = ModuleHelper.ModuleObject("java.base", cl, new String[] { "mypackage3" });
  98         try {
  99             ModuleHelper.DefineModule(m, "9.0", "mymodule/here", new String[] { "mypackage3" });
 100             throw new RuntimeException("Failed to get expected IAE for java.base, not defined with boot class loader");
 101         } catch(IllegalArgumentException e) {
 102             if (!e.getMessage().contains("Class loader must be the boot class loader")) {
 103               throw new RuntimeException("Failed to get expected IAE message for java.base: " + e.getMessage());
 104             }
 105         }
 106 
 107         // Duplicates in package list, expect an IAE
 108         m = ModuleHelper.ModuleObject("module.x", cl, new String[] { "mypackage4", "mypackage5" });
 109         try {
 110             ModuleHelper.DefineModule(m, "9.0", "mymodule/here", new String[] { "mypackage4", "mypackage5", "mypackage4" });
 111             throw new RuntimeException("Failed to get IAE for duplicate packages");
 112         } catch(IllegalArgumentException e) {
 113             if (!e.getMessage().contains("Duplicate package name")) {
 114               throw new RuntimeException("Failed to get expected IAE message for duplicate package: " + e.getMessage());
 115             }
 116         }
 117 
 118         // Empty entry in package list, expect an IAE
 119         m = ModuleHelper.ModuleObject("module.y", cl, new String[] { "mypackageX", "mypackageY" });
 120         try {
 121             ModuleHelper.DefineModule(m, "9.0", "mymodule/here", new String[] { "mypackageX", "", "mypackageY" });
 122             throw new RuntimeException("Failed to get IAE for empty package");
 123         } catch(IllegalArgumentException e) {
 124             if (!e.getMessage().contains("Invalid package name")) {
 125               throw new RuntimeException("Failed to get expected IAE message empty package entry: " + e.getMessage());
 126             }
 127         }
 128 
 129         // Duplicate module name, expect an IAE
 130         m = ModuleHelper.ModuleObject("module.name", cl, new String[] { "mypackage6" });
 131         assertNotNull(m, "Module should not be null");
 132         ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "mypackage6" });
 133         try {
 134             ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "mypackage6a" });
 135             throw new RuntimeException("Failed to get IAE for duplicate module");
 136         } catch(IllegalArgumentException e) {
 137             if (!e.getMessage().contains("Module module.name is already defined")) {
 138               throw new RuntimeException("Failed to get expected IAE message for duplicate module: " + e.getMessage());
 139             }
 140         }
 141 
 142         // Package is already defined for class loader, expect an IAE
 143         m = ModuleHelper.ModuleObject("dupl.pkg.module", cl, new String[] { "mypackage6b" });
 144         try {
 145             ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "mypackage6" });
 146             throw new RuntimeException("Failed to get IAE for existing package");
 147         } catch(IllegalArgumentException e) {
 148             if (!e.getMessage().contains("Package mypackage6 for module dupl.pkg.module already exists for class loader")) {
 149               throw new RuntimeException("Failed to get expected IAE message for duplicate package: " + e.getMessage());
 150             }
 151         }
 152 
 153         // Empty module name, expect an IAE
 154         try {
 155             m = ModuleHelper.ModuleObject("", cl, new String[] { "mypackage8" });
 156             ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "mypackage8" });
 157             throw new RuntimeException("Failed to get expected IAE for empty module name");
 158         } catch(IllegalArgumentException e) {
 159             // Expected
 160         }
 161 
 162         // Bad module name, expect an IAE
 163         try {
 164             m = ModuleHelper.ModuleObject("bad;name", cl, new String[] { "mypackage9" });
 165             ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "mypackage9" });
 166             throw new RuntimeException("Failed to get expected IAE for bad;name");
 167         } catch(IllegalArgumentException e) {
 168             // Expected
 169         }
 170 
 171         // Bad module name, expect an IAE
 172         try {
 173             m = ModuleHelper.ModuleObject(".leadingdot", cl, new String[] { "mypackage9a" });
 174             ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "mypackage9a" });
 175             throw new RuntimeException("Failed to get expected IAE for .leadingdot");
 176         } catch(IllegalArgumentException e) {
 177             // Expected
 178         }
 179 
 180         // Bad module name, expect an IAE
 181         try {
 182             m = ModuleHelper.ModuleObject("trailingdot.", cl, new String[] { "mypackage9b" });
 183             ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "mypackage9b" });
 184             throw new RuntimeException("Failed to get expected IAE for trailingdot.");
 185         } catch(IllegalArgumentException e) {
 186             // Expected
 187         }
 188 
 189         // Bad module name, expect an IAE
 190         m = ModuleHelper.ModuleObject("consecutive..dots", cl, new String[] { "mypackage9c" });
 191         try {
 192             ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "mypackage9c" });
 193             throw new RuntimeException("Failed to get expected IAE for consecutive..dots");
 194         } catch(IllegalArgumentException e) {
 195             // Expected
 196         }
 197 
 198         // module name with multiple dots, should be okay
 199         m = ModuleHelper.ModuleObject("more.than.one.dat", cl, new String[] { "mypackage9d" });
 200         assertNotNull(m, "Module should not be null");
 201         ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "mypackage9d" });
 202 
 203         // Zero length package list, should be okay
 204         m = ModuleHelper.ModuleObject("zero.packages", cl, new String[] { });
 205         assertNotNull(m, "Module should not be null");
 206         ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { });
 207 
 208         // Invalid package name, expect an IAE
 209         m = ModuleHelper.ModuleObject("module5", cl, new String[] { "your.package" });
 210         try {
 211             ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "your.package" });
 212             throw new RuntimeException("Failed to get expected IAE for your.package");
 213         } catch(IllegalArgumentException e) {
 214             if (!e.getMessage().contains("Invalid package name")) {
 215               throw new RuntimeException("Failed to get expected IAE message for bad package name: " + e.getMessage());
 216             }
 217         }
 218 
 219         // Invalid package name, expect an IAE
 220         m = ModuleHelper.ModuleObject("module6", cl, new String[] { "foo" }); // Name irrelevant
 221         try {
 222             ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { ";your/package" });
 223             throw new RuntimeException("Failed to get expected IAE for ;your.package");
 224         } catch(IllegalArgumentException e) {
 225             if (!e.getMessage().contains("Invalid package name")) {
 226               throw new RuntimeException("Failed to get expected IAE message for bad package name: " + e.getMessage());
 227             }
 228         }
 229 
 230         // Invalid package name, expect an IAE
 231         m = ModuleHelper.ModuleObject("module7", cl, new String[] { "foo" }); // Name irrelevant
 232         try {
 233             ModuleHelper.DefineModule(m, "9.0", "module.name/here", new String[] { "7[743" });
 234             throw new RuntimeException("Failed to get expected IAE for package 7[743");
 235         } catch(IllegalArgumentException e) {
 236             if (!e.getMessage().contains("Invalid package name")) {
 237               throw new RuntimeException("Failed to get expected IAE message for bad package name: " + e.getMessage());
 238             }
 239         }
 240 
 241         // module version that is null, should be okay
 242         m = ModuleHelper.ModuleObject("module8", cl, new String[] { "a_package_8" });
 243         assertNotNull(m, "Module should not be null");
 244         ModuleHelper.DefineModule(m, null, "module8/here", new String[] { "a_package_8" });
 245 
 246         // module version that is "", should be okay
 247         m = ModuleHelper.ModuleObject("module9", cl, new String[] { "a_package_9" });
 248         assertNotNull(m, "Module should not be null");
 249         ModuleHelper.DefineModule(m, "", "module9/here", new String[] { "a_package_9" });
 250 
 251         // module location that is null, should be okay
 252         m = ModuleHelper.ModuleObject("module10", cl, new String[] { "a_package_10" });
 253         assertNotNull(m, "Module should not be null");
 254         ModuleHelper.DefineModule(m, "9.0", null, new String[] { "a_package_10" });
 255 
 256         // module location that is "", should be okay
 257         m = ModuleHelper.ModuleObject("module11", cl, new String[] { "a_package_11" });
 258         assertNotNull(m, "Module should not be null");
 259         ModuleHelper.DefineModule(m, "9.0", "", new String[] { "a_package_11" });
 260     }
 261 
 262     static class MyClassLoader extends ClassLoader { }
 263 }