1 /* 2 * Copyright (c) 2015, 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 * @library /lib/testlibrary 27 * @modules jdk.compiler 28 * @build PatchTest CompilerUtils JarUtils jdk.testlibrary.* 29 * @run testng PatchTest 30 * @summary Basic test for -Xpatch 31 */ 32 33 import java.io.File; 34 import java.nio.file.Files; 35 import java.nio.file.Path; 36 import java.nio.file.Paths; 37 import java.util.stream.Collectors; 38 import java.util.stream.Stream; 39 40 import static jdk.testlibrary.ProcessTools.*; 41 42 import org.testng.annotations.BeforeTest; 43 import org.testng.annotations.Test; 44 import static org.testng.Assert.*; 45 46 47 /** 48 * Compiles and launches a test that uses -Xpatch with two directories of 49 * classes to override existing and add new classes to modules in the 50 * boot layer. 51 * 52 * The classes overridden or added via -Xpatch all define a public no-arg 53 * constructor and override toString to return "hi". This allows the launched 54 * test to check that the overridden classes are loaded. 55 */ 56 57 @Test 58 public class PatchTest { 59 60 // top-level source directory 61 private static final String TEST_SRC = System.getProperty("test.src"); 62 63 // source/destination tree for the test module 64 private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 65 private static final Path MODS_DIR = Paths.get("mods"); 66 67 // source/destination tree for patch tree 1 68 private static final Path SRC1_DIR = Paths.get(TEST_SRC, "src1"); 69 private static final Path PATCHES1_DIR = Paths.get("patches1"); 70 71 // source/destination tree for patch tree 2 72 private static final Path SRC2_DIR = Paths.get(TEST_SRC, "src2"); 73 private static final Path PATCHES2_DIR = Paths.get("patches2"); 74 75 // destination directory for patches packaged as JAR files 76 private static final Path PATCHES_DIR = Paths.get("patches"); 77 78 79 // the classes overridden or added with -Xpatch 80 private static final String[] CLASSES = { 81 82 // java.base = boot loader 83 "java.base/java.text.Annotation", // override class 84 "java.base/java.text.AnnotationBuddy", // add class to package 85 "java.base/java.lang2.Object", // new package 86 87 // jdk.naming.dns = platform class loader 88 "jdk.naming.dns/com.sun.jndi.dns.DnsClient", 89 "jdk.naming.dns/com.sun.jndi.dns.DnsClientBuddy", 90 "jdk.naming.dns/com.sun.jndi.dns2.Zone", 91 92 // jdk.compiler = application class loaded 93 "jdk.compiler/com.sun.tools.javac.Main", 94 "jdk.compiler/com.sun.tools.javac.MainBuddy", 95 "jdk.compiler/com.sun.tools.javac2.Main", 96 97 }; 98 99 100 @BeforeTest 101 public void setup() throws Exception { 102 103 // javac -d mods/test src/test/** 104 boolean compiled= CompilerUtils.compile(SRC_DIR.resolve("test"), 105 MODS_DIR.resolve("test")); 106 assertTrue(compiled, "classes did not compile"); 107 108 // javac -Xmodule:$MODULE -d patches1/$MODULE patches1/$MODULE/** 109 // jar cf patches/$MODULE-1.jar -C patches1/$MODULE . 110 for (Path src : Files.newDirectoryStream(SRC1_DIR)) { 111 Path output = PATCHES1_DIR.resolve(src.getFileName()); 112 String mn = src.getFileName().toString(); 113 compiled = CompilerUtils.compile(src, output, "-Xmodule:" + mn); 114 assertTrue(compiled, "classes did not compile"); 115 JarUtils.createJarFile(PATCHES_DIR.resolve(mn + "-1.jar"), output); 116 } 117 118 // javac -Xmodule:$MODULE -d patches2/$MODULE patches2/$MODULE/** 119 // jar cf patches/$MODULE-2.jar -C patches2/$MODULE . 120 for (Path src : Files.newDirectoryStream(SRC2_DIR)) { 121 Path output = PATCHES2_DIR.resolve(src.getFileName()); 122 String mn = src.getFileName().toString(); 123 compiled = CompilerUtils.compile(src, output, "-Xmodule:" + mn); 124 assertTrue(compiled, "classes did not compile"); 125 JarUtils.createJarFile(PATCHES_DIR.resolve(mn + "-2.jar"), output); 126 } 127 128 } 129 130 /** 131 * Run test with patches to java.base, jdk.naming.dns and jdk.compiler 132 */ 133 void runTest(String basePatches, String dnsPatches, String compilerPatches) 134 throws Exception 135 { 136 // the argument to the test is the list of classes overridden or added 137 String arg = Stream.of(CLASSES).collect(Collectors.joining(",")); 138 139 int exitValue 140 = executeTestJava("-Xpatch:java.base=" + basePatches, 141 "-Xpatch:jdk.naming.dns=" + dnsPatches, 142 "-Xpatch:jdk.compiler=" + compilerPatches, 143 "-XaddExports:java.base/java.lang2=test", 144 "-XaddExports:jdk.naming.dns/com.sun.jndi.dns=test", 145 "-XaddExports:jdk.naming.dns/com.sun.jndi.dns2=test", 146 "-XaddExports:jdk.compiler/com.sun.tools.javac2=test", 147 "-addmods", "jdk.naming.dns,jdk.compiler", 148 "-mp", MODS_DIR.toString(), 149 "-m", "test/jdk.test.Main", arg) 150 .outputTo(System.out) 151 .errorTo(System.out) 152 .getExitValue(); 153 154 assertTrue(exitValue == 0); 155 } 156 157 158 /** 159 * Run test with -Xpatch and exploded patches 160 */ 161 public void testWithExplodedPatches() throws Exception { 162 163 // patches1/java.base:patches2/java.base 164 String basePatches = PATCHES1_DIR.resolve("java.base") 165 + File.pathSeparator + PATCHES2_DIR.resolve("java.base"); 166 167 String dnsPatches = PATCHES1_DIR.resolve("jdk.naming.dns") 168 + File.pathSeparator + PATCHES2_DIR.resolve("jdk.naming.dns"); 169 170 String compilerPatches = PATCHES1_DIR.resolve("jdk.compiler") 171 + File.pathSeparator + PATCHES2_DIR.resolve("jdk.compiler"); 172 173 runTest(basePatches, dnsPatches, compilerPatches); 174 } 175 176 177 /** 178 * Run test with -Xpatch and patches in JAR files 179 */ 180 public void testWithJarPatches() throws Exception { 181 182 // patches/java.base-1.jar:patches/java-base-2.jar 183 String basePatches = PATCHES_DIR.resolve("java.base-1.jar") 184 + File.pathSeparator + PATCHES_DIR.resolve("java.base-2.jar"); 185 186 String dnsPatches = PATCHES_DIR.resolve("jdk.naming.dns-1.jar") 187 + File.pathSeparator + PATCHES_DIR.resolve("jdk.naming.dns-2.jar"); 188 189 String compilerPatches = PATCHES_DIR.resolve("jdk.compiler-1.jar") 190 + File.pathSeparator + PATCHES_DIR.resolve("jdk.compiler-2.jar"); 191 192 runTest(basePatches, dnsPatches, compilerPatches); 193 194 } 195 196 197 /** 198 * Run test with -Xpatch and patches in JAR files and exploded patches 199 */ 200 public void testWithJarAndExplodedPatches() throws Exception { 201 202 // patches/java.base-1.jar:patches2/java.base 203 String basePatches = PATCHES_DIR.resolve("java.base-1.jar") 204 + File.pathSeparator + PATCHES2_DIR.resolve("java.base"); 205 206 // patches1/jdk.naming.dns:patches/jdk.naming.dns-2.jar 207 String dnsPatches = PATCHES1_DIR.resolve("jdk.naming.dns") 208 + File.pathSeparator + PATCHES_DIR.resolve("jdk.naming.dns-2.jar"); 209 210 String compilerPatches = PATCHES1_DIR.resolve("jdk.compiler") 211 + File.pathSeparator + PATCHES_DIR.resolve("jdk.compiler-2.jar"); 212 213 runTest(basePatches, dnsPatches, compilerPatches); 214 215 } 216 }