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 import java.io.File; 25 import java.io.PrintWriter; 26 import java.io.StringWriter; 27 import java.nio.file.Files; 28 import java.nio.file.Path; 29 import java.nio.file.Paths; 30 import java.util.ArrayList; 31 import java.util.List; 32 import java.util.spi.ToolProvider; 33 import java.util.stream.Collectors; 34 import java.util.stream.Stream; 35 36 import static jdk.testlibrary.Asserts.assertTrue; 37 import static jdk.testlibrary.ProcessTools.*; 38 39 import org.testng.annotations.BeforeTest; 40 import org.testng.annotations.Test; 41 import static org.testng.Assert.*; 42 43 /** 44 * @test 45 * @bug 8174826 46 * @library /lib/testlibrary 47 * @modules jdk.compiler jdk.jlink 48 * @build BindServices CompilerUtils jdk.testlibrary.ProcessTools 49 * @run testng BindServices 50 */ 51 52 public class BindServices { 53 private static final String JAVA_HOME = System.getProperty("java.home"); 54 private static final String TEST_SRC = System.getProperty("test.src"); 55 56 private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 57 private static final Path MODS_DIR = Paths.get("mods"); 58 59 private static final String MODULE_PATH = 60 Paths.get(JAVA_HOME, "jmods").toString() + 61 File.pathSeparator + MODS_DIR.toString(); 62 63 // the names of the modules in this test 64 private static String[] modules = new String[] {"m1", "m2", "m3"}; 65 66 67 private static boolean hasJmods() { 68 if (!Files.exists(Paths.get(JAVA_HOME, "jmods"))) { 69 System.err.println("Test skipped. NO jmods directory"); 70 return false; 71 } 72 return true; 73 } 74 75 /* 76 * Compiles all modules used by the test 77 */ 78 @BeforeTest 79 public void compileAll() throws Throwable { 80 if (!hasJmods()) return; 81 82 for (String mn : modules) { 83 Path msrc = SRC_DIR.resolve(mn); 84 assertTrue(CompilerUtils.compile(msrc, MODS_DIR, 85 "--module-source-path", SRC_DIR.toString())); 86 } 87 } 88 89 @Test 90 public void noServiceBinding() throws Throwable { 91 if (!hasJmods()) return; 92 93 Path dir = Paths.get("noServiceBinding"); 94 95 // no service binding and does not link m2,m3 providers. 96 JLink.run("--output", dir.toString(), 97 "--module-path", MODULE_PATH, 98 "--add-modules", "m1").output(); 99 100 testImage(dir, "m1"); 101 } 102 103 @Test 104 public void fullServiceBinding() throws Throwable { 105 if (!hasJmods()) return; 106 107 Path dir = Paths.get("fullServiceBinding"); 108 109 // full service binding 110 // m2 is a provider used by m1. During service binding, when m2 is 111 // resolved, m2 uses p2.T that causes m3 to be linked as it is a 112 // provider to p2.T 113 JLink.run("--output", dir.toString(), 114 "--module-path", MODULE_PATH, 115 "--add-modules", "m1", 116 "--bind-services", 117 "--limit-modules", "m1,m2,m3,java.base"); 118 119 testImage(dir, "m1", "m2", "m3"); 120 } 121 122 @Test 123 public void testVerbose() throws Throwable { 124 if (!hasJmods()) return; 125 126 Path dir = Paths.get("verbose"); 127 128 List<String> output = 129 JLink.run("--output", dir.toString(), 130 "--module-path", MODULE_PATH, 131 "--add-modules", "m1", 132 "--bind-services", 133 "--verbose", 134 "--limit-modules", "m1,m2,m3,java.base").output(); 135 136 List<String> expected = List.of( 137 "module m1 (" + MODS_DIR.resolve("m1").toUri().toString() + ")", 138 "module m2 (" + MODS_DIR.resolve("m2").toUri().toString() + ")", 139 "module m3 (" + MODS_DIR.resolve("m3").toUri().toString() + ")", 140 "module m1 provides p1.S, used by m1", 141 "module m2 provides p1.S, used by m1", 142 "module m2 provides p2.T, used by m2", 143 "module m3 provides p2.T, used by m2" 144 ); 145 146 assertTrue(output.containsAll(expected)); 147 148 testImage(dir, "m1", "m2", "m3"); 149 } 150 151 @Test 152 public void testVerboseAndNoBindServices() throws Throwable { 153 if (!hasJmods()) return; 154 155 Path dir = Paths.get("verboseNoBind"); 156 157 List<String> output = 158 JLink.run("--output", dir.toString(), 159 "--module-path", MODULE_PATH, 160 "--verbose", 161 "--add-modules", "m1").output(); 162 163 assertTrue(output.contains("module m1 provides p1.S, used by m1")); 164 165 testImage(dir, "m1"); 166 } 167 168 /* 169 * Tests the given ${java.home} to only contain the specified modules 170 */ 171 private void testImage(Path javaHome, String... modules) throws Throwable { 172 Path java = javaHome.resolve("bin").resolve("java"); 173 String[] cmd = Stream.concat( 174 Stream.of(java.toString(), "-m", "m1/p1.Main"), 175 Stream.of(modules)).toArray(String[]::new); 176 177 assertTrue(executeProcess(cmd).outputTo(System.out) 178 .errorTo(System.out) 179 .getExitValue() == 0); 180 } 181 182 static class JLink { 183 static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink") 184 .orElseThrow(() -> 185 new RuntimeException("jlink tool not found") 186 ); 187 188 static JLink run(String... options) { 189 JLink jlink = new JLink(); 190 assertTrue(jlink.execute(options) == 0); 191 return jlink; 192 } 193 194 final List<String> output = new ArrayList<>(); 195 private int execute(String... options) { 196 System.out.println("jlink " + 197 Stream.of(options).collect(Collectors.joining(" "))); 198 199 StringWriter writer = new StringWriter(); 200 PrintWriter pw = new PrintWriter(writer); 201 int rc = JLINK_TOOL.run(pw, pw, options); 202 System.out.println(writer.toString()); 203 Stream.of(writer.toString().split("\\v")) 204 .map(String::trim) 205 .forEach(output::add); 206 return rc; 207 } 208 209 boolean contains(String s) { 210 return output.contains(s); 211 } 212 213 List<String> output() { 214 return output; 215 } 216 } 217 }