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