< prev index next >

test/lib/jdk/test/lib/util/JarUtils.java

Print this page
rev 58207 : 8240235: jdk.test.lib.util.JarUtils updates jar files incorrectly
Reviewed-by: martin, clanger
   1 /*
   2  * Copyright (c) 2015, 2018, 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  */


 141      */
 142     public static void updateJarFile(Path jarfile, Path dir, Path... files)
 143             throws IOException
 144     {
 145         List<Path> entries = findAllRegularFiles(dir, files);
 146 
 147         Set<String> names = entries.stream()
 148                                    .map(JarUtils::toJarEntryName)
 149                                    .collect(Collectors.toSet());
 150 
 151         Path tmpfile = Files.createTempFile("jar", "jar");
 152 
 153         try (OutputStream out = Files.newOutputStream(tmpfile);
 154              JarOutputStream jos = new JarOutputStream(out)) {
 155             // copy existing entries from the original JAR file
 156             try (JarFile jf = new JarFile(jarfile.toString())) {
 157                 Enumeration<JarEntry> jentries = jf.entries();
 158                 while (jentries.hasMoreElements()) {
 159                     JarEntry jentry = jentries.nextElement();
 160                     if (!names.contains(jentry.getName())) {
 161                         jos.putNextEntry(jentry);
 162                         jf.getInputStream(jentry).transferTo(jos);
 163                     }
 164                 }
 165             }
 166 
 167             // add the new entries
 168             for (Path entry : entries) {
 169                 String name = toJarEntryName(entry);
 170                 jos.putNextEntry(new JarEntry(name));
 171                 Files.copy(dir.resolve(entry), jos);
 172             }
 173         }
 174 
 175         // replace the original JAR file
 176         Files.move(tmpfile, jarfile, StandardCopyOption.REPLACE_EXISTING);
 177     }
 178 
 179     /**
 180      * Updates a JAR file.
 181      *


 274         System.out.printf("Creating %s from %s...\n", dest, src);
 275 
 276         if (dest.equals(src)) {
 277             throw new IOException("src and dest cannot be the same");
 278         }
 279 
 280         try (JarOutputStream jos = new JarOutputStream(
 281                 new FileOutputStream(dest))) {
 282 
 283             try (JarFile srcJarFile = new JarFile(src)) {
 284                 Enumeration<JarEntry> entries = srcJarFile.entries();
 285                 while (entries.hasMoreElements()) {
 286                     JarEntry entry = entries.nextElement();
 287                     String name = entry.getName();
 288                     if (changes.containsKey(name)) {
 289                         System.out.println(String.format("- Update %s", name));
 290                         updateEntry(jos, name, changes.get(name));
 291                         changes.remove(name);
 292                     } else {
 293                         System.out.println(String.format("- Copy %s", name));
 294                         jos.putNextEntry(entry);
 295                         srcJarFile.getInputStream(entry).transferTo(jos);
 296                     }
 297                 }
 298             }
 299             for (Map.Entry<String, Object> e : changes.entrySet()) {
 300                 System.out.println(String.format("- Add %s", e.getKey()));
 301                 updateEntry(jos, e.getKey(), e.getValue());
 302             }
 303         }
 304         System.out.println();
 305     }
 306 
 307     /**
 308      * Update the Manifest inside a jar.
 309      *
 310      * @param src the original jar file name
 311      * @param dest the new jar file name
 312      * @param man the Manifest
 313      *
 314      * @throws IOException


 343     /**
 344      * Maps a file path to the equivalent name in a JAR file
 345      */
 346     private static String toJarEntryName(Path file) {
 347         Path normalized = file.normalize();
 348         return normalized.subpath(0, normalized.getNameCount())  // drop root
 349                          .toString()
 350                          .replace(File.separatorChar, '/');
 351     }
 352 
 353     private static List<Path> findAllRegularFiles(Path dir, Path[] files) throws IOException {
 354         List<Path> entries = new ArrayList<>();
 355         for (Path file : files) {
 356             try (Stream<Path> stream = Files.find(dir.resolve(file), Integer.MAX_VALUE,
 357                     (p, attrs) -> attrs.isRegularFile())) {
 358                 stream.map(dir::relativize)
 359                       .forEach(entries::add);
 360             }
 361         }
 362         return entries;













 363     }
 364 }
   1 /*
   2  * Copyright (c) 2015, 2020, 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  */


 141      */
 142     public static void updateJarFile(Path jarfile, Path dir, Path... files)
 143             throws IOException
 144     {
 145         List<Path> entries = findAllRegularFiles(dir, files);
 146 
 147         Set<String> names = entries.stream()
 148                                    .map(JarUtils::toJarEntryName)
 149                                    .collect(Collectors.toSet());
 150 
 151         Path tmpfile = Files.createTempFile("jar", "jar");
 152 
 153         try (OutputStream out = Files.newOutputStream(tmpfile);
 154              JarOutputStream jos = new JarOutputStream(out)) {
 155             // copy existing entries from the original JAR file
 156             try (JarFile jf = new JarFile(jarfile.toString())) {
 157                 Enumeration<JarEntry> jentries = jf.entries();
 158                 while (jentries.hasMoreElements()) {
 159                     JarEntry jentry = jentries.nextElement();
 160                     if (!names.contains(jentry.getName())) {
 161                         jos.putNextEntry(copyEntry(jentry));
 162                         jf.getInputStream(jentry).transferTo(jos);
 163                     }
 164                 }
 165             }
 166 
 167             // add the new entries
 168             for (Path entry : entries) {
 169                 String name = toJarEntryName(entry);
 170                 jos.putNextEntry(new JarEntry(name));
 171                 Files.copy(dir.resolve(entry), jos);
 172             }
 173         }
 174 
 175         // replace the original JAR file
 176         Files.move(tmpfile, jarfile, StandardCopyOption.REPLACE_EXISTING);
 177     }
 178 
 179     /**
 180      * Updates a JAR file.
 181      *


 274         System.out.printf("Creating %s from %s...\n", dest, src);
 275 
 276         if (dest.equals(src)) {
 277             throw new IOException("src and dest cannot be the same");
 278         }
 279 
 280         try (JarOutputStream jos = new JarOutputStream(
 281                 new FileOutputStream(dest))) {
 282 
 283             try (JarFile srcJarFile = new JarFile(src)) {
 284                 Enumeration<JarEntry> entries = srcJarFile.entries();
 285                 while (entries.hasMoreElements()) {
 286                     JarEntry entry = entries.nextElement();
 287                     String name = entry.getName();
 288                     if (changes.containsKey(name)) {
 289                         System.out.println(String.format("- Update %s", name));
 290                         updateEntry(jos, name, changes.get(name));
 291                         changes.remove(name);
 292                     } else {
 293                         System.out.println(String.format("- Copy %s", name));
 294                         jos.putNextEntry(copyEntry(entry));
 295                         srcJarFile.getInputStream(entry).transferTo(jos);
 296                     }
 297                 }
 298             }
 299             for (Map.Entry<String, Object> e : changes.entrySet()) {
 300                 System.out.println(String.format("- Add %s", e.getKey()));
 301                 updateEntry(jos, e.getKey(), e.getValue());
 302             }
 303         }
 304         System.out.println();
 305     }
 306 
 307     /**
 308      * Update the Manifest inside a jar.
 309      *
 310      * @param src the original jar file name
 311      * @param dest the new jar file name
 312      * @param man the Manifest
 313      *
 314      * @throws IOException


 343     /**
 344      * Maps a file path to the equivalent name in a JAR file
 345      */
 346     private static String toJarEntryName(Path file) {
 347         Path normalized = file.normalize();
 348         return normalized.subpath(0, normalized.getNameCount())  // drop root
 349                          .toString()
 350                          .replace(File.separatorChar, '/');
 351     }
 352 
 353     private static List<Path> findAllRegularFiles(Path dir, Path[] files) throws IOException {
 354         List<Path> entries = new ArrayList<>();
 355         for (Path file : files) {
 356             try (Stream<Path> stream = Files.find(dir.resolve(file), Integer.MAX_VALUE,
 357                     (p, attrs) -> attrs.isRegularFile())) {
 358                 stream.map(dir::relativize)
 359                       .forEach(entries::add);
 360             }
 361         }
 362         return entries;
 363     }
 364 
 365     private static JarEntry copyEntry(JarEntry e1) {
 366         JarEntry e2 = new JarEntry(e1.getName());
 367         e2.setMethod(e1.getMethod());
 368         e2.setTime(e1.getTime());
 369         e2.setComment(e1.getComment());
 370         e2.setExtra(e1.getExtra());
 371         if (e1.getMethod() == JarEntry.STORED) {
 372             e2.setSize(e1.getSize());
 373             e2.setCrc(e1.getCrc());
 374         }
 375         return e2;
 376     }
 377 }
< prev index next >