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