< prev index next >

src/jdk.jartool/share/classes/sun/tools/jar/Main.java

Print this page




  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.tools.jar;
  27 
  28 import java.io.*;
  29 import java.lang.module.Configuration;

  30 import java.lang.module.InvalidModuleDescriptorException;
  31 import java.lang.module.ModuleDescriptor;
  32 import java.lang.module.ModuleDescriptor.Exports;
  33 import java.lang.module.ModuleDescriptor.Provides;
  34 import java.lang.module.ModuleDescriptor.Opens;
  35 import java.lang.module.ModuleDescriptor.Requires;
  36 import java.lang.module.ModuleDescriptor.Version;
  37 import java.lang.module.ModuleFinder;
  38 import java.lang.module.ModuleReader;
  39 import java.lang.module.ModuleReference;
  40 import java.lang.module.ResolutionException;
  41 import java.lang.module.ResolvedModule;
  42 import java.net.URI;
  43 import java.nio.ByteBuffer;
  44 import java.nio.file.Path;
  45 import java.nio.file.Files;
  46 import java.nio.file.Paths;
  47 import java.nio.file.StandardCopyOption;
  48 import java.util.*;
  49 import java.util.function.Consumer;


 390                     extract(fname, files);
 391                 } else {
 392                     InputStream in = (fname == null)
 393                         ? new FileInputStream(FileDescriptor.in)
 394                         : new FileInputStream(fname);
 395                     try {
 396                         if (!extract(new BufferedInputStream(in), files) && fname != null) {
 397                             extract(fname, files);
 398                         }
 399                     } finally {
 400                         in.close();
 401                     }
 402                 }
 403             } else if (iflag) {
 404                 String[] files = filesMap.get(BASE_VERSION);  // base entries only, can be null
 405                 genIndex(rootjar, files);
 406             } else if (dflag) {
 407                 boolean found;
 408                 if (fname != null) {
 409                     try (ZipFile zf = new ZipFile(fname)) {
 410                         found = printModuleDescriptor(zf);
 411                     }
 412                 } else {
 413                     try (FileInputStream fin = new FileInputStream(FileDescriptor.in)) {
 414                         found = printModuleDescriptor(fin);
 415                     }
 416                 }
 417                 if (!found)
 418                     error(getMsg("error.module.descriptor.not.found"));
 419             }
 420         } catch (IOException e) {
 421             fatalError(e);
 422             ok = false;
 423         } catch (Error ee) {
 424             ee.printStackTrace();
 425             ok = false;
 426         } catch (Throwable t) {
 427             t.printStackTrace();
 428             ok = false;
 429         } finally {
 430             if (tmpFile != null && tmpFile.exists())
 431                 tmpFile.delete();
 432         }
 433         out.flush();
 434         err.flush();


 586                         default:
 587                             usageError(formatMsg("error.illegal.option",
 588                                        String.valueOf(flags.charAt(i))));
 589                             return false;
 590                     }
 591                 }
 592             }
 593         } catch (ArrayIndexOutOfBoundsException e) {
 594             usageError(getMsg("main.usage.summary"));
 595             return false;
 596         }
 597         if (!cflag && !tflag && !xflag && !uflag && !iflag && !dflag) {
 598             usageError(getMsg("error.bad.option"));
 599             return false;
 600         }
 601 
 602         /* parse file arguments */
 603         int n = args.length - count;
 604         if (n > 0) {
 605             if (dflag) {
 606                 // "--print-module-descriptor/-d" does not require file argument(s)
 607                 usageError(formatMsg("error.bad.dflag", args[count]));
 608                 return false;
 609             }
 610             int version = BASE_VERSION;
 611             int k = 0;
 612             String[] nameBuf = new String[n];
 613             pathsMap.put(version, new HashSet<>());
 614             try {
 615                 for (int i = count; i < args.length; i++) {
 616                     if (args[i].equals("-C")) {
 617                         /* change the directory */
 618                         String dir = args[++i];
 619                         dir = (dir.endsWith(File.separator) ?
 620                                dir : (dir + File.separator));
 621                         dir = dir.replace(File.separatorChar, '/');
 622                         while (dir.indexOf("//") > -1) {
 623                             dir = dir.replace("//", "/");
 624                         }
 625                         pathsMap.get(version).add(dir.replace(File.separatorChar, '/'));
 626                         nameBuf[k++] = dir + args[++i];


1711                 }
1712             } else {
1713                 // No options left - we can not compress to stdout without access to the temporary folder
1714                 fatalError(new IOException(getMsg("error.create.tempfile")));
1715             }
1716         }
1717         return tmpfile;
1718     }
1719 
1720     // Modular jar support
1721 
1722     static <T> String toString(Collection<T> c,
1723                                CharSequence prefix,
1724                                CharSequence suffix ) {
1725         if (c.isEmpty())
1726             return "";
1727         return c.stream().map(e -> e.toString())
1728                            .collect(joining(", ", prefix, suffix));
1729     }
1730 
1731     private boolean printModuleDescriptor(ZipFile zipFile)
1732         throws IOException
1733     {
1734         ZipEntry[] zes = zipFile.stream()
1735             .filter(e -> isModuleInfoEntry(e.getName()))
1736             .sorted(Validator.ENTRY_COMPARATOR)
1737             .toArray(ZipEntry[]::new);
1738         if (zes.length == 0)
1739             return false;




















1740         for (ZipEntry ze : zes) {
1741             try (InputStream is = zipFile.getInputStream(ze)) {
1742                 printModuleDescriptor(is, ze.getName());

1743             }
1744         }
1745         return true;
1746     }
1747 
1748     private boolean printModuleDescriptor(FileInputStream fis)
1749         throws IOException
1750     {
1751         try (BufferedInputStream bis = new BufferedInputStream(fis);
1752              ZipInputStream zis = new ZipInputStream(bis)) {
1753             ZipEntry e;
1754             while ((e = zis.getNextEntry()) != null) {
1755                 String ename = e.getName();
1756                 if (isModuleInfoEntry(ename)){
1757                     moduleInfos.put(ename, zis.readAllBytes());
1758                 }
1759             }
1760         }
1761         if (moduleInfos.size() == 0)
1762             return false;
1763         String[] names = moduleInfos.keySet().stream()
1764             .sorted(Validator.ENTRYNAME_COMPARATOR)
1765             .toArray(String[]::new);
1766         for (String name : names) {
1767             printModuleDescriptor(new ByteArrayInputStream(moduleInfos.get(name)), name);
1768         }
1769         return true;
1770     }
1771 
1772     static <T> String toString(Collection<T> set) {
1773         if (set.isEmpty()) { return ""; }
1774         return set.stream().map(e -> e.toString().toLowerCase(Locale.ROOT))
1775                   .collect(joining(" "));
1776     }
1777 
1778     private void printModuleDescriptor(InputStream entryInputStream, String ename)
1779         throws IOException
1780     {
1781         ModuleInfo.Attributes attrs = ModuleInfo.read(entryInputStream, null);
1782         ModuleDescriptor md = attrs.descriptor();
1783         ModuleHashes hashes = attrs.recordedHashes();
1784 








1785         StringBuilder sb = new StringBuilder();
1786         sb.append("\nmodule ")
1787           .append(md.toNameAndVersion())
1788           .append(" (").append(ename).append(")");
1789 
1790         if (md.isOpen())
1791             sb.append("\n  open ");
1792 
1793         md.requires().stream()
1794             .sorted(Comparator.comparing(Requires::name))
1795             .forEach(r -> {
1796                 sb.append("\n  requires ");
1797                 if (!r.modifiers().isEmpty())
1798                     sb.append(toString(r.modifiers())).append(" ");
1799                 sb.append(r.name());
1800             });
1801 
1802         md.uses().stream().sorted()
1803             .forEach(p -> sb.append("\n  uses ").append(p));
1804 




  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.tools.jar;
  27 
  28 import java.io.*;
  29 import java.lang.module.Configuration;
  30 import java.lang.module.FindException;
  31 import java.lang.module.InvalidModuleDescriptorException;
  32 import java.lang.module.ModuleDescriptor;
  33 import java.lang.module.ModuleDescriptor.Exports;
  34 import java.lang.module.ModuleDescriptor.Provides;
  35 import java.lang.module.ModuleDescriptor.Opens;
  36 import java.lang.module.ModuleDescriptor.Requires;
  37 import java.lang.module.ModuleDescriptor.Version;
  38 import java.lang.module.ModuleFinder;
  39 import java.lang.module.ModuleReader;
  40 import java.lang.module.ModuleReference;
  41 import java.lang.module.ResolutionException;
  42 import java.lang.module.ResolvedModule;
  43 import java.net.URI;
  44 import java.nio.ByteBuffer;
  45 import java.nio.file.Path;
  46 import java.nio.file.Files;
  47 import java.nio.file.Paths;
  48 import java.nio.file.StandardCopyOption;
  49 import java.util.*;
  50 import java.util.function.Consumer;


 391                     extract(fname, files);
 392                 } else {
 393                     InputStream in = (fname == null)
 394                         ? new FileInputStream(FileDescriptor.in)
 395                         : new FileInputStream(fname);
 396                     try {
 397                         if (!extract(new BufferedInputStream(in), files) && fname != null) {
 398                             extract(fname, files);
 399                         }
 400                     } finally {
 401                         in.close();
 402                     }
 403                 }
 404             } else if (iflag) {
 405                 String[] files = filesMap.get(BASE_VERSION);  // base entries only, can be null
 406                 genIndex(rootjar, files);
 407             } else if (dflag) {
 408                 boolean found;
 409                 if (fname != null) {
 410                     try (ZipFile zf = new ZipFile(fname)) {
 411                         found = describeModule(zf);
 412                     }
 413                 } else {
 414                     try (FileInputStream fin = new FileInputStream(FileDescriptor.in)) {
 415                         found = describeModule(fin);
 416                     }
 417                 }
 418                 if (!found)
 419                     error(getMsg("error.module.descriptor.not.found"));
 420             }
 421         } catch (IOException e) {
 422             fatalError(e);
 423             ok = false;
 424         } catch (Error ee) {
 425             ee.printStackTrace();
 426             ok = false;
 427         } catch (Throwable t) {
 428             t.printStackTrace();
 429             ok = false;
 430         } finally {
 431             if (tmpFile != null && tmpFile.exists())
 432                 tmpFile.delete();
 433         }
 434         out.flush();
 435         err.flush();


 587                         default:
 588                             usageError(formatMsg("error.illegal.option",
 589                                        String.valueOf(flags.charAt(i))));
 590                             return false;
 591                     }
 592                 }
 593             }
 594         } catch (ArrayIndexOutOfBoundsException e) {
 595             usageError(getMsg("main.usage.summary"));
 596             return false;
 597         }
 598         if (!cflag && !tflag && !xflag && !uflag && !iflag && !dflag) {
 599             usageError(getMsg("error.bad.option"));
 600             return false;
 601         }
 602 
 603         /* parse file arguments */
 604         int n = args.length - count;
 605         if (n > 0) {
 606             if (dflag) {
 607                 // "--describe-module/-d" does not require file argument(s)
 608                 usageError(formatMsg("error.bad.dflag", args[count]));
 609                 return false;
 610             }
 611             int version = BASE_VERSION;
 612             int k = 0;
 613             String[] nameBuf = new String[n];
 614             pathsMap.put(version, new HashSet<>());
 615             try {
 616                 for (int i = count; i < args.length; i++) {
 617                     if (args[i].equals("-C")) {
 618                         /* change the directory */
 619                         String dir = args[++i];
 620                         dir = (dir.endsWith(File.separator) ?
 621                                dir : (dir + File.separator));
 622                         dir = dir.replace(File.separatorChar, '/');
 623                         while (dir.indexOf("//") > -1) {
 624                             dir = dir.replace("//", "/");
 625                         }
 626                         pathsMap.get(version).add(dir.replace(File.separatorChar, '/'));
 627                         nameBuf[k++] = dir + args[++i];


1712                 }
1713             } else {
1714                 // No options left - we can not compress to stdout without access to the temporary folder
1715                 fatalError(new IOException(getMsg("error.create.tempfile")));
1716             }
1717         }
1718         return tmpfile;
1719     }
1720 
1721     // Modular jar support
1722 
1723     static <T> String toString(Collection<T> c,
1724                                CharSequence prefix,
1725                                CharSequence suffix ) {
1726         if (c.isEmpty())
1727             return "";
1728         return c.stream().map(e -> e.toString())
1729                            .collect(joining(", ", prefix, suffix));
1730     }
1731 
1732     private boolean describeModule(ZipFile zipFile) throws IOException {


1733         ZipEntry[] zes = zipFile.stream()
1734             .filter(e -> isModuleInfoEntry(e.getName()))
1735             .sorted(Validator.ENTRY_COMPARATOR)
1736             .toArray(ZipEntry[]::new);
1737 
1738         if (zes.length == 0) {
1739             // No module descriptor found, derive the automatic module name
1740             String fn = zipFile.getName();
1741             ModuleFinder mf = ModuleFinder.of(Paths.get(fn));
1742             try {
1743                 Set<ModuleReference> mref = mf.findAll();
1744                 if (mref.isEmpty()) {
1745                     output(formatMsg("error.unable.derive.automodule", fn));
1746                     return true;
1747                 }
1748                 ModuleDescriptor md = mref.iterator().next().descriptor();
1749                 output(getMsg("out.automodule"));
1750                 describeModule(md, null, "automatic");
1751             } catch (FindException e) {
1752                 String msg = formatMsg("error.unable.derive.automodule", fn);
1753                 Throwable t = e.getCause();
1754                 if (t != null)
1755                     msg = msg + "\n" + t.getMessage();
1756                 output(msg);
1757             }
1758         } else {
1759             for (ZipEntry ze : zes) {
1760                 try (InputStream is = zipFile.getInputStream(ze)) {
1761                     describeModule(is, ze.getName());
1762                 }
1763             }
1764         }
1765         return true;
1766     }
1767 
1768     private boolean describeModule(FileInputStream fis)
1769         throws IOException
1770     {
1771         try (BufferedInputStream bis = new BufferedInputStream(fis);
1772              ZipInputStream zis = new ZipInputStream(bis)) {
1773             ZipEntry e;
1774             while ((e = zis.getNextEntry()) != null) {
1775                 String ename = e.getName();
1776                 if (isModuleInfoEntry(ename)){
1777                     moduleInfos.put(ename, zis.readAllBytes());
1778                 }
1779             }
1780         }
1781         if (moduleInfos.size() == 0)
1782             return false;
1783         String[] names = moduleInfos.keySet().stream()
1784             .sorted(Validator.ENTRYNAME_COMPARATOR)
1785             .toArray(String[]::new);
1786         for (String name : names) {
1787             describeModule(new ByteArrayInputStream(moduleInfos.get(name)), name);
1788         }
1789         return true;
1790     }
1791 
1792     static <T> String toString(Collection<T> set) {
1793         if (set.isEmpty()) { return ""; }
1794         return set.stream().map(e -> e.toString().toLowerCase(Locale.ROOT))
1795                   .collect(joining(" "));
1796     }
1797 
1798     private void describeModule(InputStream entryInputStream, String ename)
1799         throws IOException
1800     {
1801         ModuleInfo.Attributes attrs = ModuleInfo.read(entryInputStream, null);
1802         ModuleDescriptor md = attrs.descriptor();
1803         ModuleHashes hashes = attrs.recordedHashes();
1804 
1805         describeModule(md, hashes, ename);
1806     }
1807 
1808     private void describeModule(ModuleDescriptor md,
1809                                 ModuleHashes hashes,
1810                                 String ename)
1811         throws IOException
1812     {
1813         StringBuilder sb = new StringBuilder();
1814         sb.append("\nmodule ")
1815           .append(md.toNameAndVersion())
1816           .append(" (").append(ename).append(")");
1817 
1818         if (md.isOpen())
1819             sb.append("\n  open ");
1820 
1821         md.requires().stream()
1822             .sorted(Comparator.comparing(Requires::name))
1823             .forEach(r -> {
1824                 sb.append("\n  requires ");
1825                 if (!r.modifiers().isEmpty())
1826                     sb.append(toString(r.modifiers())).append(" ");
1827                 sb.append(r.name());
1828             });
1829 
1830         md.uses().stream().sorted()
1831             .forEach(p -> sb.append("\n  uses ").append(p));
1832 


< prev index next >