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 Some negative tests for the SharedArchiveFile option
28  * @requires vm.cds
29  * @library /test/lib /test/hotspot/jtreg/runtime/appcds /test/hotspot/jtreg/runtime/appcds/test-classes
30  * @build Hello
31  * @run driver ClassFileInstaller -jar hello.jar Hello
32  * @run driver SharedArchiveFileOption
33  */
34 
35 import java.io.File;
36 
37 public class SharedArchiveFileOption extends DynamicArchiveTestBase {
main(String[] args)38     public static void main(String[] args) throws Exception {
39         runTest(SharedArchiveFileOption::testCustomBase);
40     }
41 
42     static String baseArchiveName2;
testCustomBase()43     static void testCustomBase() throws Exception {
44         String topArchiveName = getNewArchiveName("top");
45         String baseArchiveName = getNewArchiveName("base");
46         baseArchiveName2 = getNewArchiveName("base2");
47         dumpBaseArchive(baseArchiveName);
48         dumpBaseArchive(baseArchiveName2);
49         doTest(baseArchiveName, topArchiveName);
50     }
51 
doTest(String baseArchiveName, String topArchiveName)52     private static void doTest(String baseArchiveName, String topArchiveName) throws Exception {
53         String appJar = ClassFileInstaller.getJarPath("hello.jar");
54         String mainClass = "Hello";
55         String dummyArchiveName = getNewArchiveName("dummy");
56 
57         // -Xshare:dump specified with -XX:ArchiveClassesAtExit
58         dump2(dummyArchiveName, dummyArchiveName,
59             "-Xlog:cds",
60             "-Xlog:cds+dynamic=debug",
61             "-Xshare:dump",
62             "-cp", appJar, mainClass)
63             .assertAbnormalExit(output -> {
64                     output.shouldContain("-XX:ArchiveClassesAtExit cannot be used with -Xshare:dump");
65                 });
66 
67         // more than 1 archive file specified in -XX:SharedArchiveFile during
68         // dynamic dumpgin
69         String dummyArchives = dummyArchiveName + File.pathSeparator + dummyArchiveName;
70         dump2(dummyArchives, dummyArchiveName,
71             "-Xlog:cds",
72             "-Xlog:cds+dynamic=debug",
73             "-cp", appJar, mainClass)
74             .assertAbnormalExit(output -> {
75                     output.shouldContain("Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping");
76                 });
77 
78         // normal dynamic archive dumping
79         dump2(baseArchiveName, topArchiveName,
80             "-Xlog:cds",
81             "-Xlog:cds+dynamic=debug",
82             "-cp", appJar, mainClass)
83             .assertNormalExit(output -> {
84                     output.shouldContain("Buffer-space to target-space delta")
85                            .shouldContain("Written dynamic archive 0x");
86                 });
87 
88         // same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit
89         dump2(baseArchiveName, baseArchiveName,
90             "-Xlog:cds",
91             "-Xlog:cds+dynamic=debug",
92             "-cp", appJar, mainClass)
93             .assertAbnormalExit(output -> {
94                     output.shouldContain("Cannot have the same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit: "
95                         + baseArchiveName);
96                 });
97 
98 
99         // a top archive specified in the base archive position
100         run2(topArchiveName, baseArchiveName,
101             "-Xlog:class+load",
102             "-Xlog:cds+dynamic=debug,cds=debug",
103             "-cp", appJar, mainClass)
104             .assertAbnormalExit(output -> {
105                     output.shouldMatch("Not a base shared archive:.*top.*.jsa");
106                 });
107 
108         // a base archive specified in the top archive position
109         run2(baseArchiveName, baseArchiveName2,
110             "-Xlog:class+load",
111             "-Xlog:cds+dynamic=debug,cds=debug",
112             "-cp", appJar, mainClass)
113             .assertAbnormalExit(output -> {
114                     output.shouldMatch("Not a top shared archive:.*base.*.jsa");
115                 });
116 
117         // more than 2 archives specified in the -XX:ShareArchiveFile option
118         String baseArchives = baseArchiveName + File.pathSeparator + baseArchiveName2;
119         run2(baseArchives, topArchiveName,
120             "-Xlog:class+load",
121             "-Xlog:cds+dynamic=debug,cds=debug",
122             "-cp", appJar, mainClass)
123             .assertAbnormalExit(output -> {
124                     output.shouldContain(
125                         "Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option");
126                 });
127 
128         // base archive not specified
129         final String topArchive = File.pathSeparator + topArchiveName;
130         run2(topArchive, null,
131             "-Xlog:class+load",
132             "-Xlog:cds+dynamic=debug,cds=debug",
133             "-cp", appJar, mainClass)
134             .assertAbnormalExit(output -> {
135                     output.shouldContain(
136                         "Base archive was not specified: " + topArchive);
137                 });
138 
139         // top archive not specified
140         final String baseArchive = baseArchiveName + File.pathSeparator;
141         run2(baseArchive, null,
142             "-Xlog:class+load",
143             "-Xlog:cds+dynamic=debug,cds=debug",
144             "-cp", appJar, mainClass)
145             .assertAbnormalExit(output -> {
146                     output.shouldContain(
147                         "Top archive was not specified: " + baseArchive);
148                 });
149     }
150 }
151