test/jdk/tools/jlink/JLinkNegativeTest.java
changeset 47216 71c04702a3d5
parent 45004 ea3137042a61
child 47399 fb677b3f0888
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /**
       
     2  * Copyright (c) 2015, 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  * @summary Negative tests for jlink
       
    27  * @bug 8130861
       
    28  * @bug 8174718
       
    29  * @author Andrei Eremeev
       
    30  * @library ../lib
       
    31  * @modules java.base/jdk.internal.jimage
       
    32  *          java.base/jdk.internal.module
       
    33  *          jdk.jdeps/com.sun.tools.classfile
       
    34  *          jdk.jlink/jdk.tools.jlink.internal
       
    35  *          jdk.jlink/jdk.tools.jmod
       
    36  *          jdk.jlink/jdk.tools.jimage
       
    37  *          jdk.compiler
       
    38  * @build tests.*
       
    39  * @run testng JLinkNegativeTest
       
    40  */
       
    41 
       
    42 import java.io.IOException;
       
    43 import java.io.OutputStream;
       
    44 import java.lang.module.ModuleDescriptor;
       
    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.Arrays;
       
    52 import java.util.Collections;
       
    53 import java.util.List;
       
    54 import java.util.Set;
       
    55 
       
    56 import jdk.internal.module.ModuleInfoWriter;
       
    57 import org.testng.SkipException;
       
    58 import org.testng.annotations.BeforeClass;
       
    59 import org.testng.annotations.Test;
       
    60 import tests.Helper;
       
    61 import tests.JImageGenerator;
       
    62 import tests.JImageGenerator.InMemoryFile;
       
    63 import tests.Result;
       
    64 
       
    65 @Test
       
    66 public class JLinkNegativeTest {
       
    67 
       
    68     private Helper helper;
       
    69 
       
    70     @BeforeClass
       
    71     public void setUp() throws IOException {
       
    72         helper = Helper.newHelper();
       
    73         if (helper == null) {
       
    74             throw new SkipException("Not run");
       
    75         }
       
    76         helper.generateDefaultModules();
       
    77     }
       
    78 
       
    79     private void deleteDirectory(Path dir) throws IOException {
       
    80         Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
       
    81             @Override
       
    82             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
       
    83                 Files.delete(file);
       
    84                 return FileVisitResult.CONTINUE;
       
    85             }
       
    86 
       
    87             @Override
       
    88             public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
       
    89                 Files.delete(dir);
       
    90                 return FileVisitResult.CONTINUE;
       
    91             }
       
    92         });
       
    93     }
       
    94 
       
    95     public void testModuleNotExist() {
       
    96         helper.generateDefaultImage("failure1").assertFailure("Error: Module failure1 not found");
       
    97     }
       
    98 
       
    99     public void testNotExistInAddMods() {
       
   100         // cannot find jmod from --add-modules
       
   101         JImageGenerator.getJLinkTask()
       
   102                 .modulePath(".")
       
   103                 .addMods("not_exist")
       
   104                 .output(helper.getImageDir().resolve("failure2"))
       
   105                 .call().assertFailure("Error: Module not_exist not found");
       
   106     }
       
   107 
       
   108     public void test() throws IOException {
       
   109         helper.generateDefaultJModule("failure3");
       
   110         Path image = helper.generateDefaultImage("failure3").assertSuccess();
       
   111         JImageGenerator.getJLinkTask()
       
   112                 .modulePath(helper.defaultModulePath())
       
   113                 .output(image)
       
   114                 .addMods("leaf1")
       
   115                 .limitMods("leaf1")
       
   116                 .call().assertFailure("Error: directory already exists: .*failure3.image(\n|\r|.)*");
       
   117     }
       
   118 
       
   119     public void testOutputIsFile() throws IOException {
       
   120         // output == file
       
   121         Path image = helper.createNewImageDir("failure4");
       
   122         Files.createFile(image);
       
   123         JImageGenerator.getJLinkTask()
       
   124                 .modulePath(helper.defaultModulePath())
       
   125                 .output(image)
       
   126                 .addMods("leaf1")
       
   127                 .call().assertFailure("Error: directory already exists: .*failure4.image(\n|\r|.)*");
       
   128     }
       
   129 
       
   130     public void testModuleNotFound() {
       
   131         // limit module is not found
       
   132         Path imageFile = helper.createNewImageDir("test");
       
   133         JImageGenerator.getJLinkTask()
       
   134                 .output(imageFile)
       
   135                 .addMods("leaf1")
       
   136                 .limitMods("leaf1")
       
   137                 .limitMods("failure5")
       
   138                 .modulePath(helper.defaultModulePath())
       
   139                 .call().assertFailure("Error: Module failure5 not found");
       
   140     }
       
   141 
       
   142     public void testJmodIsDir() throws IOException {
       
   143         Path imageFile = helper.createNewImageDir("test");
       
   144         Path dirJmod = helper.createNewJmodFile("dir");
       
   145         Files.createDirectory(dirJmod);
       
   146         try {
       
   147             JImageGenerator.getJLinkTask()
       
   148                     .output(imageFile)
       
   149                     .addMods("dir")
       
   150                     .modulePath(helper.defaultModulePath())
       
   151                     .call().assertFailure("Error: Module dir not found");
       
   152         } finally {
       
   153             deleteDirectory(dirJmod);
       
   154         }
       
   155     }
       
   156 
       
   157     public void testJarIsDir() throws IOException {
       
   158         Path imageFile = helper.createNewImageDir("test");
       
   159         Path dirJar = helper.createNewJarFile("dir");
       
   160         Files.createDirectory(dirJar);
       
   161         try {
       
   162             JImageGenerator.getJLinkTask()
       
   163                     .output(imageFile)
       
   164                     .addMods("dir")
       
   165                     .modulePath(helper.defaultModulePath())
       
   166                     .call().assertFailure("Error: Module dir not found");
       
   167         } finally {
       
   168             deleteDirectory(dirJar);
       
   169         }
       
   170     }
       
   171 
       
   172     public void testMalformedJar() throws IOException {
       
   173         Path imageFile = helper.createNewImageDir("test");
       
   174         Path jar = helper.createNewJarFile("not_zip");
       
   175         Files.createFile(jar);
       
   176         try {
       
   177             JImageGenerator.getJLinkTask()
       
   178                     .output(imageFile)
       
   179                     .addMods("not_zip")
       
   180                     .modulePath(helper.defaultModulePath())
       
   181                     .call().assertFailure("Error: Error reading");
       
   182         } finally {
       
   183             deleteDirectory(jar);
       
   184         }
       
   185     }
       
   186 
       
   187     public void testMalformedJmod() throws IOException {
       
   188         Path imageFile = helper.createNewImageDir("test");
       
   189         Path jmod = helper.createNewJmodFile("not_zip");
       
   190         Files.createFile(jmod);
       
   191         try {
       
   192             JImageGenerator.getJLinkTask()
       
   193                     .output(imageFile)
       
   194                     .addMods("not_zip")
       
   195                     .modulePath(helper.defaultModulePath())
       
   196                     .call().assertFailure("Error: java.io.IOException: Invalid JMOD file");
       
   197         } finally {
       
   198             deleteDirectory(jmod);
       
   199         }
       
   200     }
       
   201 
       
   202     // Temporarily exclude; the jmod tool can no longer be used to create a jmod
       
   203     // with a class in the unnamed package. Find another way, or remove.
       
   204 //    public void testAddDefaultPackage() throws IOException {
       
   205 //        String moduleName = "hacked1";
       
   206 //        Path module = helper.generateModuleCompiledClasses(helper.getJmodSrcDir(), helper.getJmodClassesDir(),
       
   207 //                moduleName, Arrays.asList("hacked1.Main", "A", "B"), "leaf1");
       
   208 //        JImageGenerator
       
   209 //                .getJModTask()
       
   210 //                .addClassPath(module)
       
   211 //                .jmod(helper.getJmodDir().resolve(moduleName + ".jmod"))
       
   212 //                .create().assertSuccess();
       
   213 //        Path image = helper.generateDefaultImage(moduleName).assertSuccess();
       
   214 //        helper.checkImage(image, moduleName, null, null);
       
   215 //    }
       
   216 
       
   217     public void testAddSomeTopLevelFiles() throws IOException {
       
   218         String moduleName = "hacked2";
       
   219         Path module = helper.generateModuleCompiledClasses(helper.getJmodSrcDir(), helper.getJmodClassesDir(),
       
   220                 moduleName);
       
   221         Files.createFile(module.resolve("top-level-file"));
       
   222         Path jmod = JImageGenerator
       
   223                 .getJModTask()
       
   224                 .addClassPath(module)
       
   225                 .jmod(helper.getJmodDir().resolve(moduleName + ".jmod"))
       
   226                 .create().assertSuccess();
       
   227         try {
       
   228             Path image = helper.generateDefaultImage(moduleName).assertSuccess();
       
   229             helper.checkImage(image, moduleName, null, null);
       
   230         } finally {
       
   231             deleteDirectory(jmod);
       
   232         }
       
   233     }
       
   234 
       
   235     public void testAddNonStandardSection() throws IOException {
       
   236         String moduleName = "hacked3";
       
   237         Path module = helper.generateDefaultJModule(moduleName).assertSuccess();
       
   238         JImageGenerator.addFiles(module, new InMemoryFile("unknown/A.class", new byte[0]));
       
   239         try {
       
   240             Result result = helper.generateDefaultImage(moduleName);
       
   241             System.err.println(result.getMessage());
       
   242             if (result.getExitCode() == 0) {
       
   243                 throw new AssertionError("Crash expected");
       
   244             }
       
   245         } finally {
       
   246             deleteDirectory(module);
       
   247         }
       
   248     }
       
   249 
       
   250     @Test(enabled = true)
       
   251     public void testSectionsAreFiles() throws IOException {
       
   252         String moduleName = "hacked4";
       
   253         Path jmod = helper.generateDefaultJModule(moduleName).assertSuccess();
       
   254         JImageGenerator.addFiles(jmod,
       
   255                 new InMemoryFile("/lib", new byte[0]),
       
   256                 new InMemoryFile("/conf", new byte[0]),
       
   257                 new InMemoryFile("/bin", new byte[0]));
       
   258         try {
       
   259             Result result = helper.generateDefaultImage(moduleName);
       
   260             System.err.println(result.getMessage());
       
   261             if (result.getExitCode() == 0) {
       
   262                 throw new AssertionError("Crash expected");
       
   263             }
       
   264         } finally {
       
   265             deleteDirectory(jmod);
       
   266         }
       
   267     }
       
   268 
       
   269     public void testDuplicateModule1() throws IOException {
       
   270         String moduleName1 = "dupRes1Jmod1";
       
   271         String moduleName2 = "dupRes1Jmod2";
       
   272         List<String> classNames = Arrays.asList("java.A", "javax.B");
       
   273         Path module1 = helper.generateModuleCompiledClasses(
       
   274                 helper.getJmodSrcDir(), helper.getJmodClassesDir(), moduleName1, classNames);
       
   275         Path module2 = helper.generateModuleCompiledClasses(
       
   276                 helper.getJmodSrcDir(), helper.getJmodClassesDir(), moduleName2, classNames);
       
   277 
       
   278         try (OutputStream out = Files.newOutputStream(module2.resolve("module-info.class"))) {
       
   279             ModuleInfoWriter.write(ModuleDescriptor.newModule(moduleName1)
       
   280                     .requires("java.base").build(), out);
       
   281         }
       
   282 
       
   283         Path jmod1 = JImageGenerator.getJModTask()
       
   284                 .addClassPath(module1)
       
   285                 .jmod(helper.createNewJmodFile(moduleName1))
       
   286                 .create()
       
   287                 .assertSuccess();
       
   288         Path jmod2 = JImageGenerator.getJModTask()
       
   289                 .addClassPath(module2)
       
   290                 .jmod(helper.createNewJmodFile(moduleName2))
       
   291                 .create()
       
   292                 .assertSuccess();
       
   293         try {
       
   294             helper.generateDefaultImage(moduleName1)
       
   295                     .assertFailure("Error: Two versions of module dupRes1Jmod1 found in");
       
   296         } finally {
       
   297             deleteDirectory(jmod1);
       
   298             deleteDirectory(jmod2);
       
   299         }
       
   300     }
       
   301 
       
   302     public void testDuplicateModule2() throws IOException {
       
   303         String moduleName = "dupRes2Jmod";
       
   304         List<String> classNames = Arrays.asList("java.A", "javax.B");
       
   305         Path module1 = helper.generateModuleCompiledClasses(
       
   306                 helper.getJmodSrcDir(), helper.getJmodClassesDir(), moduleName, classNames);
       
   307         Path module2 = helper.generateModuleCompiledClasses(
       
   308                 helper.getJarSrcDir(), helper.getJarClassesDir(), moduleName, classNames);
       
   309 
       
   310         Path jmod = JImageGenerator.getJModTask()
       
   311                 .addClassPath(module1)
       
   312                 .jmod(helper.createNewJmodFile(moduleName))
       
   313                 .create()
       
   314                 .assertSuccess();
       
   315         Path jar = JImageGenerator.createJarFile(helper.getJarDir().resolve(moduleName + ".jar"), module2);
       
   316         Path newJar = helper.getJmodDir().resolve(jar.getFileName());
       
   317         Files.move(jar, newJar);
       
   318         try {
       
   319             helper.generateDefaultImage(moduleName)
       
   320                     .assertFailure("Error: Two versions of module dupRes2Jmod found in");
       
   321         } finally {
       
   322             deleteDirectory(jmod);
       
   323             deleteDirectory(newJar);
       
   324         }
       
   325     }
       
   326 
       
   327     public void testDuplicateModule3() throws IOException {
       
   328         String moduleName1 = "dupRes3Jar1";
       
   329         String moduleName2 = "dupRes3Jar2";
       
   330         List<String> classNames = Arrays.asList("java.A", "javax.B");
       
   331         Path module1 = helper.generateModuleCompiledClasses(
       
   332                 helper.getJarSrcDir(), helper.getJarClassesDir(), moduleName1, classNames);
       
   333         Path module2 = helper.generateModuleCompiledClasses(
       
   334                 helper.getJarSrcDir(), helper.getJarClassesDir(), moduleName2, classNames);
       
   335 
       
   336         try (OutputStream out = Files.newOutputStream(module2.resolve("module-info.class"))) {
       
   337             ModuleInfoWriter.write(ModuleDescriptor.newModule(moduleName1)
       
   338                     .requires("java.base").build(), out);
       
   339         }
       
   340 
       
   341         Path jar1 = JImageGenerator.createJarFile(helper.getJarDir().resolve(moduleName1 + ".jar"), module1);
       
   342         Path jar2 = JImageGenerator.createJarFile(helper.getJarDir().resolve(moduleName2 + ".jar"), module2);
       
   343         try {
       
   344             helper.generateDefaultImage(moduleName1)
       
   345                     .assertFailure("Error: Two versions of module dupRes3Jar1 found in");
       
   346         } finally {
       
   347             deleteDirectory(jar1);
       
   348             deleteDirectory(jar2);
       
   349         }
       
   350     }
       
   351 
       
   352     public void testInconsistentModuleInfo() throws IOException {
       
   353         String moduleName = "inconsistentJar";
       
   354         List<String> classNames = Arrays.asList("xorg.acme.internal.B");
       
   355         Path module = helper.generateModuleCompiledClasses(
       
   356                 helper.getJarSrcDir(), helper.getJarClassesDir(), moduleName, classNames);
       
   357 
       
   358         try (OutputStream out = Files.newOutputStream(module.resolve("module-info.class"))) {
       
   359             ModuleInfoWriter.write(ModuleDescriptor.newModule(moduleName)
       
   360                     .requires("java.base")
       
   361                     .packages(Set.of("org.acme.internal"))
       
   362                     .build(), out);
       
   363         }
       
   364 
       
   365         Path jar = JImageGenerator.createJarFile(helper.getJarDir().resolve(moduleName + ".jar"), module);
       
   366         try {
       
   367             helper.generateDefaultImage(moduleName)
       
   368                   .assertFailure("Module inconsistentJar's descriptor indicates the set of packages is : " +
       
   369                   "[org.acme.internal], but module contains packages: [xorg.acme.internal]");
       
   370         } finally {
       
   371             deleteDirectory(jar);
       
   372         }
       
   373     }
       
   374 }