Path: blob/master/test/jdk/tools/jlink/JLinkNegativeTest.java
66643 views
/*1* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @summary Negative tests for jlink26* @bug 813086127* @bug 817471828* @bug 818967129* @author Andrei Eremeev30* @library ../lib31* @modules java.base/jdk.internal.jimage32* java.base/jdk.internal.module33* jdk.jdeps/com.sun.tools.classfile34* jdk.jlink/jdk.tools.jlink.internal35* jdk.jlink/jdk.tools.jmod36* jdk.jlink/jdk.tools.jimage37* jdk.compiler38* @build tests.*39* @run testng JLinkNegativeTest40*/4142import java.io.File;43import java.io.FileOutputStream;44import java.io.IOException;45import java.io.OutputStream;46import java.lang.module.ModuleDescriptor;47import java.nio.file.FileVisitResult;48import java.nio.file.Files;49import java.nio.file.Path;50import java.nio.file.Paths;51import java.nio.file.SimpleFileVisitor;52import java.nio.file.attribute.BasicFileAttributes;53import java.util.Arrays;54import java.util.Collections;55import java.util.List;56import java.util.Set;57import java.util.jar.JarEntry;58import java.util.jar.JarOutputStream;5960import jdk.internal.module.ModuleInfoWriter;61import org.testng.SkipException;62import org.testng.annotations.BeforeClass;63import org.testng.annotations.Test;64import tests.Helper;65import tests.JImageGenerator;66import tests.JImageGenerator.InMemoryFile;67import tests.Result;6869@Test70public class JLinkNegativeTest {7172private Helper helper;7374@BeforeClass75public void setUp() throws IOException {76helper = Helper.newHelper();77if (helper == null) {78throw new SkipException("Not run");79}80helper.generateDefaultModules();81}8283private void deleteDirectory(Path dir) throws IOException {84Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {85@Override86public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {87Files.delete(file);88return FileVisitResult.CONTINUE;89}9091@Override92public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {93Files.delete(dir);94return FileVisitResult.CONTINUE;95}96});97}9899public void testModuleNotExist() {100helper.generateDefaultImage("failure1").assertFailure("Error: Module failure1 not found");101}102103public void testNotExistInAddMods() {104// cannot find jmod from --add-modules105JImageGenerator.getJLinkTask()106.modulePath(".")107.addMods("not_exist")108.output(helper.getImageDir().resolve("failure2"))109.call().assertFailure("Error: Module not_exist not found");110}111112public void test() throws IOException {113helper.generateDefaultJModule("failure3");114Path image = helper.generateDefaultImage("failure3").assertSuccess();115JImageGenerator.getJLinkTask()116.modulePath(helper.defaultModulePath())117.output(image)118.addMods("leaf1")119.limitMods("leaf1")120.call().assertFailure("Error: directory already exists: .*failure3.image(\n|\r|.)*");121}122123public void testOutputIsFile() throws IOException {124// output == file125Path image = helper.createNewImageDir("failure4");126Files.createFile(image);127JImageGenerator.getJLinkTask()128.modulePath(helper.defaultModulePath())129.output(image)130.addMods("leaf1")131.call().assertFailure("Error: directory already exists: .*failure4.image(\n|\r|.)*");132if (Files.notExists(image)) {133throw new RuntimeException("output directory should not have been deleted");134}135}136137public void testModuleNotFound() {138// limit module is not found139Path imageFile = helper.createNewImageDir("test");140JImageGenerator.getJLinkTask()141.output(imageFile)142.addMods("leaf1")143.limitMods("leaf1")144.limitMods("failure5")145.modulePath(helper.defaultModulePath())146.call().assertFailure("Error: Module failure5 not found");147}148149public void testJmodIsDir() throws IOException {150Path imageFile = helper.createNewImageDir("test");151Path dirJmod = helper.createNewJmodFile("dir");152Files.createDirectory(dirJmod);153try {154JImageGenerator.getJLinkTask()155.output(imageFile)156.addMods("dir")157.modulePath(helper.defaultModulePath())158.call().assertFailure("Error: Module dir not found");159} finally {160deleteDirectory(dirJmod);161}162}163164public void testJarIsDir() throws IOException {165Path imageFile = helper.createNewImageDir("test");166Path dirJar = helper.createNewJarFile("dir");167Files.createDirectory(dirJar);168try {169JImageGenerator.getJLinkTask()170.output(imageFile)171.addMods("dir")172.modulePath(helper.defaultModulePath())173.call().assertFailure("Error: Module dir not found");174} finally {175deleteDirectory(dirJar);176}177}178179public void testMalformedJar() throws IOException {180Path imageFile = helper.createNewImageDir("test");181Path jar = helper.createNewJarFile("not_zip");182Files.createFile(jar);183try {184JImageGenerator.getJLinkTask()185.output(imageFile)186.addMods("not_zip")187.modulePath(helper.defaultModulePath())188.call().assertFailure("Error: Error reading");189} finally {190deleteDirectory(jar);191}192}193194public void testMalformedJmod() throws IOException {195Path imageFile = helper.createNewImageDir("test");196Path jmod = helper.createNewJmodFile("not_zip");197Files.createFile(jmod);198try {199JImageGenerator.getJLinkTask()200.output(imageFile)201.addMods("not_zip")202.modulePath(helper.defaultModulePath())203.call().assertFailure("Error: java.io.IOException: Invalid JMOD file");204} finally {205deleteDirectory(jmod);206}207}208209private static File createJarFile(File dir, String filename, String pkg, String name) throws IOException {210File jarFile = new File(dir, filename + ".jar");211212try (JarOutputStream output = new JarOutputStream(new FileOutputStream(jarFile))) {213JarEntry entry = new JarEntry(filename + "/" + pkg + "/" + name);214output.putNextEntry(entry);215}216217return jarFile;218}219220public void testAutomaticModuleAsRoot() throws IOException {221Path imageFile = helper.createNewImageDir("test");222String jarName = "myautomod";223File jarFile = createJarFile(new File("jars"), jarName, "com/acme", "Bar.class");224try {225JImageGenerator.getJLinkTask()226.output(imageFile)227.addMods(jarName)228.modulePath(helper.defaultModulePath())229.call().assertFailure("Error: automatic module cannot be used with jlink: " + jarName);230} finally {231jarFile.delete();232}233}234235public void testAutomaticModuleAsDependency() throws IOException {236Path imageFile = helper.createNewImageDir("test");237String autoJarName = "myautomod";238File autoJarFile = createJarFile(new File("jars"), autoJarName, "com/acme", "Bar.class");239String rootMod = "autodepender";240helper.generateDefaultJModule(rootMod, autoJarName).assertSuccess();241try {242JImageGenerator.getJLinkTask()243.output(imageFile)244.addMods(rootMod)245.modulePath(helper.defaultModulePath())246.call().assertFailure("Error: automatic module cannot be used with jlink: " + autoJarName);247} finally {248autoJarFile.delete();249}250}251252// Temporarily exclude; the jmod tool can no longer be used to create a jmod253// with a class in the unnamed package. Find another way, or remove.254// public void testAddDefaultPackage() throws IOException {255// String moduleName = "hacked1";256// Path module = helper.generateModuleCompiledClasses(helper.getJmodSrcDir(), helper.getJmodClassesDir(),257// moduleName, Arrays.asList("hacked1.Main", "A", "B"), "leaf1");258// JImageGenerator259// .getJModTask()260// .addClassPath(module)261// .jmod(helper.getJmodDir().resolve(moduleName + ".jmod"))262// .create().assertSuccess();263// Path image = helper.generateDefaultImage(moduleName).assertSuccess();264// helper.checkImage(image, moduleName, null, null);265// }266267public void testAddSomeTopLevelFiles() throws IOException {268String moduleName = "hacked2";269Path module = helper.generateModuleCompiledClasses(helper.getJmodSrcDir(), helper.getJmodClassesDir(),270moduleName);271Files.createFile(module.resolve("top-level-file"));272Path jmod = JImageGenerator273.getJModTask()274.addClassPath(module)275.jmod(helper.getJmodDir().resolve(moduleName + ".jmod"))276.create().assertSuccess();277try {278Path image = helper.generateDefaultImage(moduleName).assertSuccess();279helper.checkImage(image, moduleName, null, null);280} finally {281deleteDirectory(jmod);282}283}284285public void testAddNonStandardSection() throws IOException {286String moduleName = "hacked3";287Path module = helper.generateDefaultJModule(moduleName).assertSuccess();288JImageGenerator.addFiles(module, new InMemoryFile("unknown/A.class", new byte[0]));289try {290Result result = helper.generateDefaultImage(moduleName);291System.err.println(result.getMessage());292if (result.getExitCode() == 0) {293throw new AssertionError("Crash expected");294}295} finally {296deleteDirectory(module);297}298}299300@Test(enabled = true)301public void testSectionsAreFiles() throws IOException {302String moduleName = "hacked4";303Path jmod = helper.generateDefaultJModule(moduleName).assertSuccess();304JImageGenerator.addFiles(jmod,305new InMemoryFile("/lib", new byte[0]),306new InMemoryFile("/conf", new byte[0]),307new InMemoryFile("/bin", new byte[0]));308try {309Result result = helper.generateDefaultImage(moduleName);310System.err.println(result.getMessage());311if (result.getExitCode() == 0) {312throw new AssertionError("Crash expected");313}314} finally {315deleteDirectory(jmod);316}317}318319public void testDuplicateModule1() throws IOException {320String moduleName1 = "dupRes1Jmod1";321String moduleName2 = "dupRes1Jmod2";322List<String> classNames = Arrays.asList("java.A", "javax.B");323Path module1 = helper.generateModuleCompiledClasses(324helper.getJmodSrcDir(), helper.getJmodClassesDir(), moduleName1, classNames);325Path module2 = helper.generateModuleCompiledClasses(326helper.getJmodSrcDir(), helper.getJmodClassesDir(), moduleName2, classNames);327328try (OutputStream out = Files.newOutputStream(module2.resolve("module-info.class"))) {329ModuleInfoWriter.write(ModuleDescriptor.newModule(moduleName1)330.requires("java.base").build(), out);331}332333Path jmod1 = JImageGenerator.getJModTask()334.addClassPath(module1)335.jmod(helper.createNewJmodFile(moduleName1))336.create()337.assertSuccess();338Path jmod2 = JImageGenerator.getJModTask()339.addClassPath(module2)340.jmod(helper.createNewJmodFile(moduleName2))341.create()342.assertSuccess();343try {344helper.generateDefaultImage(moduleName1)345.assertFailure("Error: Two versions of module dupRes1Jmod1 found in");346} finally {347deleteDirectory(jmod1);348deleteDirectory(jmod2);349}350}351352public void testDuplicateModule2() throws IOException {353String moduleName = "dupRes2Jmod";354List<String> classNames = Arrays.asList("java.A", "javax.B");355Path module1 = helper.generateModuleCompiledClasses(356helper.getJmodSrcDir(), helper.getJmodClassesDir(), moduleName, classNames);357Path module2 = helper.generateModuleCompiledClasses(358helper.getJarSrcDir(), helper.getJarClassesDir(), moduleName, classNames);359360Path jmod = JImageGenerator.getJModTask()361.addClassPath(module1)362.jmod(helper.createNewJmodFile(moduleName))363.create()364.assertSuccess();365Path jar = JImageGenerator.createJarFile(helper.getJarDir().resolve(moduleName + ".jar"), module2);366Path newJar = helper.getJmodDir().resolve(jar.getFileName());367Files.move(jar, newJar);368try {369helper.generateDefaultImage(moduleName)370.assertFailure("Error: Two versions of module dupRes2Jmod found in");371} finally {372deleteDirectory(jmod);373deleteDirectory(newJar);374}375}376377public void testDuplicateModule3() throws IOException {378String moduleName1 = "dupRes3Jar1";379String moduleName2 = "dupRes3Jar2";380List<String> classNames = Arrays.asList("java.A", "javax.B");381Path module1 = helper.generateModuleCompiledClasses(382helper.getJarSrcDir(), helper.getJarClassesDir(), moduleName1, classNames);383Path module2 = helper.generateModuleCompiledClasses(384helper.getJarSrcDir(), helper.getJarClassesDir(), moduleName2, classNames);385386try (OutputStream out = Files.newOutputStream(module2.resolve("module-info.class"))) {387ModuleInfoWriter.write(ModuleDescriptor.newModule(moduleName1)388.requires("java.base").build(), out);389}390391Path jar1 = JImageGenerator.createJarFile(helper.getJarDir().resolve(moduleName1 + ".jar"), module1);392Path jar2 = JImageGenerator.createJarFile(helper.getJarDir().resolve(moduleName2 + ".jar"), module2);393try {394helper.generateDefaultImage(moduleName1)395.assertFailure("Error: Two versions of module dupRes3Jar1 found in");396} finally {397deleteDirectory(jar1);398deleteDirectory(jar2);399}400}401402public void testInconsistentModuleInfo() throws IOException {403String moduleName = "inconsistentJar";404List<String> classNames = Arrays.asList("xorg.acme.internal.B");405Path module = helper.generateModuleCompiledClasses(406helper.getJarSrcDir(), helper.getJarClassesDir(), moduleName, classNames);407408try (OutputStream out = Files.newOutputStream(module.resolve("module-info.class"))) {409ModuleInfoWriter.write(ModuleDescriptor.newModule(moduleName)410.requires("java.base")411.packages(Set.of("org.acme.internal"))412.build(), out);413}414415Path jar = JImageGenerator.createJarFile(helper.getJarDir().resolve(moduleName + ".jar"), module);416try {417helper.generateDefaultImage(moduleName)418.assertFailure("Module inconsistentJar's descriptor indicates the set of packages is : " +419"[org.acme.internal], but module contains packages: [xorg.acme.internal]");420} finally {421deleteDirectory(jar);422}423}424}425426427