/** * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test * @summary Test --no-man-pages and --no-header-files * @library /lib/testlibrary * @modules jdk.compiler * jdk.jlink * @build CompilerUtils * @run testng ExcludeJmodSectionPluginTest */ import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.spi.ToolProvider; import java.util.stream.Collectors; import java.util.stream.Stream; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import static org.testng.Assert.*; public class ExcludeJmodSectionPluginTest { static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod") .orElseThrow(() -> new RuntimeException("jmod tool not found") ); static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink") .orElseThrow(() -> new RuntimeException("jlink tool not found") ); static final Path MODULE_PATH = Paths.get(System.getProperty("java.home"), "jmods"); static final Path SRC_DIR = Paths.get("src"); static final Path MODS_DIR = Paths.get("mods"); static final Path JMODS_DIR = Paths.get("jmods"); static final Path MAN_DIR = Paths.get("man"); static final Path INCLUDE_DIR = Paths.get("include"); static final Path IMAGES_DIR = Paths.get("images"); @BeforeTest private void setup() throws Exception { // build jmod files JmodFileBuilder m1 = new JmodFileBuilder("m1"); m1.headerFile("m1a.h"); m1.headerFile("m1b.h"); m1.build(); JmodFileBuilder m2 = new JmodFileBuilder("m2"); m2.headerFile("m2.h"); m2.manPage("tool2.1"); m2.build(); JmodFileBuilder m3 = new JmodFileBuilder("m3"); m3.manPage("tool3.1"); m3.build(); } private String imageDir(String dir) { return IMAGES_DIR.resolve(dir).toString(); } @DataProvider(name = "jlinkoptions") public Object[][] jlinkoptions() { // options and expected header files & man pages return new Object[][] { { new String [] { "test1", "--exclude-files=/java.base/include/**,/java.base/man/**", }, List.of("include/m1a.h", "include/m1b.h", "include/m2.h", "man/tool2.1", "man/tool3.1") }, { new String [] { "test2", "--no-man-pages", "--no-header-files", }, List.of() }, { new String[] { "test3", "--no-header-files", "--exclude-files=/java.base/man/**" }, List.of("man/tool2.1", "man/tool3.1") }, { new String [] { "test4", "--no-man-pages", "--exclude-files=/java.base/include/**,/m2/include/**", }, List.of("include/m1a.h", "include/m1b.h") }, { new String [] { "test5", "--no-header-files", "--exclude-files=/java.base/man/**,/m2/man/**" }, List.of("man/tool3.1") }, }; } @Test(dataProvider = "jlinkoptions") public void test(String[] opts, List<String> expectedFiles) throws Exception { if (Files.notExists(MODULE_PATH)) { // exploded image return; } String dir = opts[0]; List<String> options = new ArrayList<>(); for (int i = 1; i < opts.length; i++) { options.add(opts[i]); } String mpath = MODULE_PATH.toString() + File.pathSeparator + JMODS_DIR.toString(); Stream.of("--module-path", mpath, "--add-modules", "m1,m2,m3", "--output", imageDir(dir)) .forEach(options::add); Path image = createImage(dir, options, expectedFiles); // check if any unexpected header file or man page Set<Path> extraFiles = Files.walk(image, Integer.MAX_VALUE) .filter(p -> Files.isRegularFile(p)) .filter(p -> p.getParent().endsWith("include") || p.getParent().endsWith("man")) .filter(p -> { String fn = String.format("%s/%s", p.getParent().getFileName().toString(), p.getFileName().toString()); return !expectedFiles.contains(fn); }) .collect(Collectors.toSet()); if (extraFiles.size() > 0) { System.out.println("Unexpected files: " + extraFiles.toString()); assertTrue(extraFiles.isEmpty()); } } /** * Test java.base's include header files */ @Test public void testJavaBase() { if (Files.notExists(MODULE_PATH)) { // exploded image return; } List<String> options = List.of("--module-path", MODULE_PATH.toString(), "--add-modules", "java.base", "--output", imageDir("base")); createImage("base", options, List.of("include/jni.h", "include/jvmti.h")); } private Path createImage(String outputDir, List<String> options, List<String> expectedFiles) { System.out.println("jlink " + options.toString()); int rc = JLINK_TOOL.run(System.out, System.out, options.toArray(new String[0])); assertTrue(rc == 0); Path d = IMAGES_DIR.resolve(outputDir); for (String fn : expectedFiles) { Path path = d.resolve(fn); if (Files.notExists(path)) { throw new RuntimeException(path + " not found"); } } return d; } private void deleteDirectory(Path dir) throws IOException { Files.walkFileTree(dir, new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { Files.delete(dir); return FileVisitResult.CONTINUE; } }); } /** * Builder to create JMOD file */ class JmodFileBuilder { final String name; final Set<String> manPages = new HashSet<>(); final Set<String> headerFiles = new HashSet<>(); JmodFileBuilder(String name) throws IOException { this.name = name; Path msrc = SRC_DIR.resolve(name); if (Files.exists(msrc)) { deleteDirectory(msrc); } } JmodFileBuilder manPage(String filename) { manPages.add(filename); return this; } JmodFileBuilder headerFile(String filename) { headerFiles.add(filename); return this; } Path build() throws IOException { compileModule(); // create man pages Path mdir = MAN_DIR.resolve(name); for (String filename : manPages) { Files.createDirectories(mdir); Files.createFile(mdir.resolve(filename)); } // create header files mdir = INCLUDE_DIR.resolve(name); for (String filename : headerFiles) { Files.createDirectories(mdir); Files.createFile(mdir.resolve(filename)); } return createJmodFile(); } void compileModule() throws IOException { Path msrc = SRC_DIR.resolve(name); Files.createDirectories(msrc); Path minfo = msrc.resolve("module-info.java"); try (BufferedWriter bw = Files.newBufferedWriter(minfo); PrintWriter writer = new PrintWriter(bw)) { writer.format("module %s { }%n", name); } assertTrue(CompilerUtils.compile(msrc, MODS_DIR, "--module-source-path", SRC_DIR.toString())); } Path createJmodFile() throws IOException { Path mclasses = MODS_DIR.resolve(name); Files.createDirectories(JMODS_DIR); Path outfile = JMODS_DIR.resolve(name + ".jmod"); List<String> args = new ArrayList<>(); args.add("create"); // add classes args.add("--class-path"); args.add(mclasses.toString()); // man pages if (manPages.size() > 0) { args.add("--man-pages"); args.add(MAN_DIR.resolve(name).toString()); } // header files if (headerFiles.size() > 0) { args.add("--header-files"); args.add(INCLUDE_DIR.resolve(name).toString()); } args.add(outfile.toString()); if (Files.exists(outfile)) Files.delete(outfile); System.out.println("jmod " + args.stream().collect(Collectors.joining(" "))); int rc = JMOD_TOOL.run(System.out, System.out, args.toArray(new String[args.size()])); if (rc != 0) { throw new AssertionError("jmod failed: rc = " + rc); } return outfile; } } }