src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java

Print this page
rev 16200 : 8166568: jmod tool needs extract option
8169492: jdk.internal.jmod.JmodFile.JMOD_MAGIC_NUMBER is a mutable array
Reviewed-by:


  30 import java.io.File;
  31 import java.io.IOException;
  32 import java.io.InputStream;
  33 import java.io.OutputStream;
  34 import java.io.PrintStream;
  35 import java.io.PrintWriter;
  36 import java.io.UncheckedIOException;
  37 import java.lang.module.Configuration;
  38 import java.lang.module.ModuleReader;
  39 import java.lang.module.ModuleReference;
  40 import java.lang.module.ModuleFinder;
  41 import java.lang.module.ModuleDescriptor;
  42 import java.lang.module.ModuleDescriptor.Exports;
  43 import java.lang.module.ModuleDescriptor.Opens;
  44 import java.lang.module.ModuleDescriptor.Provides;
  45 import java.lang.module.ModuleDescriptor.Requires;
  46 import java.lang.module.ModuleDescriptor.Version;
  47 import java.lang.module.ResolutionException;
  48 import java.lang.module.ResolvedModule;
  49 import java.net.URI;

  50 import java.nio.file.FileSystems;
  51 import java.nio.file.FileVisitOption;
  52 import java.nio.file.FileVisitResult;
  53 import java.nio.file.Files;
  54 import java.nio.file.InvalidPathException;
  55 import java.nio.file.Path;
  56 import java.nio.file.PathMatcher;
  57 import java.nio.file.Paths;
  58 import java.nio.file.SimpleFileVisitor;
  59 import java.nio.file.StandardCopyOption;
  60 import java.nio.file.attribute.BasicFileAttributes;
  61 import java.text.MessageFormat;
  62 import java.util.ArrayDeque;
  63 import java.util.ArrayList;
  64 import java.util.Collection;
  65 import java.util.Collections;
  66 import java.util.Comparator;
  67 import java.util.Deque;
  68 import java.util.HashMap;
  69 import java.util.HashSet;


 136     }
 137 
 138     private static final String PROGNAME = "jmod";
 139     private static final String MODULE_INFO = "module-info.class";
 140 
 141     private Options options;
 142     private PrintWriter out = new PrintWriter(System.out, true);
 143     void setLog(PrintWriter out, PrintWriter err) {
 144         this.out = out;
 145     }
 146 
 147     /* Result codes. */
 148     static final int EXIT_OK = 0, // Completed with no errors.
 149                      EXIT_ERROR = 1, // Completed but reported errors.
 150                      EXIT_CMDERR = 2, // Bad command-line arguments
 151                      EXIT_SYSERR = 3, // System error or resource exhaustion.
 152                      EXIT_ABNORMAL = 4;// terminated abnormally
 153 
 154     enum Mode {
 155         CREATE,

 156         LIST,
 157         DESCRIBE,
 158         HASH
 159     };
 160 
 161     static class Options {
 162         Mode mode;
 163         Path jmodFile;
 164         boolean help;
 165         boolean version;
 166         List<Path> classpath;
 167         List<Path> cmds;
 168         List<Path> configs;
 169         List<Path> libs;
 170         List<Path> headerFiles;
 171         List<Path> manPages;
 172         ModuleFinder moduleFinder;
 173         Version moduleVersion;
 174         String mainClass;
 175         String osName;


 185         try {
 186             handleOptions(args);
 187             if (options == null) {
 188                 showUsageSummary();
 189                 return EXIT_CMDERR;
 190             }
 191             if (options.help) {
 192                 showHelp();
 193                 return EXIT_OK;
 194             }
 195             if (options.version) {
 196                 showVersion();
 197                 return EXIT_OK;
 198             }
 199 
 200             boolean ok;
 201             switch (options.mode) {
 202                 case CREATE:
 203                     ok = create();
 204                     break;



 205                 case LIST:
 206                     ok = list();
 207                     break;
 208                 case DESCRIBE:
 209                     ok = describe();
 210                     break;
 211                 case HASH:
 212                     ok = hashModules();
 213                     break;
 214                 default:
 215                     throw new AssertionError("Unknown mode: " + options.mode.name());
 216             }
 217 
 218             return ok ? EXIT_OK : EXIT_ERROR;
 219         } catch (CommandException e) {
 220             reportError(e.getMessage());
 221             if (e.showUsage)
 222                 showUsageSummary();
 223             return EXIT_CMDERR;
 224         } catch (Exception x) {


 231     }
 232 
 233     private boolean list() throws IOException {
 234         ZipFile zip = null;
 235         try {
 236             try {
 237                 zip = new ZipFile(options.jmodFile.toFile());
 238             } catch (IOException x) {
 239                 throw new IOException("error opening jmod file", x);
 240             }
 241 
 242             // Trivially print the archive entries for now, pending a more complete implementation
 243             zip.stream().forEach(e -> out.println(e.getName()));
 244             return true;
 245         } finally {
 246             if (zip != null)
 247                 zip.close();
 248         }
 249     }
 250 

























 251     private boolean hashModules() {
 252         return new Hasher(options.moduleFinder).run();
 253     }
 254 
 255     private boolean describe() throws IOException {
 256         try (JmodFile jf = new JmodFile(options.jmodFile)) {
 257             try (InputStream in = jf.getInputStream(Section.CLASSES, MODULE_INFO)) {
 258                 ModuleDescriptor md = ModuleDescriptor.read(in);
 259                 printModuleDescriptor(md);
 260                 return true;
 261             } catch (IOException e) {
 262                 throw new CommandException("err.module.descriptor.not.found");
 263             }
 264         }
 265     }
 266 
 267     static <T> String toString(Collection<T> c) {
 268         if (c.isEmpty()) { return ""; }
 269         return c.stream().map(e -> e.toString().toLowerCase(Locale.ROOT))
 270                   .collect(joining(" "));


1141                 @Override
1142                 public List<?> defaultValues() { return Collections.emptyList(); }
1143                 @Override
1144                 public boolean isRequired() { return false; }
1145                 @Override
1146                 public boolean acceptsArguments() { return false; }
1147                 @Override
1148                 public boolean requiresArgument() { return false; }
1149                 @Override
1150                 public String argumentDescription() { return null; }
1151                 @Override
1152                 public String argumentTypeIndicator() { return null; }
1153                 @Override
1154                 public boolean representsNonOptions() { return false; }
1155             });
1156             String content = super.format(all);
1157             StringBuilder builder = new StringBuilder();
1158 
1159             builder.append(getMessage("main.opt.mode")).append("\n  ");
1160             builder.append(getMessage("main.opt.mode.create")).append("\n  ");

1161             builder.append(getMessage("main.opt.mode.list")).append("\n  ");
1162             builder.append(getMessage("main.opt.mode.describe")).append("\n  ");
1163             builder.append(getMessage("main.opt.mode.hash")).append("\n\n");
1164 
1165             String cmdfile = null;
1166             String[] lines = content.split("\n");
1167             for (String line : lines) {
1168                 if (line.startsWith("--@")) {
1169                     cmdfile = line.replace("--" + CMD_FILENAME, CMD_FILENAME + "  ");
1170                 } else if (line.startsWith("Option") || line.startsWith("------")) {
1171                     builder.append(" ").append(line).append("\n");
1172                 } else if (!line.matches("Non-option arguments")){
1173                     builder.append("  ").append(line).append("\n");
1174                 }
1175             }
1176             if (cmdfile != null) {
1177                 builder.append("  ").append(cmdfile).append("\n");
1178             }
1179             return builder.toString();
1180         }




  30 import java.io.File;
  31 import java.io.IOException;
  32 import java.io.InputStream;
  33 import java.io.OutputStream;
  34 import java.io.PrintStream;
  35 import java.io.PrintWriter;
  36 import java.io.UncheckedIOException;
  37 import java.lang.module.Configuration;
  38 import java.lang.module.ModuleReader;
  39 import java.lang.module.ModuleReference;
  40 import java.lang.module.ModuleFinder;
  41 import java.lang.module.ModuleDescriptor;
  42 import java.lang.module.ModuleDescriptor.Exports;
  43 import java.lang.module.ModuleDescriptor.Opens;
  44 import java.lang.module.ModuleDescriptor.Provides;
  45 import java.lang.module.ModuleDescriptor.Requires;
  46 import java.lang.module.ModuleDescriptor.Version;
  47 import java.lang.module.ResolutionException;
  48 import java.lang.module.ResolvedModule;
  49 import java.net.URI;
  50 import java.nio.file.CopyOption;
  51 import java.nio.file.FileSystems;
  52 import java.nio.file.FileVisitOption;
  53 import java.nio.file.FileVisitResult;
  54 import java.nio.file.Files;
  55 import java.nio.file.InvalidPathException;
  56 import java.nio.file.Path;
  57 import java.nio.file.PathMatcher;
  58 import java.nio.file.Paths;
  59 import java.nio.file.SimpleFileVisitor;
  60 import java.nio.file.StandardCopyOption;
  61 import java.nio.file.attribute.BasicFileAttributes;
  62 import java.text.MessageFormat;
  63 import java.util.ArrayDeque;
  64 import java.util.ArrayList;
  65 import java.util.Collection;
  66 import java.util.Collections;
  67 import java.util.Comparator;
  68 import java.util.Deque;
  69 import java.util.HashMap;
  70 import java.util.HashSet;


 137     }
 138 
 139     private static final String PROGNAME = "jmod";
 140     private static final String MODULE_INFO = "module-info.class";
 141 
 142     private Options options;
 143     private PrintWriter out = new PrintWriter(System.out, true);
 144     void setLog(PrintWriter out, PrintWriter err) {
 145         this.out = out;
 146     }
 147 
 148     /* Result codes. */
 149     static final int EXIT_OK = 0, // Completed with no errors.
 150                      EXIT_ERROR = 1, // Completed but reported errors.
 151                      EXIT_CMDERR = 2, // Bad command-line arguments
 152                      EXIT_SYSERR = 3, // System error or resource exhaustion.
 153                      EXIT_ABNORMAL = 4;// terminated abnormally
 154 
 155     enum Mode {
 156         CREATE,
 157         EXTRACT,
 158         LIST,
 159         DESCRIBE,
 160         HASH
 161     };
 162 
 163     static class Options {
 164         Mode mode;
 165         Path jmodFile;
 166         boolean help;
 167         boolean version;
 168         List<Path> classpath;
 169         List<Path> cmds;
 170         List<Path> configs;
 171         List<Path> libs;
 172         List<Path> headerFiles;
 173         List<Path> manPages;
 174         ModuleFinder moduleFinder;
 175         Version moduleVersion;
 176         String mainClass;
 177         String osName;


 187         try {
 188             handleOptions(args);
 189             if (options == null) {
 190                 showUsageSummary();
 191                 return EXIT_CMDERR;
 192             }
 193             if (options.help) {
 194                 showHelp();
 195                 return EXIT_OK;
 196             }
 197             if (options.version) {
 198                 showVersion();
 199                 return EXIT_OK;
 200             }
 201 
 202             boolean ok;
 203             switch (options.mode) {
 204                 case CREATE:
 205                     ok = create();
 206                     break;
 207                 case EXTRACT:
 208                     ok = extract();
 209                     break;
 210                 case LIST:
 211                     ok = list();
 212                     break;
 213                 case DESCRIBE:
 214                     ok = describe();
 215                     break;
 216                 case HASH:
 217                     ok = hashModules();
 218                     break;
 219                 default:
 220                     throw new AssertionError("Unknown mode: " + options.mode.name());
 221             }
 222 
 223             return ok ? EXIT_OK : EXIT_ERROR;
 224         } catch (CommandException e) {
 225             reportError(e.getMessage());
 226             if (e.showUsage)
 227                 showUsageSummary();
 228             return EXIT_CMDERR;
 229         } catch (Exception x) {


 236     }
 237 
 238     private boolean list() throws IOException {
 239         ZipFile zip = null;
 240         try {
 241             try {
 242                 zip = new ZipFile(options.jmodFile.toFile());
 243             } catch (IOException x) {
 244                 throw new IOException("error opening jmod file", x);
 245             }
 246 
 247             // Trivially print the archive entries for now, pending a more complete implementation
 248             zip.stream().forEach(e -> out.println(e.getName()));
 249             return true;
 250         } finally {
 251             if (zip != null)
 252                 zip.close();
 253         }
 254     }
 255 
 256     private boolean extract() throws IOException {
 257         try (JmodFile jf = new JmodFile(options.jmodFile)) {
 258             jf.stream().forEach(e -> {
 259                 try {
 260                     ZipEntry entry = e.zipEntry();
 261                     String name = entry.getName();
 262                     int index = name.lastIndexOf("/");
 263                     if (index != -1) {
 264                         Path p = Paths.get(name.substring(0, index));
 265                         if (Files.notExists(p))
 266                             Files.createDirectories(p);
 267                     }
 268 
 269                     try (OutputStream os = Files.newOutputStream(Paths.get(name))) {
 270                         jf.getInputStream(e).transferTo(os);
 271                     }
 272                 } catch (IOException x) {
 273                     throw new UncheckedIOException(x);
 274                 }
 275             });
 276 
 277             return true;
 278         }
 279     }
 280 
 281     private boolean hashModules() {
 282         return new Hasher(options.moduleFinder).run();
 283     }
 284 
 285     private boolean describe() throws IOException {
 286         try (JmodFile jf = new JmodFile(options.jmodFile)) {
 287             try (InputStream in = jf.getInputStream(Section.CLASSES, MODULE_INFO)) {
 288                 ModuleDescriptor md = ModuleDescriptor.read(in);
 289                 printModuleDescriptor(md);
 290                 return true;
 291             } catch (IOException e) {
 292                 throw new CommandException("err.module.descriptor.not.found");
 293             }
 294         }
 295     }
 296 
 297     static <T> String toString(Collection<T> c) {
 298         if (c.isEmpty()) { return ""; }
 299         return c.stream().map(e -> e.toString().toLowerCase(Locale.ROOT))
 300                   .collect(joining(" "));


1171                 @Override
1172                 public List<?> defaultValues() { return Collections.emptyList(); }
1173                 @Override
1174                 public boolean isRequired() { return false; }
1175                 @Override
1176                 public boolean acceptsArguments() { return false; }
1177                 @Override
1178                 public boolean requiresArgument() { return false; }
1179                 @Override
1180                 public String argumentDescription() { return null; }
1181                 @Override
1182                 public String argumentTypeIndicator() { return null; }
1183                 @Override
1184                 public boolean representsNonOptions() { return false; }
1185             });
1186             String content = super.format(all);
1187             StringBuilder builder = new StringBuilder();
1188 
1189             builder.append(getMessage("main.opt.mode")).append("\n  ");
1190             builder.append(getMessage("main.opt.mode.create")).append("\n  ");
1191             builder.append(getMessage("main.opt.mode.extract")).append("\n  ");
1192             builder.append(getMessage("main.opt.mode.list")).append("\n  ");
1193             builder.append(getMessage("main.opt.mode.describe")).append("\n  ");
1194             builder.append(getMessage("main.opt.mode.hash")).append("\n\n");
1195 
1196             String cmdfile = null;
1197             String[] lines = content.split("\n");
1198             for (String line : lines) {
1199                 if (line.startsWith("--@")) {
1200                     cmdfile = line.replace("--" + CMD_FILENAME, CMD_FILENAME + "  ");
1201                 } else if (line.startsWith("Option") || line.startsWith("------")) {
1202                     builder.append(" ").append(line).append("\n");
1203                 } else if (!line.matches("Non-option arguments")){
1204                     builder.append("  ").append(line).append("\n");
1205                 }
1206             }
1207             if (cmdfile != null) {
1208                 builder.append("  ").append(cmdfile).append("\n");
1209             }
1210             return builder.toString();
1211         }