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 }