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 static class JLink { 175 static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink") 176 .orElseThrow(() -> 177 new RuntimeException("jlink tool not found") 178 ); 179 180 static JLink run(String... options) { 181 JLink jlink = new JLink(); 182 assertTrue(jlink.execute(options) == 0); 183 return jlink; 184 } 185 186 final List<String> output = new ArrayList<>(); 187 private int execute(String... options) { 188 System.out.println("jlink " + 189 Stream.of(options).collect(Collectors.joining(" "))); 190 191 StringWriter writer = new StringWriter(); 192 PrintWriter pw = new PrintWriter(writer); 193 int rc = JLINK_TOOL.run(pw, pw, options); 194 System.out.println(writer.toString()); 195 Stream.of(writer.toString().split("\\v")) 196 .map(String::trim) 197 .forEach(output::add); 198 return rc; 199 } 200 201 boolean contains(String s) { 202 return output.contains(s); 203 } 204 205 List<String> output() { 206 return output; 207 } 208 } 209 }