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;
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 = printModuleDescriptor(zf);
412 }
413 } else {
414 try (FileInputStream fin = new FileInputStream(FileDescriptor.in)) {
415 found = printModuleDescriptor(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())
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 // "--print-module-descriptor/-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 printModuleDescriptor(ZipFile zipFile)
1733 throws IOException
1734 {
1735 ZipEntry[] zes = zipFile.stream()
1736 .filter(e -> isModuleInfoEntry(e.getName()))
1737 .sorted(Validator.ENTRY_COMPARATOR)
1738 .toArray(ZipEntry[]::new);
1739 if (zes.length == 0)
1740 return false;
1741 for (ZipEntry ze : zes) {
1742 try (InputStream is = zipFile.getInputStream(ze)) {
1743 printModuleDescriptor(is, ze.getName());
1744 }
1745 }
1746 return true;
1747 }
1748
1749 private boolean printModuleDescriptor(FileInputStream fis)
1750 throws IOException
1751 {
1752 try (BufferedInputStream bis = new BufferedInputStream(fis);
1753 ZipInputStream zis = new ZipInputStream(bis)) {
1754 ZipEntry e;
1755 while ((e = zis.getNextEntry()) != null) {
1756 String ename = e.getName();
1757 if (isModuleInfoEntry(ename)){
1758 moduleInfos.put(ename, zis.readAllBytes());
1759 }
1760 }
1761 }
1762 if (moduleInfos.size() == 0)
1763 return false;
1764 String[] names = moduleInfos.keySet().stream()
1765 .sorted(Validator.ENTRYNAME_COMPARATOR)
|
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;
392 extract(fname, files);
393 } else {
394 InputStream in = (fname == null)
395 ? new FileInputStream(FileDescriptor.in)
396 : new FileInputStream(fname);
397 try {
398 if (!extract(new BufferedInputStream(in), files) && fname != null) {
399 extract(fname, files);
400 }
401 } finally {
402 in.close();
403 }
404 }
405 } else if (iflag) {
406 String[] files = filesMap.get(BASE_VERSION); // base entries only, can be null
407 genIndex(rootjar, files);
408 } else if (dflag) {
409 boolean found;
410 if (fname != null) {
411 try (ZipFile zf = new ZipFile(fname)) {
412 found = describeModule(zf);
413 }
414 } else {
415 try (FileInputStream fin = new FileInputStream(FileDescriptor.in)) {
416 found = printModuleDescriptor(fin);
417 }
418 }
419 if (!found)
420 error(getMsg("error.module.descriptor.not.found"));
421 }
422 } catch (IOException e) {
423 fatalError(e);
424 ok = false;
425 } catch (Error ee) {
426 ee.printStackTrace();
427 ok = false;
428 } catch (Throwable t) {
429 t.printStackTrace();
430 ok = false;
431 } finally {
432 if (tmpFile != null && tmpFile.exists())
588 default:
589 usageError(formatMsg("error.illegal.option",
590 String.valueOf(flags.charAt(i))));
591 return false;
592 }
593 }
594 }
595 } catch (ArrayIndexOutOfBoundsException e) {
596 usageError(getMsg("main.usage.summary"));
597 return false;
598 }
599 if (!cflag && !tflag && !xflag && !uflag && !iflag && !dflag) {
600 usageError(getMsg("error.bad.option"));
601 return false;
602 }
603
604 /* parse file arguments */
605 int n = args.length - count;
606 if (n > 0) {
607 if (dflag) {
608 // "--describe-module/-d" does not require file argument(s)
609 usageError(formatMsg("error.bad.dflag", args[count]));
610 return false;
611 }
612 int version = BASE_VERSION;
613 int k = 0;
614 String[] nameBuf = new String[n];
615 pathsMap.put(version, new HashSet<>());
616 try {
617 for (int i = count; i < args.length; i++) {
618 if (args[i].equals("-C")) {
619 /* change the directory */
620 String dir = args[++i];
621 dir = (dir.endsWith(File.separator) ?
622 dir : (dir + File.separator));
623 dir = dir.replace(File.separatorChar, '/');
624 while (dir.indexOf("//") > -1) {
625 dir = dir.replace("//", "/");
626 }
627 pathsMap.get(version).add(dir.replace(File.separatorChar, '/'));
628 nameBuf[k++] = dir + args[++i];
1713 }
1714 } else {
1715 // No options left - we can not compress to stdout without access to the temporary folder
1716 fatalError(new IOException(getMsg("error.create.tempfile")));
1717 }
1718 }
1719 return tmpfile;
1720 }
1721
1722 // Modular jar support
1723
1724 static <T> String toString(Collection<T> c,
1725 CharSequence prefix,
1726 CharSequence suffix ) {
1727 if (c.isEmpty())
1728 return "";
1729 return c.stream().map(e -> e.toString())
1730 .collect(joining(", ", prefix, suffix));
1731 }
1732
1733 private boolean describeModule(ZipFile zipFile) throws IOException {
1734 ZipEntry[] zes = zipFile.stream()
1735 .filter(e -> isModuleInfoEntry(e.getName()))
1736 .sorted(Validator.ENTRY_COMPARATOR)
1737 .toArray(ZipEntry[]::new);
1738
1739 if (zes.length == 0) {
1740 // No module descriptor found, derive the automatic module name
1741 String fn = zipFile.getName();
1742 ModuleFinder mf = ModuleFinder.of(Paths.get(fn));
1743 try {
1744 Set<ModuleReference> mref = mf.findAll();
1745 if (mref.isEmpty()) {
1746 output(formatMsg("error.unable.derive.automodule", fn));
1747 return true;
1748 }
1749 String nv = mref.iterator().next().descriptor().toNameAndVersion();
1750 output(formatMsg("out.automodule.name", nv));
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 printModuleDescriptor(is, ze.getName());
1762 }
1763 }
1764 }
1765 return true;
1766 }
1767
1768 private boolean printModuleDescriptor(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)
|