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