jdk/test/java/lang/invoke/modules/m1/p1/Main.java
changeset 43712 5dfd0950317c
child 44545 83b611b88ac8
equal deleted inserted replaced
43619:dc9102c475f3 43712:5dfd0950317c
       
     1 /*
       
     2  * Copyright (c) 2015, 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 package p1;
       
    25 
       
    26 import java.lang.invoke.MethodHandle;
       
    27 import java.lang.invoke.MethodHandles;
       
    28 import java.lang.invoke.MethodHandles.Lookup;
       
    29 import java.lang.invoke.MethodType;
       
    30 import java.lang.reflect.Layer;
       
    31 import java.lang.reflect.Module;
       
    32 
       
    33 import static java.lang.invoke.MethodHandles.Lookup.*;
       
    34 
       
    35 import org.testng.annotations.BeforeTest;
       
    36 import org.testng.annotations.Test;
       
    37 import static org.testng.Assert.*;
       
    38 
       
    39 /**
       
    40  * Basic test case for module access checks and Lookup.in.
       
    41  */
       
    42 
       
    43 @Test
       
    44 public class Main {
       
    45 
       
    46     private Class<?> p1_Type1;        // m1, exported
       
    47     private Class<?> p2_Type2;        // m1, not exported
       
    48     private Class<?> q1_Type1;        // m2, exported
       
    49     private Class<?> q2_Type2;        // m2, not exported
       
    50     private Class<?> x500NameClass;   // java.base, not exported
       
    51     private Class<?> unnamedClass;    // class in unnamed module
       
    52 
       
    53     @BeforeTest
       
    54     public void setup() throws Exception {
       
    55         try {
       
    56             p1_Type1 = Class.forName("p1.Type1");
       
    57             p2_Type2 = Class.forName("p2.Type2");
       
    58             q1_Type1 = Class.forName("q1.Type1");
       
    59             q2_Type2 = Class.forName("q2.Type2");
       
    60             x500NameClass = Class.forName("sun.security.x509.X500Name");
       
    61             unnamedClass = Class.forName("Unnamed");
       
    62         } catch (ClassNotFoundException e) {
       
    63             throw new AssertionError(e);
       
    64         }
       
    65 
       
    66         // check setup
       
    67         Module m1 = Layer.boot().findModule("m1").orElse(null);
       
    68         assertNotNull(m1);
       
    69         assertTrue(p1_Type1.getModule() == m1);
       
    70         assertTrue(p2_Type2.getModule() == m1);
       
    71         assertTrue(m1.isExported("p1"));
       
    72         assertFalse(m1.isExported("p2"));
       
    73 
       
    74         Module m2 = Layer.boot().findModule("m2").orElse(null);
       
    75         assertNotNull(m2);
       
    76         assertTrue(q1_Type1.getModule() == m2);
       
    77         assertTrue(q2_Type2.getModule() == m2);
       
    78         assertTrue(m2.isExported("q1"));
       
    79         assertFalse(m2.isExported("q2"));
       
    80 
       
    81         Module unnamedModule = unnamedClass.getModule();
       
    82         assertFalse(unnamedModule.isNamed());
       
    83 
       
    84         // m1 needs to read unnamed module
       
    85         Main.class.getModule().addReads(unnamedModule);
       
    86     }
       
    87 
       
    88     /**
       
    89      * MethodHandles.lookup()
       
    90      *
       
    91      * [A0] has module access
       
    92      * [A1] can access all public types in m1
       
    93      * [A2] can access public types in packages exported by modules that m1 reads
       
    94      * [A3] cannot access public types in non-exported modules of modules that m1 reads
       
    95      */
       
    96     public void testLookup() throws Exception {
       
    97         Lookup lookup = MethodHandles.lookup();
       
    98         assertTrue((lookup.lookupModes() & MODULE) == MODULE); // [A0]
       
    99 
       
   100         // m1
       
   101         findConstructor(lookup, p1_Type1, void.class); // [A1]
       
   102         findConstructor(lookup, p2_Type2, void.class); // [A1]
       
   103 
       
   104         // m2
       
   105         findConstructor(lookup, q1_Type1, void.class); // [A2]
       
   106         findConstructorExpectingIAE(lookup, q2_Type2, void.class); // [A3]
       
   107 
       
   108         // java.base
       
   109         findConstructor(lookup, Object.class, void.class); // [A2]
       
   110         findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class); // [A3]
       
   111 
       
   112         // unnamed
       
   113         findConstructor(lookup, unnamedClass, void.class);  // [A3]
       
   114     }
       
   115 
       
   116     /**
       
   117      * Hop to lookup class in the same module
       
   118      *
       
   119      * [A0] module and public access is not lost
       
   120      */
       
   121     public void testToSameModule() throws Exception {
       
   122         Lookup lookup = MethodHandles.lookup().in(p2_Type2);
       
   123         assertTrue(lookup.lookupModes() == (MODULE|PUBLIC)); // [A0]
       
   124 
       
   125         // m1
       
   126         findConstructor(lookup, p1_Type1, void.class);
       
   127         findConstructor(lookup, p2_Type2, void.class);
       
   128 
       
   129         // m2
       
   130         findConstructor(lookup, q1_Type1, void.class);
       
   131         findConstructorExpectingIAE(lookup, q2_Type2, void.class);
       
   132 
       
   133         // java.base
       
   134         findConstructor(lookup, Object.class, void.class);
       
   135         findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
       
   136 
       
   137         // unnamed
       
   138         findConstructor(lookup, unnamedClass, void.class);
       
   139     }
       
   140 
       
   141     /**
       
   142      * Hop to lookup class in another named module
       
   143      *
       
   144      * [A0] has no access
       
   145      */
       
   146     public void testFromNamedToNamedModule() throws Exception {
       
   147         Lookup lookup = MethodHandles.lookup().in(q1_Type1);
       
   148         assertTrue(lookup.lookupModes() == 0); // [A0]
       
   149 
       
   150         // m1
       
   151         findConstructorExpectingIAE(lookup, p1_Type1, void.class);
       
   152         findConstructorExpectingIAE(lookup, p2_Type2, void.class);
       
   153 
       
   154         // m2
       
   155         findConstructorExpectingIAE(lookup, q1_Type1, void.class);
       
   156         findConstructorExpectingIAE(lookup, q2_Type2, void.class);
       
   157 
       
   158         // java.base
       
   159         findConstructorExpectingIAE(lookup, Object.class, void.class);
       
   160         findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
       
   161 
       
   162         // unnamed
       
   163         findConstructorExpectingIAE(lookup, unnamedClass, void.class);
       
   164     }
       
   165 
       
   166     /**
       
   167      * Hop to lookup class in an unnamed module
       
   168      *
       
   169      * [A0] has no access
       
   170      */
       
   171     public void testFromNamedToUnnamedModule() throws Exception {
       
   172         Lookup lookup = MethodHandles.lookup().in(unnamedClass);
       
   173         assertTrue(lookup.lookupModes() == 0); // [A0]
       
   174 
       
   175         // m1
       
   176         findConstructorExpectingIAE(lookup, p1_Type1, void.class);
       
   177         findConstructorExpectingIAE(lookup, p2_Type2, void.class);
       
   178 
       
   179         // m2
       
   180         findConstructorExpectingIAE(lookup, q1_Type1, void.class);
       
   181         findConstructorExpectingIAE(lookup, q2_Type2, void.class);
       
   182 
       
   183         // java.base
       
   184         findConstructorExpectingIAE(lookup, Object.class, void.class);
       
   185         findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
       
   186 
       
   187         // unnamed
       
   188         findConstructorExpectingIAE(lookup, unnamedClass, void.class);
       
   189     }
       
   190 
       
   191     /**
       
   192      * Hop from unnamed to named module.
       
   193      *
       
   194      * [A0] retains PUBLIC access
       
   195      */
       
   196     public void testFromUnnamedToNamedModule() throws Exception {
       
   197         Lookup lookup = MethodHandles.lookup();
       
   198         lookup = MethodHandles.privateLookupIn(unnamedClass, lookup).in(p1_Type1);
       
   199         assertTrue(lookup.lookupModes() == PUBLIC); // A0
       
   200 
       
   201         // m1
       
   202         findConstructor(lookup, p1_Type1, void.class);
       
   203         findConstructorExpectingIAE(lookup, p2_Type2, void.class);
       
   204 
       
   205         // m2
       
   206         findConstructor(lookup, q1_Type1, void.class);
       
   207         findConstructorExpectingIAE(lookup, q2_Type2, void.class);
       
   208 
       
   209         // java.base
       
   210         findConstructor(lookup, Object.class, void.class);
       
   211         findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
       
   212 
       
   213         // unnamed
       
   214         findConstructor(lookup, unnamedClass, void.class);
       
   215     }
       
   216 
       
   217     /**
       
   218      * MethodHandles.publicLookup()
       
   219      *
       
   220      * [A0] has PUBLIC|UNCONDITIONAL access
       
   221      */
       
   222     public void testPublicLookup() throws Exception {
       
   223         Lookup lookup = MethodHandles.publicLookup();
       
   224         assertTrue(lookup.lookupModes() == (PUBLIC|UNCONDITIONAL)); // A0
       
   225 
       
   226         // m1
       
   227         findConstructor(lookup, p1_Type1, void.class);
       
   228         findConstructorExpectingIAE(lookup, p2_Type2, void.class);
       
   229 
       
   230         // m2
       
   231         findConstructor(lookup, q1_Type1, void.class);
       
   232         findConstructorExpectingIAE(lookup, q2_Type2, void.class);
       
   233 
       
   234         // java.base
       
   235         findConstructor(lookup, Object.class, void.class);
       
   236         findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
       
   237 
       
   238         // unnamed
       
   239         findConstructor(lookup, unnamedClass, void.class);
       
   240     }
       
   241 
       
   242     /**
       
   243      * Hop from publicLookup to accessible type in java.base
       
   244      */
       
   245     public void testPublicLookupToBaseModule() throws Exception {
       
   246         Lookup lookup = MethodHandles.publicLookup().in(String.class);
       
   247         assertTrue(lookup.lookupModes() == PUBLIC); // A0
       
   248 
       
   249         // m1
       
   250         findConstructorExpectingIAE(lookup, p1_Type1, void.class);
       
   251         findConstructorExpectingIAE(lookup, p2_Type2, void.class);
       
   252 
       
   253         // m2
       
   254         findConstructorExpectingIAE(lookup, q1_Type1, void.class);
       
   255         findConstructorExpectingIAE(lookup, q2_Type2, void.class);
       
   256 
       
   257         // java.base
       
   258         findConstructor(lookup, Object.class, void.class);
       
   259         findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
       
   260 
       
   261         // unnamed
       
   262         findConstructorExpectingIAE(lookup, unnamedClass, void.class);
       
   263     }
       
   264 
       
   265 
       
   266     /**
       
   267      * Hop from publicLookup to accessible type in named module.
       
   268      *
       
   269      * [A0] has PUBLIC access
       
   270      */
       
   271     public void testPublicLookupToAccessibleTypeInNamedModule() throws Exception {
       
   272         Lookup lookup = MethodHandles.publicLookup().in(p1_Type1);
       
   273         assertTrue(lookup.lookupModes() == PUBLIC); // A0
       
   274 
       
   275         // m1
       
   276         findConstructor(lookup, p1_Type1, void.class);
       
   277         findConstructorExpectingIAE(lookup, p2_Type2, void.class);
       
   278 
       
   279         // m2
       
   280         findConstructor(lookup, q1_Type1, void.class);
       
   281         findConstructorExpectingIAE(lookup, q2_Type2, void.class);
       
   282 
       
   283         // java.base
       
   284         findConstructor(lookup, Object.class, void.class);
       
   285         findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
       
   286 
       
   287         // unnamed
       
   288         findConstructor(lookup, unnamedClass, void.class);
       
   289     }
       
   290 
       
   291     /**
       
   292      * Teleport from publicLookup to inaccessible type in named module.
       
   293      *
       
   294      * [A0] has no access
       
   295      */
       
   296     public void testPublicLookupToInaccessibleTypeInNamedModule() throws Exception {
       
   297         Lookup lookup = MethodHandles.publicLookup().in(p2_Type2);
       
   298         assertTrue(lookup.lookupModes() == 0); // A0
       
   299 
       
   300         // m1
       
   301         findConstructorExpectingIAE(lookup, p1_Type1, void.class);
       
   302         findConstructorExpectingIAE(lookup, p2_Type2, void.class);
       
   303 
       
   304         // m2
       
   305         findConstructorExpectingIAE(lookup, q1_Type1, void.class);
       
   306         findConstructorExpectingIAE(lookup, q2_Type2, void.class);
       
   307 
       
   308         // java.base
       
   309         findConstructorExpectingIAE(lookup, Object.class, void.class);
       
   310         findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
       
   311 
       
   312         // unnamed
       
   313         findConstructorExpectingIAE(lookup, unnamedClass, void.class);
       
   314     }
       
   315 
       
   316     /**
       
   317      * Teleport from publicLookup to public type in unnamed module
       
   318      *
       
   319      * [A0] has PUBLIC access
       
   320      */
       
   321     public void testPublicLookupToUnnamedModule() throws Exception {
       
   322         Lookup lookup = MethodHandles.publicLookup().in(unnamedClass);
       
   323         assertTrue(lookup.lookupModes() == PUBLIC); // A0
       
   324 
       
   325         // m1
       
   326         findConstructor(lookup, p1_Type1, void.class);
       
   327         findConstructorExpectingIAE(lookup, p2_Type2, void.class);
       
   328 
       
   329         // m2
       
   330         findConstructor(lookup, q1_Type1, void.class);
       
   331         findConstructorExpectingIAE(lookup, q2_Type2, void.class);
       
   332 
       
   333         // java.base
       
   334         findConstructor(lookup, Object.class, void.class);
       
   335         findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
       
   336 
       
   337         // unnamed
       
   338         findConstructor(lookup, unnamedClass, void.class);
       
   339     }
       
   340 
       
   341     /**
       
   342      * Invokes Lookup findConstructor with a method type constructored from the
       
   343      * given return and parameter types, expecting IllegalAccessException to be
       
   344      * thrown.
       
   345      */
       
   346     static void findConstructorExpectingIAE(Lookup lookup,
       
   347                                             Class<?> clazz,
       
   348                                             Class<?> rtype,
       
   349                                             Class<?>... ptypes) throws Exception {
       
   350         try {
       
   351             findConstructor(lookup, clazz, rtype, ptypes);
       
   352             assertTrue(false);
       
   353         } catch (IllegalAccessException expected) { }
       
   354     }
       
   355 
       
   356     /**
       
   357      * Invokes Lookup findConstructor with a method type constructored from the
       
   358      * given return and parameter types.
       
   359      */
       
   360     static MethodHandle findConstructor(Lookup lookup,
       
   361                                         Class<?> clazz,
       
   362                                         Class<?> rtype,
       
   363                                         Class<?>... ptypes) throws Exception {
       
   364         MethodType mt = MethodType.methodType(rtype, ptypes);
       
   365         return lookup.findConstructor(clazz, mt);
       
   366     }
       
   367 }