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 38 import org.testng.annotations.BeforeTest; 39 import org.testng.annotations.Test; 40 import static org.testng.Assert.*; 41 42 /** 43 * @test 44 * @bug 8174826 45 * @library /lib/testlibrary 46 * @modules jdk.charsets jdk.compiler jdk.jlink 47 * @build SuggestProviders CompilerUtils 48 * @run testng SuggestProviders 49 */ 50 51 public class SuggestProviders { 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 suggestProviders() throws Throwable { 90 if (!hasJmods()) return; 91 92 List<String> output = JLink.run("--module-path", MODULE_PATH, 93 "--add-modules", "m1", 94 "--suggest-providers").output(); 95 // check a subset of services used by java.base 96 List<String> expected = List.of( 97 "uses java.lang.System$LoggerFinder", 98 "uses java.net.ContentHandlerFactory", 99 "uses java.net.spi.URLStreamHandlerProvider", 100 "uses java.nio.channels.spi.AsynchronousChannelProvider", 101 "uses java.nio.channels.spi.SelectorProvider", 102 "uses java.nio.charset.spi.CharsetProvider", 103 "uses java.nio.file.spi.FileSystemProvider", 104 "uses java.nio.file.spi.FileTypeDetector", 105 "uses java.security.Provider", 106 "uses java.util.spi.ToolProvider", 107 "uses p1.S", 108 "module jdk.charsets provides java.nio.charset.spi.CharsetProvider, used by java.base", 109 "module jdk.compiler provides java.util.spi.ToolProvider, used by java.base", 110 "module jdk.jlink provides java.util.spi.ToolProvider, used by java.base", 111 "module m1 provides p1.S, used by m1", 112 "module m2 provides p1.S, used by m1" 113 ); 114 115 assertTrue(output.containsAll(expected)); 116 } 117 118 @Test 119 public void providersForServices() throws Throwable { 120 if (!hasJmods()) return; 121 122 List<String> output = 123 JLink.run("--module-path", MODULE_PATH, 124 "--add-modules", "m1", 125 "--suggest-providers", 126 "java.nio.charset.spi.CharsetProvider,p1.S,p2.T").output(); 127 128 System.out.println(output); 129 List<String> expected = List.of( 130 "module jdk.charsets provides java.nio.charset.spi.CharsetProvider, used by java.base", 131 "module m1 provides p1.S, used by m1", 132 "module m2 provides p1.S, used by m1", 133 "module m2 provides p2.T, used by m2", 134 "module m3 provides p2.T, used by m2" 135 ); 136 137 assertTrue(output.containsAll(expected)); 138 } 139 140 @Test 141 public void unusedService() throws Throwable { 142 if (!hasJmods()) return; 143 144 List<String> output = 145 JLink.run("--module-path", MODULE_PATH, 146 "--add-modules", "m1", 147 "--suggest-providers", 148 "nonExistentType").output(); 149 150 System.out.println(output); 151 List<String> expected = List.of( 152 "Services specified in --suggest-providers not used: nonExistentType" 153 ); 154 155 assertTrue(output.containsAll(expected)); 156 } 157 158 @Test 159 public void noSuggestProviders() throws Throwable { 160 if (!hasJmods()) return; 161 162 List<String> output = 163 JLink.run("--module-path", MODULE_PATH, 164 "--add-modules", "m1", 165 "--bind-services", 166 "--limit-modules", "m1,m2,m3,java.base", 167 "--suggest-providers").output(); 168 169 String expected = "--bind-services option is specified. No additional providers suggested."; 170 assertTrue(output.contains(expected)); 171 172 } 173 174 @Test 175 public void suggestNotProvider() throws Throwable { 176 if (!hasJmods()) return; 177 178 List<String> output = 179 JLink.run("--module-path", MODULE_PATH, 180 "--add-modules", "m1", 181 "--suggest-providers", 182 "java.util.List").output(); 183 184 System.out.println(output); 185 List<String> expected = List.of( 186 "Services specified in --suggest-providers not used: java.util.List" 187 ); 188 189 assertTrue(output.containsAll(expected)); 190 } 191 192 @Test 193 public void noOneUsesProvider() throws Throwable { 194 if (!hasJmods()) return; 195 196 List<String> output = 197 JLink.run("--module-path", MODULE_PATH, 198 "--add-modules", "m4", 199 "--suggest-providers", 200 "p4.Impl").output(); 201 202 System.out.println(output); 203 List<String> expected = List.of( 204 "Services specified in --suggest-providers not used: p4.Impl" 205 ); 206 207 assertTrue(output.containsAll(expected)); 208 } 209 210 static class JLink { 211 static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink") 212 .orElseThrow(() -> 213 new RuntimeException("jlink tool not found") 214 ); 215 216 static JLink run(String... options) { 217 JLink jlink = new JLink(); 218 assertTrue(jlink.execute(options) == 0); 219 return jlink; 220 } 221 222 final List<String> output = new ArrayList<>(); 223 private int execute(String... options) { 224 System.out.println("jlink " + 225 Stream.of(options).collect(Collectors.joining(" "))); 226 227 StringWriter writer = new StringWriter(); 228 PrintWriter pw = new PrintWriter(writer); 229 int rc = JLINK_TOOL.run(pw, pw, options); 230 System.out.println(writer.toString()); 231 Stream.of(writer.toString().split("\\v")) 232 .map(String::trim) 233 .forEach(output::add); 234 return rc; 235 } 236 237 boolean contains(String s) { 238 return output.contains(s); 239 } 240 241 List<String> output() { 242 return output; 243 } 244 } 245 }