1 /* 2 * Copyright (c) 2015, 2016, 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 /** 25 * @test 26 * @library /lib/testlibrary 27 * @modules java.base/jdk.internal.module 28 * jdk.compiler 29 * jdk.jlink 30 * @build ModuleReaderTest CompilerUtils JarUtils 31 * @run testng ModuleReaderTest 32 * @summary Basic tests for java.lang.module.ModuleReader 33 */ 34 35 import java.io.File; 36 import java.io.IOException; 37 import java.io.InputStream; 38 import java.lang.module.ModuleFinder; 39 import java.lang.module.ModuleReader; 40 import java.lang.module.ModuleReference; 41 import java.lang.reflect.Module; 42 import java.net.URI; 43 import java.net.URL; 44 import java.net.URLConnection; 45 import java.nio.ByteBuffer; 46 import java.nio.file.Files; 47 import java.nio.file.Path; 48 import java.nio.file.Paths; 49 import java.util.Arrays; 50 import java.util.Optional; 51 import java.util.spi.ToolProvider; 52 53 import jdk.internal.module.ConfigurableModuleFinder; 54 import jdk.internal.module.ConfigurableModuleFinder.Phase; 55 56 import org.testng.annotations.BeforeTest; 57 import org.testng.annotations.Test; 58 import static org.testng.Assert.*; 59 60 @Test 61 public class ModuleReaderTest { 62 63 private static final String TEST_SRC = System.getProperty("test.src"); 64 65 private static final Path USER_DIR = Paths.get(System.getProperty("user.dir")); 66 private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 67 private static final Path MODS_DIR = Paths.get("mods"); 68 69 // the module name of the base module 70 private static final String BASE_MODULE = "java.base"; 71 72 // the module name of the test module 73 private static final String TEST_MODULE = "m"; 74 75 // resources in the base module 76 private static final String[] BASE_RESOURCES = { 77 "java/lang/Object.class" 78 }; 79 80 // resources in test module (can't use module-info.class as a test 81 // resource as it will be modified by the jmod tool) 82 private static final String[] TEST_RESOURCES = { 83 "p/Main.class" 84 }; 85 86 // a resource that is not in the base or test module 87 private static final String NOT_A_RESOURCE = "NotAResource"; 88 89 90 @BeforeTest 91 public void compileTestModule() throws Exception { 92 93 // javac -d mods/$TESTMODULE src/$TESTMODULE/** 94 boolean compiled 95 = CompilerUtils.compile(SRC_DIR.resolve(TEST_MODULE), 96 MODS_DIR.resolve(TEST_MODULE)); 97 assertTrue(compiled, "test module did not compile"); 98 } 99 100 101 /** 102 * Test ModuleReader to module in runtime image 103 */ 104 public void testImage() throws Exception { 105 106 ModuleFinder finder = ModuleFinder.ofSystem(); 107 ModuleReference mref = finder.find(BASE_MODULE).get(); 108 ModuleReader reader = mref.open(); 109 110 try (reader) { 111 112 for (String name : BASE_RESOURCES) { 113 byte[] expectedBytes; 114 Module baseModule = Object.class.getModule(); 115 try (InputStream in = baseModule.getResourceAsStream(name)) { 116 expectedBytes = in.readAllBytes(); 117 } 118 119 testFind(reader, name, expectedBytes); 120 testOpen(reader, name, expectedBytes); 121 testRead(reader, name, expectedBytes); 122 123 } 124 125 // test "not found" 126 assertFalse(reader.find(NOT_A_RESOURCE).isPresent()); 127 assertFalse(reader.open(NOT_A_RESOURCE).isPresent()); 128 assertFalse(reader.read(NOT_A_RESOURCE).isPresent()); 129 130 131 // test nulls 132 try { 133 reader.find(null); 134 assertTrue(false); 135 } catch (NullPointerException expected) { } 136 137 try { 138 reader.open(null); 139 assertTrue(false); 140 } catch (NullPointerException expected) { } 141 142 try { 143 reader.read(null); 144 assertTrue(false); 145 } catch (NullPointerException expected) { } 146 147 try { 148 reader.release(null); 149 assertTrue(false); 150 } catch (NullPointerException expected) { } 151 152 } 153 154 // test closed ModuleReader 155 try { 156 reader.open(BASE_RESOURCES[0]); 157 assertTrue(false); 158 } catch (IOException expected) { } 159 160 161 try { 162 reader.read(BASE_RESOURCES[0]); 163 assertTrue(false); 164 } catch (IOException expected) { } 165 } 166 167 168 /** 169 * Test ModuleReader to exploded module 170 */ 171 public void testExplodedModule() throws Exception { 172 test(MODS_DIR); 173 } 174 175 176 /** 177 * Test ModuleReader to modular JAR 178 */ 179 public void testModularJar() throws Exception { 180 Path dir = Files.createTempDirectory(USER_DIR, "mlib"); 181 182 // jar cf mlib/${TESTMODULE}.jar -C mods . 183 JarUtils.createJarFile(dir.resolve("m.jar"), 184 MODS_DIR.resolve(TEST_MODULE)); 185 186 test(dir); 187 } 188 189 190 /** 191 * Test ModuleReader to JMOD 192 */ 193 public void testJMod() throws Exception { 194 Path dir = Files.createTempDirectory(USER_DIR, "mlib"); 195 196 // jmod create --class-path mods/${TESTMODULE} mlib/${TESTMODULE}.jmod 197 String cp = MODS_DIR.resolve(TEST_MODULE).toString(); 198 String jmod = dir.resolve("m.jmod").toString(); 199 String[] args = { "create", "--class-path", cp, jmod }; 200 ToolProvider jmodTool = ToolProvider.findFirst("jmod") 201 .orElseThrow(() -> 202 new RuntimeException("jmod tool not found") 203 ); 204 assertEquals(jmodTool.run(System.out, System.out, args), 0); 205 206 test(dir); 207 } 208 209 210 /** 211 * The test module is found on the given module path. Open a ModuleReader 212 * to the test module and test the reader. 213 */ 214 void test(Path mp) throws Exception { 215 216 ModuleFinder finder = ModuleFinder.of(mp); 217 if (finder instanceof ConfigurableModuleFinder) { 218 // need ModuleFinder to be in the phase to find JMOD files 219 ((ConfigurableModuleFinder)finder).configurePhase(Phase.LINK_TIME); 220 } 221 222 ModuleReference mref = finder.find(TEST_MODULE).get(); 223 ModuleReader reader = mref.open(); 224 225 try (reader) { 226 227 // test each of the known resources in the module 228 for (String name : TEST_RESOURCES) { 229 byte[] expectedBytes 230 = Files.readAllBytes(MODS_DIR 231 .resolve(TEST_MODULE) 232 .resolve(name.replace('/', File.separatorChar))); 233 234 testFind(reader, name, expectedBytes); 235 testOpen(reader, name, expectedBytes); 236 testRead(reader, name, expectedBytes); 237 } 238 239 // test "not found" 240 assertFalse(reader.find(NOT_A_RESOURCE).isPresent()); 241 assertFalse(reader.open(NOT_A_RESOURCE).isPresent()); 242 assertFalse(reader.read(NOT_A_RESOURCE).isPresent()); 243 244 // test nulls 245 try { 246 reader.find(null); 247 assertTrue(false); 248 } catch (NullPointerException expected) { } 249 250 try { 251 reader.open(null); 252 assertTrue(false); 253 } catch (NullPointerException expected) { } 254 255 try { 256 reader.read(null); 257 assertTrue(false); 258 } catch (NullPointerException expected) { } 259 260 try { 261 reader.release(null); 262 throw new RuntimeException(); 263 } catch (NullPointerException expected) { } 264 265 } 266 267 // test closed ModuleReader 268 try { 269 reader.open(TEST_RESOURCES[0]); 270 assertTrue(false); 271 } catch (IOException expected) { } 272 273 274 try { 275 reader.read(TEST_RESOURCES[0]); 276 assertTrue(false); 277 } catch (IOException expected) { } 278 } 279 280 /** 281 * Test ModuleReader#find 282 */ 283 void testFind(ModuleReader reader, String name, byte[] expectedBytes) 284 throws Exception 285 { 286 Optional<URI> ouri = reader.find(name); 287 assertTrue(ouri.isPresent()); 288 289 URL url = ouri.get().toURL(); 290 if (!url.getProtocol().equalsIgnoreCase("jmod")) { 291 URLConnection uc = url.openConnection(); 292 uc.setUseCaches(false); 293 try (InputStream in = uc.getInputStream()) { 294 byte[] bytes = in.readAllBytes(); 295 assertTrue(Arrays.equals(bytes, expectedBytes)); 296 } 297 } 298 } 299 300 /** 301 * Test ModuleReader#open 302 */ 303 void testOpen(ModuleReader reader, String name, byte[] expectedBytes) 304 throws Exception 305 { 306 Optional<InputStream> oin = reader.open(name); 307 assertTrue(oin.isPresent()); 308 309 InputStream in = oin.get(); 310 try (in) { 311 byte[] bytes = in.readAllBytes(); 312 assertTrue(Arrays.equals(bytes, expectedBytes)); 313 } 314 } 315 316 /** 317 * Test ModuleReader#read 318 */ 319 void testRead(ModuleReader reader, String name, byte[] expectedBytes) 320 throws Exception 321 { 322 Optional<ByteBuffer> obb = reader.read(name); 323 assertTrue(obb.isPresent()); 324 325 ByteBuffer bb = obb.get(); 326 try { 327 int rem = bb.remaining(); 328 assertTrue(rem == expectedBytes.length); 329 byte[] bytes = new byte[rem]; 330 bb.get(bytes); 331 assertTrue(Arrays.equals(bytes, expectedBytes)); 332 } finally { 333 reader.release(bb); 334 } 335 } 336 337 }