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.test.lib.compiler.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"); 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").output(); 135 136 List<String> expected = List.of( 137 "m1 " + MODS_DIR.resolve("m1").toUri().toString(), 138 "m2 " + MODS_DIR.resolve("m2").toUri().toString(), 139 "m3 " + MODS_DIR.resolve("m3").toUri().toString(), 140 "java.base provides java.nio.file.spi.FileSystemProvider used by java.base", 141 "m1 provides p1.S used by m1", 142 "m2 provides p1.S used by m1", 143 "m2 provides p2.T used by m2", 144 "m3 provides p2.T used by m2", 145 "m3 provides p3.S not used by any observable module" 146 ); 147 148 assertTrue(output.containsAll(expected)); 149 150 testImage(dir, "m1", "m2", "m3"); 151 } 152 153 @Test 154 public void testVerboseAndNoBindServices() throws Throwable { 155 if (!hasJmods()) return; 156 157 Path dir = Paths.get("verboseNoBind"); 158 159 List<String> output = 160 JLink.run("--output", dir.toString(), 161 "--module-path", MODULE_PATH, 162 "--verbose", 163 "--add-modules", "m1").output(); 164 165 assertTrue(output.contains("m1 provides p1.S used by m1")); 166 167 testImage(dir, "m1"); 168 } 169 170 /* 171 * Tests the given ${java.home} to only contain the specified modules 172 */ 173 private void testImage(Path javaHome, String... modules) throws Throwable { 174 Path java = javaHome.resolve("bin").resolve("java"); 175 String[] cmd = Stream.concat( 176 Stream.of(java.toString(), "-m", "m1/p1.Main"), 177 Stream.of(modules)).toArray(String[]::new); 178 179 assertTrue(executeProcess(cmd).outputTo(System.out) 180 .errorTo(System.out) 181 .getExitValue() == 0); 182 } 183 184 static class JLink { 185 static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink") 186 .orElseThrow(() -> 187 new RuntimeException("jlink tool not found") 188 ); 189 190 static JLink run(String... options) { 191 JLink jlink = new JLink(); 192 assertTrue(jlink.execute(options) == 0); 193 return jlink; 194 } 195 196 final List<String> output = new ArrayList<>(); 197 private int execute(String... options) { 198 System.out.println("jlink " + 199 Stream.of(options).collect(Collectors.joining(" "))); 200 201 StringWriter writer = new StringWriter(); 202 PrintWriter pw = new PrintWriter(writer); 203 int rc = JLINK_TOOL.run(pw, pw, options); 204 System.out.println(writer.toString()); 205 Stream.of(writer.toString().split("\\v")) 206 .map(String::trim) 207 .forEach(output::add); 208 return rc; 209 } 210 211 boolean contains(String s) { 212 return output.contains(s); 213 } 214 215 List<String> output() { 216 return output; 217 } 218 } 219 }