test/hotspot/jtreg/runtime/modules/AccessCheck/MethodAccessReadTwice.java
changeset 47684 c3c04b6e14f8
equal deleted inserted replaced
47682:e4a89dfa1247 47684:c3c04b6e14f8
       
     1 /*
       
     2  Copyright (c) 2017, 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  * @bug 8174954
       
    27  * @summary Test that invokedynamic instructions, that initially throw IAE exceptions
       
    28  *          because of a missing module read edge, behave correctly when executed
       
    29  *          after the module read edge is added.
       
    30  * @compile ModuleLibrary.java
       
    31  *          p2/c2.java
       
    32  *          p5/c5.java
       
    33  *          p7/c7.java
       
    34  * @run main/othervm MethodAccessReadTwice
       
    35  */
       
    36 
       
    37 import java.lang.module.Configuration;
       
    38 import java.lang.module.ModuleDescriptor;
       
    39 import java.lang.module.ModuleFinder;
       
    40 import java.lang.ModuleLayer;
       
    41 import java.lang.Module;
       
    42 import java.util.HashMap;
       
    43 import java.util.Map;
       
    44 import java.util.Set;
       
    45 
       
    46 // defines first_mod --> packages p5
       
    47 // defines second_mod --> package p2, p2 is exported to first_mod
       
    48 // defines third_mod --> packages p7
       
    49 
       
    50 public class MethodAccessReadTwice {
       
    51 
       
    52     // Create a Layer over the boot layer.
       
    53     // Define modules within this layer to test access between
       
    54     // publicly defined classes within packages of those modules.
       
    55     public void createLayerOnBoot() throws Throwable {
       
    56 
       
    57         // Define module:     first_mod
       
    58         // Can read:          java.base
       
    59         // Packages:          p5
       
    60         // Packages exported: p5 is exported unqualifiedly
       
    61         ModuleDescriptor descriptor_first_mod =
       
    62                 ModuleDescriptor.newModule("first_mod")
       
    63                         .requires("java.base")
       
    64                         .exports("p5")
       
    65                         .build();
       
    66 
       
    67         // Define module:     second_mod
       
    68         // Can read:          java.base
       
    69         // Packages:          p2
       
    70         // Packages exported: p2 is exported to first_mod
       
    71         ModuleDescriptor descriptor_second_mod =
       
    72                 ModuleDescriptor.newModule("second_mod")
       
    73                         .requires("java.base")
       
    74                         .exports("p2")
       
    75                         .build();
       
    76 
       
    77         // Define module:     third_mod
       
    78         // Can read:          java.base
       
    79         // Packages:          p7
       
    80         // Packages exported: p7 is exported unqualifiedly
       
    81         ModuleDescriptor descriptor_third_mod =
       
    82                 ModuleDescriptor.newModule("third_mod")
       
    83                         .requires("java.base")
       
    84                         .exports("p7")
       
    85                         .build();
       
    86 
       
    87         // Set up a ModuleFinder containing all modules for this layer
       
    88         ModuleFinder finder = ModuleLibrary.of(descriptor_first_mod,
       
    89                                                descriptor_second_mod,
       
    90                                                descriptor_third_mod);
       
    91 
       
    92         // Resolves "first_mod", "second_mod", and "third_mod"
       
    93         Configuration cf = ModuleLayer.boot()
       
    94                 .configuration()
       
    95                 .resolve(finder, ModuleFinder.of(),
       
    96                          Set.of("first_mod", "second_mod", "third_mod"));
       
    97 
       
    98         // Map each module to this class loader
       
    99         Map<String, ClassLoader> map = new HashMap<>();
       
   100         ClassLoader loader = MethodAccessReadTwice.class.getClassLoader();
       
   101         map.put("first_mod", loader);
       
   102         map.put("second_mod", loader);
       
   103         map.put("third_mod", loader);
       
   104 
       
   105         // Create Layer that contains first_mod, second_mod, and third_mod
       
   106         ModuleLayer layer = ModuleLayer.boot().defineModules(cf, map::get);
       
   107 
       
   108         Class p2_c2_class = loader.loadClass("p2.c2");
       
   109         Class p5_c5_class = loader.loadClass("p5.c5");
       
   110         Class p7_c7_class = loader.loadClass("p7.c7");
       
   111 
       
   112         Module first_mod = p5_c5_class.getModule();
       
   113         Module second_mod = p2_c2_class.getModule();
       
   114         Module third_mod = p7_c7_class.getModule();
       
   115 
       
   116         p5.c5 c5_obj = new p5.c5();
       
   117         p2.c2 c2_obj = new p2.c2();
       
   118         p7.c7 c7_obj = new p7.c7();
       
   119 
       
   120         // Test that if an invokedynamic instruction gets an IAE exception because
       
   121         // of a module read issue, and then the read issue is fixed, that
       
   122         // re-executing the same invokedynamic instruction will get the same IAE.
       
   123 
       
   124         // First access check for p5.c5 --> call to method5 --> tries to access p2.c2
       
   125         try {
       
   126             // Should throw IAE because p5.c5's module cannot read p2.c2's module.
       
   127             c5_obj.method5(c2_obj);
       
   128             throw new RuntimeException("Test Failed, module first_mod should not have access to p2.c2");
       
   129         } catch (IllegalAccessError e) {
       
   130             String message = e.getMessage();
       
   131             if (!(message.contains("cannot access") &&
       
   132                   message.contains("because module first_mod does not read module second_mod"))) {
       
   133                 throw new RuntimeException("Wrong message: " + message);
       
   134             } else {
       
   135                 System.out.println("Test Succeeded at attempt #1");
       
   136             }
       
   137         }
       
   138 
       
   139         // Add a read edge from p5/c5's module (first_mod) to p2.c2's module (second_mod)
       
   140         c5_obj.methodAddReadEdge(p2_c2_class.getModule());
       
   141         // Second access check for p5.c5, should have same result as first
       
   142         try {
       
   143             c5_obj.method5(c2_obj); // should result in IAE
       
   144             throw new RuntimeException("Test Failed, access should have been cached above");
       
   145         } catch (IllegalAccessError e) {
       
   146             String message = e.getMessage();
       
   147             if (!(message.contains("cannot access") &&
       
   148                   message.contains("because module first_mod does not read module second_mod"))) {
       
   149                 throw new RuntimeException("Wrong message: " + message);
       
   150             } else {
       
   151                 System.out.println("Test Succeeded at attempt #2");
       
   152             }
       
   153         }
       
   154 
       
   155 
       
   156         // Test that if one invokedynamic instruction gets an IAE exception
       
   157         // because of a module read issue, and then the read issue is fixed, that
       
   158         // a subsequent invokedynamic instruction, that tries the same access,
       
   159         // succeeds.
       
   160         c7_obj.method7(c2_obj, second_mod); // Should not result in IAE
       
   161     }
       
   162 
       
   163     public static void main(String args[]) throws Throwable {
       
   164       MethodAccessReadTwice test = new MethodAccessReadTwice();
       
   165       test.createLayerOnBoot();
       
   166     }
       
   167 }