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 jdk.compiler
  27  * @summary Test java.lang.reflect.Module methods that specify permission checks
  28  * @run main/othervm -Djava.security.policy=${test.src}/allow.policy WithSecurityManager allow
  29  * @run main/othervm WithSecurityManager deny
  30  */
  31 
  32 import java.io.IOException;
  33 import java.io.InputStream;
  34 import java.lang.module.Configuration;
  35 import java.lang.module.ModuleFinder;
  36 import java.lang.module.ModuleReference;
  37 import java.lang.reflect.Layer;
  38 import java.lang.reflect.Module;
  39 import java.util.Collections;
  40 import java.util.Optional;
  41 import java.util.Set;
  42 
  43 /**
  44  * Test java.lang.reflect.Module methods that specify permission checks.
  45  */
  46 
  47 public class WithSecurityManager {
  48 
  49     // a module that will be loaded into a child layer
  50     static final String ANOTHER_MODULE          = "jdk.compiler";
  51     static final String ANOTHER_MODULE_RESOURCE = "com/sun/tools/javac/Main.class";
  52 
  53     public static void main(String[] args) throws IOException {
  54         boolean allow = args[0].equals("allow");
  55 
  56         // base module, in the boot layer
  57         Module base = Object.class.getModule();
  58 
  59         // another module, in a child layer
  60         Module other = loadModuleInChildLayer(ANOTHER_MODULE);
  61         assertTrue(other.getLayer() != Layer.boot());
  62 
  63         System.setSecurityManager(new SecurityManager());
  64 
  65         test(base, "java/lang/Object.class", allow);
  66         test(other, ANOTHER_MODULE_RESOURCE, allow);
  67     }
  68 
  69     /**
  70      * Test the permission checks by invoking methods on the given module.
  71      *
  72      * If {@code allow} is {@code true} then the permission checks should succeed.
  73      */
  74     static void test(Module m, String name, boolean allow) throws IOException {
  75 
  76         // test Module::getClassLoader
  77         System.out.format("Test getClassLoader on %s ...%n", m);
  78         try {
  79             ClassLoader cl = m.getClassLoader();
  80             System.out.println(cl);
  81             if (!allow)
  82                 assertTrue("getClassLoader should have failed", false);
  83         } catch (SecurityException e) {
  84             System.out.println(e + " thrown");
  85             if (allow)
  86                 throw e;
  87         }
  88 
  89         // test Module::getResourceAsStream
  90         System.out.format("Test getResourceAsStream(\"%s\") on %s ...%n", name, m);
  91         try (InputStream in = m.getResourceAsStream(name)) {
  92             System.out.println(in);
  93             if (allow && (in == null))
  94                 assertTrue(name + " not found", false);
  95             if (!allow && (in != null))
  96                 assertTrue(name + " should not be found", false);
  97         }
  98 
  99     }
 100 
 101     /**
 102      * Create a module layer that contains the given system module.
 103      */
 104     static Module loadModuleInChildLayer(String mn) {
 105         Optional<ModuleReference> omref = ModuleFinder.ofSystem().find(mn);
 106         assertTrue("module " + mn + " not a system module", omref.isPresent());
 107 
 108         // create a ModuleFinder that only finds this module
 109         ModuleReference mref = omref.get();
 110         ModuleFinder finder = new ModuleFinder() {
 111             @Override
 112             public Optional<ModuleReference> find(String name) {
 113                 if (name.equals(mn))
 114                     return Optional.of(mref);
 115                 else
 116                     return Optional.empty();
 117             }
 118 
 119             @Override
 120             public Set<ModuleReference> findAll() {
 121                 return Collections.singleton(mref);
 122             }
 123         };
 124 
 125         // create a child configuration and layer with this module
 126         Layer bootLayer = Layer.boot();
 127         Configuration cf = bootLayer
 128             .configuration()
 129             .resolveRequires(finder, ModuleFinder.of(), Set.of(ANOTHER_MODULE));
 130         Layer layer = bootLayer.defineModulesWithOneLoader(cf, null);
 131 
 132         Optional<Module> om = layer.findModule(mn);
 133         assertTrue("module " + mn + " not in child layer", om.isPresent());
 134         return om.get();
 135     }
 136 
 137     static void assertTrue(String msg, boolean e) {
 138         if (!e)
 139             throw new RuntimeException(msg);
 140     }
 141 
 142     static void assertTrue(boolean e) {
 143         if (!e)
 144             throw new RuntimeException();
 145     }
 146 
 147 }