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