1 /* 2 * Copyright (c) 2019, 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 /* 26 * @test 27 * @summary Test relative paths specified in the -cp. 28 * @requires vm.cds 29 * @library /test/lib 30 * @modules java.base/jdk.internal.misc 31 * java.management 32 * jdk.jartool/sun.tools.jar 33 * @compile test-classes/Hello.java 34 * @compile test-classes/HelloMore.java 35 * @run driver RelativePath 36 */ 37 38 import java.io.File; 39 import java.nio.file.Files; 40 import java.nio.file.Path; 41 import java.nio.file.Paths; 42 import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES; 43 import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; 44 import java.util.Arrays; 45 import jdk.test.lib.Platform; 46 47 public class RelativePath { 48 49 private static final Path USER_DIR = Paths.get(System.getProperty("user.dir")); 50 51 public static void main(String[] args) throws Exception { 52 String appJar = JarBuilder.getOrCreateHelloJar(); 53 String appJar2 = JarBuilder.build("AppendClasspath_HelloMore", "HelloMore"); 54 55 // dump an archive with only the jar name in the -cp 56 int idx = appJar.lastIndexOf(File.separator); 57 String jarName = appJar.substring(idx + 1); 58 String jarDir = appJar.substring(0, idx); 59 TestCommon.testDump(jarDir, jarName, TestCommon.list("Hello")); 60 61 // copy the jar file to another dir. Specify the jar file without 62 // a directory path. 63 Path srcPath = Paths.get(appJar); 64 Path destDir = Files.createTempDirectory(USER_DIR, "deploy"); 65 Path destPath = destDir.resolve(jarName); 66 Files.copy(srcPath, destPath, REPLACE_EXISTING, COPY_ATTRIBUTES); 67 TestCommon.runWithRelativePath( 68 destDir.toString(), 69 "-Xshare:on", 70 "-XX:SharedArchiveFile=" + TestCommon.getCurrentArchiveName(), 71 "-cp", jarName + File.pathSeparator + appJar2, 72 "-Xlog:class+load=trace,class+path=info", 73 "HelloMore") 74 .assertNormalExit(output -> { 75 output.shouldContain("Hello source: shared objects file") 76 .shouldHaveExitValue(0); 77 }); 78 79 // Long path test 80 // Create a long directory path and copy the appJar there. 81 final int MAX_PATH = 260; 82 destDir = Paths.get(jarDir); 83 int subDirLen = MAX_PATH - jarDir.length() - 3; 84 if (subDirLen > 0) { 85 char[] chars = new char[subDirLen]; 86 Arrays.fill(chars, 'x'); 87 String subPath = new String(chars); 88 destDir = Paths.get(jarDir, subPath); 89 } 90 File longDir = destDir.toFile(); 91 longDir.mkdir(); 92 String destJar = longDir.getPath() + File.separator + jarName; 93 Files.copy(Paths.get(appJar), Paths.get(destJar), REPLACE_EXISTING); 94 // Create an archive with the appJar in the long directory path. 95 TestCommon.testDump(destJar, TestCommon.list("Hello")); 96 97 // Run with -cp containing the appJar and another jar appended. 98 TestCommon.run( 99 "-cp", destJar + File.pathSeparator + appJar2, 100 "-Xlog:class+load=trace,class+path=info", 101 "HelloMore") 102 .assertNormalExit(output -> { 103 output.shouldContain("Hello source: shared objects file") 104 .shouldHaveExitValue(0); 105 }); 106 107 // Dump an archive with a specified JAR file in -classpath 108 TestCommon.testDump(appJar, TestCommon.list("Hello")); 109 110 // compose a relative path to the hello.jar 111 String newHello = TestCommon.composeRelPath(appJar); 112 113 // create a sym link to the original hello.jar 114 File linkedHello = null; 115 if (!Platform.isWindows()) { 116 linkedHello = TestCommon.createSymLink(appJar); 117 } 118 119 // PASS:1) same appJar but referred to via a relative path 120 TestCommon.run( 121 "-cp", newHello + File.pathSeparator + appJar2, 122 "-Xlog:class+load=trace,class+path=info", 123 "HelloMore") 124 .assertNormalExit(); 125 126 // PASS:2) relative path starting with "." 127 TestCommon.runWithRelativePath( 128 jarDir, 129 "-Xshare:on", 130 "-XX:SharedArchiveFile=" + TestCommon.getCurrentArchiveName(), 131 "-cp", "." + File.separator + jarName + File.pathSeparator + appJar2, 132 "-Xlog:class+load=trace,class+path=info", 133 "HelloMore") 134 .assertNormalExit(output -> { 135 output.shouldContain("Hello source: shared objects file") 136 .shouldHaveExitValue(0); 137 }); 138 139 // PASS:3) relative path starting with ".." 140 idx = jarDir.lastIndexOf(File.separator); 141 String jarSubDir = jarDir.substring(idx + 1); 142 TestCommon.runWithRelativePath( 143 jarDir, 144 "-Xshare:on", 145 "-XX:SharedArchiveFile=" + TestCommon.getCurrentArchiveName(), 146 "-cp", ".." + File.separator + jarSubDir + File.separator + jarName 147 + File.pathSeparator + appJar2, 148 "-Xlog:class+load=trace,class+path=info", 149 "HelloMore") 150 .assertNormalExit(output -> { 151 output.shouldContain("Hello source: shared objects file") 152 .shouldHaveExitValue(0); 153 }); 154 155 // PASS:4) a jar linked to the original hello.jar 156 if (!Platform.isWindows()) { 157 TestCommon.run( 158 "-cp", linkedHello.getPath() + File.pathSeparator + appJar2, 159 "HelloMore") 160 .assertNormalExit(); 161 } 162 163 final String errorMessage1 = "Unable to use shared archive"; 164 final String errorMessage2 = "shared class paths mismatch"; 165 // FAIL: 1) runtime with classpath different from the one used in dump time 166 // (runtime has an extra jar file prepended to the class path) 167 TestCommon.run( 168 "-cp", appJar2 + File.pathSeparator + newHello, 169 "HelloMore") 170 .assertAbnormalExit(errorMessage1, errorMessage2); 171 172 } 173 }