1 /*
2 * Copyright (c) 2006, 2010, 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 * @bug 6434207 6442687 6984046
27 * @modules jdk.jartool
28 * @summary Ensure that jar ufm actually updates the
29 * existing jar file's manifest with contents of the
30 * manifest file.
31 */
32
33 import java.io.*;
34 import java.util.logging.*;
35 import java.util.spi.ToolProvider;
36 import java.util.zip.*;
37
38 public class UpdateManifest {
39 static PrintStream out = System.out;
40 static PrintStream err = System.err;
41 static boolean debug = true;
42
43 static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar").get();
44
45 static final Logger JAR_LOGGER = Logger.getLogger("java.util.jar");
46
47 public static void realMain(String[] args) throws Throwable {
48 if (args.length == 0) {
49 debug = false;
50 File tmp = File.createTempFile("system-out-err", ".txt");
51 tmp.deleteOnExit();
52 out = new PrintStream(new FileOutputStream(tmp));
53 err = out;
54 // Attributes.read() can log a message we don't care to see.
55 JAR_LOGGER.setLevel(Level.OFF);
56 }
57
58 try { testManifestExistence(); } catch (Throwable t) { unexpected(t); }
59 try { testManifestContents(); } catch (Throwable t) { unexpected(t); }
60 }
61
62 static void testManifestExistence() throws Throwable {
63 // Create a file to put in a jar file
64 File existence = createTextFile("existence");
65
66 // Create a jar file, specifying a Main-Class
67 final String jarFileName = "um-existence.jar";
68 new File(jarFileName).delete(); // remove pre-existing first!
69 int status = JAR_TOOL.run(out, err, "cfe", jarFileName,
70 "Hello", existence.getPath());
71 check(status == 0);
72 checkManifest(jarFileName, "Hello");
73
74 // Update that jar file by changing the Main-Class
75 status = JAR_TOOL.run(out, err, "ufe", jarFileName, "Bye");
76 check(status == 0);
77 checkManifest(jarFileName, "Bye");
78 }
79
80 static void testManifestContents() throws Throwable {
81 // Create some strings we expect to find in the updated manifest
82 final String animal =
83 "Name: animal/marsupial";
84 final String specTitle =
85 "Specification-Title: Wombat";
86
87 // Create a text file with manifest entries
88 File manifestOrig = File.createTempFile("manifestOrig", ".txt");
89 if (!debug) manifestOrig.deleteOnExit();
90 PrintWriter pw = new PrintWriter(manifestOrig);
91 pw.println("Manifest-Version: 1.0");
92 pw.println("Created-By: 1.7.0-internal (Oracle Corporation)");
93 pw.println("");
94 pw.println(animal);
95 pw.println(specTitle);
96 pw.close();
97
98 File hello = createTextFile("hello");
99
100 // Create a jar file
101 final String jarFileName = "um-test.jar";
102 new File(jarFileName).delete(); // remove pre-existing first!
103 int status = JAR_TOOL.run(out, err, "cfm", jarFileName,
104 manifestOrig.getPath(), hello.getPath());
105 check(status == 0);
106
107 // Create a new manifest, to use in updating the jar file.
108 File manifestUpdate = File.createTempFile("manifestUpdate", ".txt");
109 if (!debug) manifestUpdate.deleteOnExit();
110 pw = new PrintWriter(manifestUpdate);
111 final String createdBy =
112 "Created-By: 1.7.0-special (Oracle Corporation)";
113 final String specVersion =
114 "Specification-Version: 1.0.0.0";
115 pw.println(createdBy); // replaces line in the original
116 pw.println("");
117 pw.println(animal);
118 pw.println(specVersion); // addition to animal/marsupial section
119 pw.close();
120
121 // Update jar file with manifest
122 status = JAR_TOOL.run(out, err, "ufm",
123 jarFileName, manifestUpdate.getPath());
124 check(status == 0);
125
126 // Extract jar, and verify contents of manifest file
127 File f = new File(jarFileName);
128 if (!debug) f.deleteOnExit();
129 ZipFile zf = new ZipFile(f);
130 ZipEntry ze = zf.getEntry("META-INF/MANIFEST.MF");
131 BufferedReader r = new BufferedReader(
132 new InputStreamReader(zf.getInputStream(ze)));
133 r.readLine(); // skip Manifest-Version
134 check(r.readLine().equals(createdBy));
135 r.readLine(); // skip blank line
136 check(r.readLine().equals(animal));
137 String s = r.readLine();
138 if (s.equals(specVersion)) {
139 check(r.readLine().equals(specTitle));
140 } else if (s.equals(specTitle)) {
141 check(r.readLine().equals(specVersion));
142 } else {
143 fail("did not match specVersion nor specTitle");
144 }
145 zf.close();
146 }
147
148 // --------------------- Convenience ---------------------------
149
150 static File createTextFile(String name) throws Throwable {
151 // Create a text file to put in a jar file
152 File rc = File.createTempFile(name, ".txt");
153 if (!debug) rc.deleteOnExit();
154 PrintWriter pw = new PrintWriter(rc);
155 pw.println("hello, world");
156 pw.close();
157 return rc;
158 }
159
160 static void checkManifest(String jarFileName, String mainClass)
161 throws Throwable {
162 File f = new File(jarFileName);
163 if (!debug) f.deleteOnExit();
164 ZipFile zf = new ZipFile(f);
165 ZipEntry ze = zf.getEntry("META-INF/MANIFEST.MF");
166 BufferedReader r = new BufferedReader(
167 new InputStreamReader(zf.getInputStream(ze)));
168 String line = r.readLine();
169 while (line != null && !(line.startsWith("Main-Class:"))) {
170 line = r.readLine();
171 }
172 if (line == null) {
173 fail("Didn't find Main-Class in manifest");
174 } else {
175 check(line.equals("Main-Class: " + mainClass));
176 }
177 zf.close();
178 }
179
180 // --------------------- Infrastructure ---------------------------
181
182 static volatile int passed = 0, failed = 0;
183
184 static void pass() {
185 passed++;
186 }
187
188 static void fail() {
189 failed++;
190 Thread.dumpStack();
191 }
192
193 static void fail(String msg) {
194 System.out.println(msg);
195 fail();
196 }
197
198 static void unexpected(Throwable t) {
199 failed++;
200 t.printStackTrace();
201 }
202
203 static void check(boolean cond) {
204 if (cond)
205 pass();
206 else
207 fail();
208 }
209
210 static void equal(Object x, Object y) {
211 if ((x == null) ? (y == null) : x.equals(y))
212 pass();
213 else
214 fail(x + " not equal to " + y);
215 }
216
217 public static void main(String[] args) throws Throwable {
218 try {
219 realMain(args);
220 } catch (Throwable t) {
221 unexpected(t);
222 }
223 System.out.println("\nPassed = " + passed + " failed = " + failed);
224 if (failed > 0)
225 throw new AssertionError("Some tests failed");
226 }
227 }