1 /* 2 * Copyright (c) 2017, 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 * @library /lib/testlibrary 27 * @build ExecJarWithAgent Main Agent AgentHelper JarUtils jdk.testlibrary.* 28 * @run testng ExecJarWithAgent 29 * @summary Test starting agents in executable JAR files 30 */ 31 32 import java.nio.file.Path; 33 import java.nio.file.Paths; 34 import java.util.jar.Attributes; 35 import java.util.jar.Manifest; 36 import java.util.stream.Stream; 37 38 import org.testng.annotations.Test; 39 import static org.testng.Assert.*; 40 41 import jdk.testlibrary.ProcessTools; 42 import jdk.testlibrary.OutputAnalyzer; 43 44 @Test 45 public class ExecJarWithAgent { 46 47 /** 48 * Basic test of java -jar with agent in the executable JAR 49 */ 50 public void testBasic() throws Exception { 51 Manifest man = new Manifest(); 52 Attributes attrs = man.getMainAttributes(); 53 attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0.0"); 54 attrs.put(Attributes.Name.MAIN_CLASS, "Main"); 55 attrs.put(new Attributes.Name("Launcher-Agent-Class"), "Agent"); 56 57 // require all capabilities 58 attrs.put(new Attributes.Name("Can-Redefine-Classes"), "true"); 59 attrs.put(new Attributes.Name("Can-Retransform-Classes"), "true"); 60 attrs.put(new Attributes.Name("Can-Set-Native-Method-Prefix"), "true"); 61 attrs.put(new Attributes.Name("Boot-Class-Path"), "helper.jar"); 62 63 Path app = Paths.get("app.jar"); 64 Path dir = Paths.get(System.getProperty("test.classes")); 65 66 Path[] paths = Stream.of("Main.class", "Agent.class") 67 .map(Paths::get) 68 .toArray(Path[]::new); 69 70 JarUtils.createJarFile(app, man, dir, paths); 71 72 // helper API to test that the BCP has been extended 73 Path helper = Paths.get("helper.jar"); 74 JarUtils.createJarFile(helper, dir, "AgentHelper.class"); 75 76 // java -jar app.jar 77 assertEquals(exec(app).getExitValue(), 0); 78 } 79 80 /** 81 * Test that java -jar fails when the executable JAR has the 82 * Launcher-Agent-Class attribute but the class cannot be loaded. 83 */ 84 public void testBadAgentClass() throws Exception { 85 Manifest man = new Manifest(); 86 Attributes attrs = man.getMainAttributes(); 87 attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0.0"); 88 attrs.put(Attributes.Name.MAIN_CLASS, "Main"); 89 90 // agent class does not exist 91 attrs.put(new Attributes.Name("Launcher-Agent-Class"), "BadAgent"); 92 93 Path app = Paths.get("app.jar"); 94 Path dir = Paths.get(System.getProperty("test.classes")); 95 96 JarUtils.createJarFile(app, man, dir, Paths.get("Main.class")); 97 98 // java -jar app.jar 99 int exitCode = exec(app).shouldContain("ClassNotFoundException").getExitValue(); 100 assertNotEquals(exitCode, 0); 101 } 102 103 /** 104 * Test that java -jar fails when the executable JAR has the 105 * Launcher-Agent-Class attribute and the class does not define an 106 * agentmain method. 107 */ 108 public void testNoAgentMain() throws Exception { 109 // manifest for the executable JAR 110 Manifest man = new Manifest(); 111 Attributes attrs = man.getMainAttributes(); 112 attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0.0"); 113 attrs.put(Attributes.Name.MAIN_CLASS, "Main"); 114 115 // the main class does not define the agentmain method 116 attrs.put(new Attributes.Name("Launcher-Agent-Class"), "Main"); 117 118 Path app = Paths.get("app.jar"); 119 Path dir = Paths.get(System.getProperty("test.classes")); 120 121 JarUtils.createJarFile(app, man, dir, Paths.get("Main.class")); 122 123 // java -jar app.jar 124 int exitCode = exec(app).shouldContain("NoSuchMethodException").getExitValue(); 125 assertNotEquals(exitCode, 0); 126 } 127 128 /** 129 * java -jar app.jar, returning the OutputAnalyzer to analyze the output 130 */ 131 private OutputAnalyzer exec(Path appJar) throws Exception { 132 return ProcessTools.executeTestJava("-jar", appJar.toString()) 133 .outputTo(System.out) 134 .errorTo(System.out); 135 } 136 137 138 }