< prev index next >

src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java

Print this page

   1 /*
   2  * Copyright (c) 2015, 2024, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  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

 356             }
 357         } catch (IOException io) {
 358             log.println(taskHelper.getMessage("error.prefix") + " " + io.getMessage());
 359             if (DEBUG) {
 360                 io.printStackTrace(log);
 361             }
 362         }
 363     }
 364 
 365     /*
 366      * Jlink API entry point.
 367      */
 368     public static void createImage(JlinkConfiguration config,
 369                                    PluginsConfiguration plugins)
 370             throws Exception {
 371         Objects.requireNonNull(config);
 372         Objects.requireNonNull(config.getOutput());
 373         plugins = plugins == null ? new PluginsConfiguration() : plugins;
 374 
 375         // First create the image provider
 376         ImageProvider imageProvider =
 377                 createImageProvider(config,
 378                                     null,
 379                                     IGNORE_SIGNING_DEFAULT,
 380                                     false,
 381                                     null,
 382                                     false,
 383                                     new OptionsValues(),
 384                                     null);
 385 
 386         // Then create the Plugin Stack
 387         ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(plugins);
 388 
 389         //Ask the stack to proceed;
 390         stack.operate(imageProvider);

 391     }
 392 
 393     // the token for "all modules on the module path"
 394     private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
 395     private JlinkConfiguration initJlinkConfig() throws BadArgs {
 396         // Empty module path not allowed with ALL-MODULE-PATH in --add-modules
 397         if (options.addMods.contains(ALL_MODULE_PATH) && options.modulePath.isEmpty()) {
 398             throw taskHelper.newBadArgs("err.no.module.path");
 399         }
 400         ModuleFinder appModuleFinder = newModuleFinder(options.modulePath);
 401         ModuleFinder finder = appModuleFinder;
 402 
 403         boolean isLinkFromRuntime = false;
 404         if (!appModuleFinder.find("java.base").isPresent()) {
 405             // If the application module finder doesn't contain the
 406             // java.base module we have one of two cases:
 407             // 1. A custom module is being linked into a runtime, but the JDK
 408             //    modules have not been provided on the module path.
 409             // 2. We have a run-time image based link.
 410             //

 494 
 495     /*
 496      * Creates a ModuleFinder for the given module paths.
 497      */
 498     public static ModuleFinder newModuleFinder(List<Path> paths) {
 499         Runtime.Version version = Runtime.version();
 500         Path[] entries = paths.toArray(new Path[0]);
 501         return ModulePath.of(version, true, entries);
 502     }
 503 
 504     private void createImage(JlinkConfiguration config) throws Exception {
 505         if (options.output == null) {
 506             throw taskHelper.newBadArgs("err.output.must.be.specified").showUsage(true);
 507         }
 508         if (options.addMods.isEmpty()) {
 509             throw taskHelper.newBadArgs("err.mods.must.be.specified", "--add-modules")
 510                             .showUsage(true);
 511         }
 512 
 513         // First create the image provider
 514         ImageHelper imageProvider = createImageProvider(config,
 515                                                         options.packagedModulesPath,
 516                                                         options.ignoreSigning,
 517                                                         options.bindServices,
 518                                                         options.endian,
 519                                                         options.verbose,
 520                                                         options,
 521                                                         log);
 522 
 523         // Then create the Plugin Stack
 524         ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(
 525             taskHelper.getPluginsConfig(options.output, options.launchers,
 526                     imageProvider.targetPlatform));
 527 
 528         //Ask the stack to proceed
 529         stack.operate(imageProvider);


 530     }
 531 
 532     /**
 533      * @return the system module path or null
 534      */
 535     public static Path getDefaultModulePath() {
 536         Path jmods = Paths.get(System.getProperty("java.home"), "jmods");
 537         return Files.isDirectory(jmods)? jmods : null;
 538     }
 539 
 540     /*
 541      * Returns a module finder of the given module finder that limits the
 542      * observable modules to those in the transitive closure of the modules
 543      * specified in {@code limitMods} plus other modules specified in the
 544      * {@code roots} set.
 545      */
 546     public static ModuleFinder limitFinder(ModuleFinder finder,
 547                                            Set<String> limitMods,
 548                                            Set<String> roots) {
 549         // if limitMods is specified then limit the universe

1037             if (!names.isEmpty()) {
1038                 log.println(taskHelper.getMessage("warn.provider.notfound",
1039                     names.stream().sorted().collect(Collectors.joining(","))));
1040             }
1041 
1042             String msg = String.format("%n%s:", taskHelper.getMessage("suggested.providers.header"));
1043             printProviders(log, msg, mrefs, uses);
1044         }
1045     }
1046 
1047     private String getSaveOpts() {
1048         StringBuilder sb = new StringBuilder();
1049         sb.append('#').append(new Date()).append("\n");
1050         for (String c : optionsHelper.getInputCommand()) {
1051             sb.append(c).append(" ");
1052         }
1053 
1054         return sb.toString();
1055     }
1056 
1057     private static record ImageHelper(Set<Archive> archives,
1058                                       Platform targetPlatform,
1059                                       Path packagedModulesPath,
1060                                       boolean generateRuntimeImage) implements ImageProvider {

1061         @Override
1062         public ExecutableImage retrieve(ImagePluginStack stack) throws IOException {
1063             ExecutableImage image = ImageFileCreator.create(archives,
1064                     targetPlatform.arch().byteOrder(), stack, generateRuntimeImage);
1065             if (packagedModulesPath != null) {
1066                 // copy the packaged modules to the given path
1067                 Files.createDirectories(packagedModulesPath);
1068                 for (Archive a : archives) {
1069                     Path file = a.getPath();
1070                     Path dest = packagedModulesPath.resolve(file.getFileName());
1071                     Files.copy(file, dest);
1072                 }
1073             }
1074             return image;
1075         }




















1076     }
1077 }

   1 /*
   2  * Copyright (c) 2015, 2025, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  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

 356             }
 357         } catch (IOException io) {
 358             log.println(taskHelper.getMessage("error.prefix") + " " + io.getMessage());
 359             if (DEBUG) {
 360                 io.printStackTrace(log);
 361             }
 362         }
 363     }
 364 
 365     /*
 366      * Jlink API entry point.
 367      */
 368     public static void createImage(JlinkConfiguration config,
 369                                    PluginsConfiguration plugins)
 370             throws Exception {
 371         Objects.requireNonNull(config);
 372         Objects.requireNonNull(config.getOutput());
 373         plugins = plugins == null ? new PluginsConfiguration() : plugins;
 374 
 375         // First create the image provider
 376         try (ImageHelper imageProvider =
 377                      createImageProvider(config,
 378                              null,
 379                              IGNORE_SIGNING_DEFAULT,
 380                              false,
 381                              null,
 382                              false,
 383                              new OptionsValues(),
 384                              null)) {
 385 
 386             // Then create the Plugin Stack
 387             ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(plugins);
 388 
 389             // Ask the stack to proceed;
 390             stack.operate(imageProvider);
 391         }
 392     }
 393 
 394     // the token for "all modules on the module path"
 395     private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
 396     private JlinkConfiguration initJlinkConfig() throws BadArgs {
 397         // Empty module path not allowed with ALL-MODULE-PATH in --add-modules
 398         if (options.addMods.contains(ALL_MODULE_PATH) && options.modulePath.isEmpty()) {
 399             throw taskHelper.newBadArgs("err.no.module.path");
 400         }
 401         ModuleFinder appModuleFinder = newModuleFinder(options.modulePath);
 402         ModuleFinder finder = appModuleFinder;
 403 
 404         boolean isLinkFromRuntime = false;
 405         if (!appModuleFinder.find("java.base").isPresent()) {
 406             // If the application module finder doesn't contain the
 407             // java.base module we have one of two cases:
 408             // 1. A custom module is being linked into a runtime, but the JDK
 409             //    modules have not been provided on the module path.
 410             // 2. We have a run-time image based link.
 411             //

 495 
 496     /*
 497      * Creates a ModuleFinder for the given module paths.
 498      */
 499     public static ModuleFinder newModuleFinder(List<Path> paths) {
 500         Runtime.Version version = Runtime.version();
 501         Path[] entries = paths.toArray(new Path[0]);
 502         return ModulePath.of(version, true, entries);
 503     }
 504 
 505     private void createImage(JlinkConfiguration config) throws Exception {
 506         if (options.output == null) {
 507             throw taskHelper.newBadArgs("err.output.must.be.specified").showUsage(true);
 508         }
 509         if (options.addMods.isEmpty()) {
 510             throw taskHelper.newBadArgs("err.mods.must.be.specified", "--add-modules")
 511                             .showUsage(true);
 512         }
 513 
 514         // First create the image provider
 515         try (ImageHelper imageProvider = createImageProvider(config,
 516                 options.packagedModulesPath,
 517                 options.ignoreSigning,
 518                 options.bindServices,
 519                 options.endian,
 520                 options.verbose,
 521                 options,
 522                 log)) {
 523             // Then create the Plugin Stack
 524             ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(
 525                     taskHelper.getPluginsConfig(
 526                             options.output,
 527                             options.launchers,
 528                             imageProvider.targetPlatform));
 529 
 530             //Ask the stack to proceed
 531             stack.operate(imageProvider);
 532         }
 533     }
 534 
 535     /**
 536      * @return the system module path or null
 537      */
 538     public static Path getDefaultModulePath() {
 539         Path jmods = Paths.get(System.getProperty("java.home"), "jmods");
 540         return Files.isDirectory(jmods)? jmods : null;
 541     }
 542 
 543     /*
 544      * Returns a module finder of the given module finder that limits the
 545      * observable modules to those in the transitive closure of the modules
 546      * specified in {@code limitMods} plus other modules specified in the
 547      * {@code roots} set.
 548      */
 549     public static ModuleFinder limitFinder(ModuleFinder finder,
 550                                            Set<String> limitMods,
 551                                            Set<String> roots) {
 552         // if limitMods is specified then limit the universe

1040             if (!names.isEmpty()) {
1041                 log.println(taskHelper.getMessage("warn.provider.notfound",
1042                     names.stream().sorted().collect(Collectors.joining(","))));
1043             }
1044 
1045             String msg = String.format("%n%s:", taskHelper.getMessage("suggested.providers.header"));
1046             printProviders(log, msg, mrefs, uses);
1047         }
1048     }
1049 
1050     private String getSaveOpts() {
1051         StringBuilder sb = new StringBuilder();
1052         sb.append('#').append(new Date()).append("\n");
1053         for (String c : optionsHelper.getInputCommand()) {
1054             sb.append(c).append(" ");
1055         }
1056 
1057         return sb.toString();
1058     }
1059 
1060     private record ImageHelper(Set<Archive> archives,
1061                                Platform targetPlatform,
1062                                Path packagedModulesPath,
1063                                boolean generateRuntimeImage)
1064             implements ImageProvider, AutoCloseable {
1065         @Override
1066         public ExecutableImage retrieve(ImagePluginStack stack) throws IOException {
1067             ExecutableImage image = ImageFileCreator.create(archives,
1068                     targetPlatform.arch().byteOrder(), stack, generateRuntimeImage);
1069             if (packagedModulesPath != null) {
1070                 // copy the packaged modules to the given path
1071                 Files.createDirectories(packagedModulesPath);
1072                 for (Archive a : archives) {
1073                     Path file = a.getPath();
1074                     Path dest = packagedModulesPath.resolve(file.getFileName());
1075                     Files.copy(file, dest);
1076                 }
1077             }
1078             return image;
1079         }
1080 
1081         @Override
1082         public void close() throws IOException {
1083             List<IOException> thrown = null;
1084             for (Archive archive : archives) {
1085                 try {
1086                     archive.close();
1087                 } catch (IOException ex) {
1088                     if (thrown == null) {
1089                         thrown = new ArrayList<>();
1090                     }
1091                     thrown.add(ex);
1092                 }
1093             }
1094             if (thrown != null) {
1095                 IOException ex = new IOException("Archives could not be closed", thrown.getFirst());
1096                 thrown.subList(1, thrown.size()).forEach(ex::addSuppressed);
1097                 throw ex;
1098             }
1099         }
1100     }
1101 }
< prev index next >