Path: blob/master/test/jdk/java/lang/ClassLoader/securityManager/ClassLoaderTest.java
41153 views
/*1* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 816842326* @summary Different types of ClassLoader running with(out) SecurityManager and27* (in)valid security policy file.28* @library /test/lib29* @modules java.base/jdk.internal.module30* @build jdk.test.lib.util.JarUtils31* @build TestClassLoader TestClient32* @run main ClassLoaderTest -noPolicy33* @run main ClassLoaderTest -validPolicy34* @run main ClassLoaderTest -invalidPolicy35* @run main ClassLoaderTest -noPolicy -customSCL36* @run main ClassLoaderTest -validPolicy -customSCL37* @run main ClassLoaderTest -invalidPolicy -customSCL38*/39import java.io.File;40import java.io.OutputStream;41import java.nio.file.Files;42import java.nio.file.Path;43import java.nio.file.Paths;44import java.nio.file.StandardCopyOption;45import java.util.stream.Stream;46import java.lang.module.ModuleDescriptor;47import java.util.Collections;48import java.util.LinkedList;49import java.util.List;50import jdk.internal.module.ModuleInfoWriter;51import jdk.test.lib.process.ProcessTools;52import jdk.test.lib.util.JarUtils;5354public class ClassLoaderTest {5556private static final String SRC = System.getProperty("test.src");57private static final Path TEST_CLASSES =58Paths.get(System.getProperty("test.classes"));59private static final Path ARTIFACT_DIR = Paths.get("jars");60private static final Path VALID_POLICY = Paths.get(SRC, "valid.policy");61private static final Path INVALID_POLICY62= Paths.get(SRC, "malformed.policy");63/*64* Here is the naming convention followed for each jar.65* cl.jar - Regular custom class loader jar.66* mcl.jar - Modular custom class loader jar.67* c.jar - Regular client jar.68* mc.jar - Modular client jar.69* amc.jar - Modular client referring automated custom class loader jar.70*/71private static final Path CL_JAR = ARTIFACT_DIR.resolve("cl.jar");72private static final Path MCL_JAR = ARTIFACT_DIR.resolve("mcl.jar");73private static final Path C_JAR = ARTIFACT_DIR.resolve("c.jar");74private static final Path MC_JAR = ARTIFACT_DIR.resolve("mc.jar");75private static final Path AMC_JAR = ARTIFACT_DIR.resolve("amc.jar");7677// Expected output messages78private static final String MISSING_MODULE =79"Module cl not found, required by mc";80private static final String POLICY_ERROR =81"java.security.policy: error parsing file";82private static final String SYSTEM_CL_MSG =83"jdk.internal.loader.ClassLoaders$AppClassLoader";84private static final String CUSTOM_CL_MSG = "cl.TestClassLoader";8586// Member vars87private final boolean useSCL; // Use default system loader, or custom88private final String smMsg; // Security manager message, or ""89private final String autoAddModArg; // Flag to add cl modules, or ""90private final String addmodArg; // Flag to add mcl modules, or ""91private final String expectedStatus;// Expected exit status from client92private final String expectedMsg; // Expected output message from client9394// Common set of VM arguments used in all test cases95private final List<String> commonArgs;9697public ClassLoaderTest(Path policy, boolean useSCL) {98this.useSCL = useSCL;99100List<String> argList = new LinkedList<>();101argList.add("-Duser.language=en");102argList.add("-Duser.region=US");103104boolean malformedPolicy = false;105if (policy == null) {106smMsg = "Without SecurityManager";107} else {108malformedPolicy = policy.equals(INVALID_POLICY);109argList.add("-Djava.security.manager");110argList.add("-Djava.security.policy=" +111policy.toFile().getAbsolutePath());112smMsg = "With SecurityManager";113}114115if (useSCL) {116autoAddModArg = "";117addmodArg = "";118} else {119argList.add("-Djava.system.class.loader=cl.TestClassLoader");120autoAddModArg = "--add-modules=cl";121addmodArg = "--add-modules=mcl";122}123124if (malformedPolicy) {125expectedStatus = "FAIL";126expectedMsg = POLICY_ERROR;127} else if (useSCL) {128expectedStatus = "PASS";129expectedMsg = SYSTEM_CL_MSG;130} else {131expectedStatus = "PASS";132expectedMsg = CUSTOM_CL_MSG;133}134commonArgs = Collections.unmodifiableList(argList);135}136137public static void main(String[] args) throws Exception {138Path policy;139if (args[0].equals("-noPolicy")) {140policy = null;141} else if (args[0].equals("-validPolicy")) {142policy = VALID_POLICY;143} else if (args[0].equals("-invalidPolicy")) {144policy = INVALID_POLICY;145} else {146throw new RuntimeException("Unknown policy arg: " + args[0]);147}148149boolean useSystemLoader = true;150if (args.length > 1) {151if (args[1].equals("-customSCL")) {152useSystemLoader = false;153} else {154throw new RuntimeException("Unknown custom loader arg: " + args[1]);155}156}157158ClassLoaderTest test = new ClassLoaderTest(policy, useSystemLoader);159setUp();160test.processForPolicyFile();161}162163/**164* Test cases are based on the following logic,165* given: a policyFile in {none, valid, malformed} and166* a classLoader in {SystemClassLoader, CustomClassLoader}:167* for (clientModule : {"NAMED", "UNNAMED"}) {168* for (classLoaderModule : {"NAMED", "UNNAMED"}) {169* Create and run java command for each possible Test case170* }171* }172*/173private void processForPolicyFile() throws Exception {174final String regLoaderLoc = CL_JAR.toFile().getAbsolutePath();175final String modLoadrLoc = MCL_JAR.toFile().getAbsolutePath();176final String regClientLoc = C_JAR.toFile().getAbsolutePath();177final String modClientLoc = MC_JAR.toFile().getAbsolutePath();178final String autoModCloc = AMC_JAR.toFile().getAbsolutePath();179final String separator = File.pathSeparator;180181// NAMED-NAMED:182System.out.println("Case:- Modular Client and " +183((useSCL) ? "SystemClassLoader"184: "Modular CustomClassLoader") + " " + smMsg);185execute("--module-path", modClientLoc + separator + modLoadrLoc, "-m",186"mc/c.TestClient");187188// NAMED-UNNAMED:189System.out.println("Case:- Modular Client and " + ((useSCL)190? "SystemClassLoader"191: "Unknown modular CustomClassLoader") + " " + smMsg);192execute(new String[] {"--module-path", autoModCloc, "-cp", regLoaderLoc,193"-m", "mc/c.TestClient"},194"FAIL", MISSING_MODULE);195196// UNNAMED-NAMED:197System.out.println("Case:- Unknown modular Client and " +198((useSCL) ? "SystemClassLoader"199: "Modular CustomClassLoader") + " " + smMsg);200execute("-cp", regClientLoc, "--module-path", modLoadrLoc, addmodArg,201"c.TestClient");202203// UNNAMED-UNNAMED:204System.out.println("Case:- Unknown modular Client and " +205((useSCL) ? "SystemClassLoader"206: "Unknown modular CustomClassLoader") + " " + smMsg);207execute("-cp", regClientLoc + separator + regLoaderLoc, "c.TestClient");208209// Regular jars in module-path210System.out.println("Case:- Regular Client and " + ((useSCL)211? "SystemClassLoader"212: "Unknown modular CustomClassLoader") +213" inside --module-path " + smMsg);214execute("--module-path", regClientLoc + separator + regLoaderLoc,215autoAddModArg, "-m", "c/c.TestClient");216217// Modular jars in class-path218System.out.println("Case:- Modular Client and " +219((useSCL) ? "SystemClassLoader"220: "Modular CustomClassLoader") + " in -cp " + smMsg);221execute("-cp", modClientLoc + separator + modLoadrLoc, "c.TestClient");222}223224private void execute(String... args) throws Exception {225execute(args, this.expectedStatus, this.expectedMsg);226}227228/**229* Execute with command arguments and process the result.230*/231private void execute(String[] args, String status, String msg) throws Exception {232233// Combine with commonArgs, and perform sanity check234String[] safeArgs = Stream.concat(commonArgs.stream(), Stream.of(args))235.filter(s -> {236if (s.contains(" ")) { throw new RuntimeException("No spaces in args");}237return !s.isEmpty();238}).toArray(String[]::new);239String out = ProcessTools.executeTestJvm(safeArgs).getOutput();240// Handle response.241if ("PASS".equals(status) && out.contains(msg)) {242System.out.println("PASS: Expected Result: " + msg);243} else if ("FAIL".equals(status) && out.contains(msg)) {244System.out.printf("PASS: Expected Failure: " + msg);245} else if (out.contains("Exception") || out.contains("Error")) {246System.out.printf("OUTPUT: %s", out);247throw new RuntimeException("FAIL: Unknown Exception.");248} else {249System.out.printf("OUTPUT: %s", out);250throw new RuntimeException("FAIL: Unknown Test case found");251}252}253254/**255* Creates regular/modular jar files for TestClient and TestClassLoader.256*/257private static void setUp() throws Exception {258259// Generate regular jar files for TestClient and TestClassLoader260JarUtils.createJarFile(CL_JAR, TEST_CLASSES,261"cl/TestClassLoader.class");262JarUtils.createJarFile(C_JAR, TEST_CLASSES,263"c/TestClient.class");264// Generate modular jar files for TestClient and TestClassLoader with265// their corresponding ModuleDescriptor.266Files.copy(CL_JAR, MCL_JAR,267StandardCopyOption.REPLACE_EXISTING);268updateModuleDescr(MCL_JAR, ModuleDescriptor.newModule("mcl")269.exports("cl").requires("java.base").build());270Files.copy(C_JAR, MC_JAR,271StandardCopyOption.REPLACE_EXISTING);272updateModuleDescr(MC_JAR, ModuleDescriptor.newModule("mc")273.exports("c").requires("java.base").requires("mcl").build());274Files.copy(C_JAR, AMC_JAR,275StandardCopyOption.REPLACE_EXISTING);276updateModuleDescr(AMC_JAR, ModuleDescriptor.newModule("mc")277.exports("c").requires("java.base").requires("cl").build());278}279280/**281* Update regular jars and include module-info.class inside it to make282* modular jars.283*/284private static void updateModuleDescr(Path jar, ModuleDescriptor mDescr)285throws Exception {286if (mDescr != null) {287Path dir = Files.createTempDirectory("tmp");288Path mi = dir.resolve("module-info.class");289try (OutputStream out = Files.newOutputStream(mi)) {290ModuleInfoWriter.write(mDescr, out);291}292System.out.format("Adding 'module-info.class' to jar '%s'%n", jar);293JarUtils.updateJarFile(jar, dir);294}295}296}297298299