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 * @bug 8160286
27 * @summary Test the recording and checking of module hashes
28 * @library /lib/testlibrary
29 * @modules java.base/jdk.internal.misc
30 * java.base/jdk.internal.module
31 * jdk.compiler
32 * jdk.jartool
33 * jdk.jlink
34 * @build CompilerUtils ModuleInfoMaker
35 * @run testng HashesTest
36 */
37
38 import java.io.File;
39 import java.io.IOException;
40 import java.io.InputStream;
41 import java.io.UncheckedIOException;
42 import java.lang.module.ModuleDescriptor;
43 import java.lang.module.ModuleFinder;
44 import java.lang.module.ModuleReader;
45 import java.lang.module.ModuleReference;
46 import java.nio.file.FileVisitResult;
47 import java.nio.file.Files;
48 import java.nio.file.Path;
49 import java.nio.file.Paths;
50 import java.nio.file.SimpleFileVisitor;
51 import java.nio.file.attribute.BasicFileAttributes;
52 import java.util.ArrayList;
53 import java.util.Arrays;
54 import java.util.Collections;
55 import java.util.List;
56 import java.util.Set;
57 import java.util.spi.ToolProvider;
58 import java.util.stream.Collectors;
59 import java.util.stream.Stream;
60
61 import jdk.internal.module.ModuleInfo;
62 import jdk.internal.module.ModuleHashes;
63 import jdk.internal.module.ModulePath;
64
65 import org.testng.annotations.Test;
66
67 import static org.testng.Assert.*;
68 import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
69
70 public class HashesTest {
71 static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
72 .orElseThrow(() ->
73 new RuntimeException("jmod tool not found")
74 );
75 static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
76 .orElseThrow(() ->
77 new RuntimeException("jar tool not found")
78 );
79
80 private final Path mods;
81 private final Path srcDir;
82 private final Path lib;
83 private final ModuleInfoMaker builder;
84 HashesTest(Path dest) throws IOException {
287 public static void testImageJmods1() throws IOException {
288 Path mpath = Paths.get(System.getProperty("java.home"), "jmods");
289 if (!Files.exists(mpath)) {
290 return;
291 }
292
293 Path dest = Paths.get("test6");
294 HashesTest ht = new HashesTest(dest);
295 ht.makeModule("m1", "jdk.compiler", "jdk.attach");
296 ht.makeModule("m2", "m1");
297 ht.makeModule("m3", "java.compiler");
298
299 ht.makeJar("m2");
300 ht.makeJar("m1",
301 "--module-path",
302 mpath.toString() + File.pathSeparator + ht.lib.toString(),
303 "--hash-modules", ".*");
304 validateImageJmodsTest(ht, mpath);
305 }
306
307 private static void validateImageJmodsTest(HashesTest ht, Path mpath)
308 throws IOException
309 {
310 // hash is recorded in m1 and not any other packaged modules on module path
311 ht.checkHashes("m1", "m2");
312 assertTrue(ht.hashes("m2") == null);
313
314 // should not override any JDK packaged modules
315 ModuleFinder finder = ModulePath.of(Runtime.version(), true, mpath);
316 assertTrue(ht.hashes(finder,"jdk.compiler") == null);
317 assertTrue(ht.hashes(finder,"jdk.attach") == null);
318 }
319
320 private void checkHashes(String mn, String... hashModules) throws IOException {
321 ModuleHashes hashes = hashes(mn);
322 assertTrue(hashes.names().equals(Set.of(hashModules)));
323 }
324
325 private ModuleHashes hashes(String name) {
326 ModuleFinder finder = ModulePath.of(Runtime.version(), true, lib);
327 return hashes(finder, name);
328 }
329
366 Files.delete(file);
367 return FileVisitResult.CONTINUE;
368 }
369
370 @Override
371 public FileVisitResult postVisitDirectory(Path dir, IOException exc)
372 throws IOException
373 {
374 Files.delete(dir);
375 return FileVisitResult.CONTINUE;
376 }
377 });
378 }
379
380
381 private void makeModule(String mn, String... deps) throws IOException {
382 makeModule(mn, null, deps);
383 }
384
385 private void makeModule(String mn, ModuleDescriptor.Requires.Modifier mod, String... deps)
386 throws IOException
387 {
388 if (mod != null && mod != TRANSITIVE && mod != STATIC) {
389 throw new IllegalArgumentException(mod.toString());
390 }
391
392 StringBuilder sb = new StringBuilder();
393 sb.append("module " + mn + " {").append("\n");
394 Arrays.stream(deps).forEach(req -> {
395 sb.append(" requires ");
396 if (mod != null) {
397 sb.append(mod.toString().toLowerCase()).append(" ");
398 }
399 sb.append(req + ";\n");
400 });
401 sb.append("}\n");
402 builder.writeJavaFiles(mn, sb.toString());
403
404 compileModule(mn, srcDir);
405 }
406
407 private void compileModule(String moduleName, Path src) throws IOException {
408 Path msrc = src.resolve(moduleName);
409 assertTrue(CompilerUtils.compile(msrc, mods, "--module-source-path", src.toString()));
410 }
411
412 private void jmodHashModules(String moduleName, String hashModulesPattern) {
413 makeJmod(moduleName, "--module-path", lib.toString(),
414 "--hash-modules", hashModulesPattern);
415 }
416
417 private void makeJmod(String moduleName, String... options) {
418 Path mclasses = mods.resolve(moduleName);
419 Path outfile = lib.resolve(moduleName + ".jmod");
420 List<String> args = new ArrayList<>();
421 args.add("create");
422 Collections.addAll(args, options);
423 Collections.addAll(args, "--class-path", mclasses.toString(),
424 outfile.toString());
425
426 if (Files.exists(outfile)) {
427 try {
428 Files.delete(outfile);
429 } catch (IOException e) {
|
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 * @bug 8160286
27 * @summary Test the recording and checking of module hashes
28 * @library /test/lib
29 * @modules java.base/jdk.internal.misc
30 * java.base/jdk.internal.module
31 * jdk.compiler
32 * jdk.jartool
33 * jdk.jlink
34 * @run testng HashesTest
35 */
36
37 import java.io.File;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.UncheckedIOException;
41 import java.lang.module.ModuleDescriptor;
42 import java.lang.module.ModuleFinder;
43 import java.lang.module.ModuleReader;
44 import java.lang.module.ModuleReference;
45 import java.nio.file.FileVisitResult;
46 import java.nio.file.Files;
47 import java.nio.file.Path;
48 import java.nio.file.Paths;
49 import java.nio.file.SimpleFileVisitor;
50 import java.nio.file.attribute.BasicFileAttributes;
51 import java.util.ArrayList;
52 import java.util.Arrays;
53 import java.util.Collections;
54 import java.util.List;
55 import java.util.Set;
56 import java.util.spi.ToolProvider;
57 import java.util.stream.Collectors;
58 import java.util.stream.Stream;
59
60 import jdk.internal.module.ModuleInfo;
61 import jdk.internal.module.ModuleHashes;
62 import jdk.internal.module.ModulePath;
63
64 import jdk.test.lib.compiler.ModuleInfoMaker;
65
66 import org.testng.annotations.Test;
67
68 import static org.testng.Assert.*;
69 import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
70
71 public class HashesTest {
72 static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
73 .orElseThrow(() ->
74 new RuntimeException("jmod tool not found")
75 );
76 static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
77 .orElseThrow(() ->
78 new RuntimeException("jar tool not found")
79 );
80
81 private final Path mods;
82 private final Path srcDir;
83 private final Path lib;
84 private final ModuleInfoMaker builder;
85 HashesTest(Path dest) throws IOException {
288 public static void testImageJmods1() throws IOException {
289 Path mpath = Paths.get(System.getProperty("java.home"), "jmods");
290 if (!Files.exists(mpath)) {
291 return;
292 }
293
294 Path dest = Paths.get("test6");
295 HashesTest ht = new HashesTest(dest);
296 ht.makeModule("m1", "jdk.compiler", "jdk.attach");
297 ht.makeModule("m2", "m1");
298 ht.makeModule("m3", "java.compiler");
299
300 ht.makeJar("m2");
301 ht.makeJar("m1",
302 "--module-path",
303 mpath.toString() + File.pathSeparator + ht.lib.toString(),
304 "--hash-modules", ".*");
305 validateImageJmodsTest(ht, mpath);
306 }
307
308 private static void validateImageJmodsTest(HashesTest ht, Path mpath) throws IOException {
309 // hash is recorded in m1 and not any other packaged modules on module path
310 ht.checkHashes("m1", "m2");
311 assertTrue(ht.hashes("m2") == null);
312
313 // should not override any JDK packaged modules
314 ModuleFinder finder = ModulePath.of(Runtime.version(), true, mpath);
315 assertTrue(ht.hashes(finder,"jdk.compiler") == null);
316 assertTrue(ht.hashes(finder,"jdk.attach") == null);
317 }
318
319 private void checkHashes(String mn, String... hashModules) throws IOException {
320 ModuleHashes hashes = hashes(mn);
321 assertTrue(hashes.names().equals(Set.of(hashModules)));
322 }
323
324 private ModuleHashes hashes(String name) {
325 ModuleFinder finder = ModulePath.of(Runtime.version(), true, lib);
326 return hashes(finder, name);
327 }
328
365 Files.delete(file);
366 return FileVisitResult.CONTINUE;
367 }
368
369 @Override
370 public FileVisitResult postVisitDirectory(Path dir, IOException exc)
371 throws IOException
372 {
373 Files.delete(dir);
374 return FileVisitResult.CONTINUE;
375 }
376 });
377 }
378
379
380 private void makeModule(String mn, String... deps) throws IOException {
381 makeModule(mn, null, deps);
382 }
383
384 private void makeModule(String mn, ModuleDescriptor.Requires.Modifier mod, String... deps)
385 throws IOException {
386 if (mod != null && mod != TRANSITIVE && mod != STATIC) {
387 throw new IllegalArgumentException(mod.toString());
388 }
389
390 StringBuilder sb = new StringBuilder();
391 sb.append("module ")
392 .append(mn)
393 .append(" {")
394 .append("\n");
395 Arrays.stream(deps)
396 .forEach(req -> {
397 sb.append(" requires ");
398 if (mod != null) {
399 sb.append(mod.toString().toLowerCase())
400 .append(" ");
401 }
402 sb.append(req)
403 .append(";\n");
404 });
405 sb.append("}\n");
406 builder.writeJavaFiles(mn, sb.toString());
407 builder.compile(mn, mods);
408 }
409
410 private void jmodHashModules(String moduleName, String hashModulesPattern) {
411 makeJmod(moduleName, "--module-path", lib.toString(),
412 "--hash-modules", hashModulesPattern);
413 }
414
415 private void makeJmod(String moduleName, String... options) {
416 Path mclasses = mods.resolve(moduleName);
417 Path outfile = lib.resolve(moduleName + ".jmod");
418 List<String> args = new ArrayList<>();
419 args.add("create");
420 Collections.addAll(args, options);
421 Collections.addAll(args, "--class-path", mclasses.toString(),
422 outfile.toString());
423
424 if (Files.exists(outfile)) {
425 try {
426 Files.delete(outfile);
427 } catch (IOException e) {
|