< 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

 332             }
 333         } catch (IOException io) {
 334             log.println(taskHelper.getMessage("error.prefix") + " " + io.getMessage());
 335             if (DEBUG) {
 336                 io.printStackTrace(log);
 337             }
 338         }
 339     }
 340 
 341     /*
 342      * Jlink API entry point.
 343      */
 344     public static void createImage(JlinkConfiguration config,
 345                                    PluginsConfiguration plugins)
 346             throws Exception {
 347         Objects.requireNonNull(config);
 348         Objects.requireNonNull(config.getOutput());
 349         plugins = plugins == null ? new PluginsConfiguration() : plugins;
 350 
 351         // First create the image provider
 352         ImageProvider imageProvider =
 353                 createImageProvider(config,
 354                                     null,
 355                                     IGNORE_SIGNING_DEFAULT,
 356                                     false,
 357                                     null,
 358                                     false,
 359                                     new OptionsValues(),
 360                                     null);
 361 
 362         // Then create the Plugin Stack
 363         ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(plugins);
 364 
 365         //Ask the stack to proceed;
 366         stack.operate(imageProvider);

 367     }
 368 
 369     // the token for "all modules on the module path"
 370     private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
 371     private JlinkConfiguration initJlinkConfig() throws BadArgs {
 372         // Empty module path not allowed with ALL-MODULE-PATH in --add-modules
 373         if (options.addMods.contains(ALL_MODULE_PATH) && options.modulePath.isEmpty()) {
 374             throw taskHelper.newBadArgs("err.no.module.path");
 375         }
 376         ModuleFinder appModuleFinder = newModuleFinder(options.modulePath);
 377         ModuleFinder finder = appModuleFinder;
 378 
 379         boolean isLinkFromRuntime = false;
 380         if (!appModuleFinder.find("java.base").isPresent()) {
 381             // If the application module finder doesn't contain the
 382             // java.base module we have one of two cases:
 383             // 1. A custom module is being linked into a runtime, but the JDK
 384             //    modules have not been provided on the module path.
 385             // 2. We have a run-time image based link.
 386             //

 469 
 470     /*
 471      * Creates a ModuleFinder for the given module paths.
 472      */
 473     public static ModuleFinder newModuleFinder(List<Path> paths) {
 474         Runtime.Version version = Runtime.version();
 475         Path[] entries = paths.toArray(new Path[0]);
 476         return ModulePath.of(version, true, entries);
 477     }
 478 
 479     private void createImage(JlinkConfiguration config) throws Exception {
 480         if (options.output == null) {
 481             throw taskHelper.newBadArgs("err.output.must.be.specified").showUsage(true);
 482         }
 483         if (options.addMods.isEmpty()) {
 484             throw taskHelper.newBadArgs("err.mods.must.be.specified", "--add-modules")
 485                             .showUsage(true);
 486         }
 487 
 488         // First create the image provider
 489         ImageHelper imageProvider = createImageProvider(config,
 490                                                         options.packagedModulesPath,
 491                                                         options.ignoreSigning,
 492                                                         options.bindServices,
 493                                                         options.endian,
 494                                                         options.verbose,
 495                                                         options,
 496                                                         log);
 497 
 498         // Then create the Plugin Stack
 499         ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(
 500             taskHelper.getPluginsConfig(options.output, options.launchers,
 501                     imageProvider.targetPlatform));
 502 
 503         //Ask the stack to proceed
 504         stack.operate(imageProvider);


 505     }
 506 
 507     /**
 508      * @return the system module path or null
 509      */
 510     public static Path getDefaultModulePath() {
 511         Path jmods = Paths.get(System.getProperty("java.home"), "jmods");
 512         return Files.isDirectory(jmods)? jmods : null;
 513     }
 514 
 515     /*
 516      * Returns a module finder of the given module finder that limits the
 517      * observable modules to those in the transitive closure of the modules
 518      * specified in {@code limitMods} plus other modules specified in the
 519      * {@code roots} set.
 520      */
 521     public static ModuleFinder limitFinder(ModuleFinder finder,
 522                                            Set<String> limitMods,
 523                                            Set<String> roots) {
 524         // if limitMods is specified then limit the universe

1010             if (!names.isEmpty()) {
1011                 log.println(taskHelper.getMessage("warn.provider.notfound",
1012                     names.stream().sorted().collect(Collectors.joining(","))));
1013             }
1014 
1015             String msg = String.format("%n%s:", taskHelper.getMessage("suggested.providers.header"));
1016             printProviders(log, msg, mrefs, uses);
1017         }
1018     }
1019 
1020     private String getSaveOpts() {
1021         StringBuilder sb = new StringBuilder();
1022         sb.append('#').append(new Date()).append("\n");
1023         for (String c : optionsHelper.getInputCommand()) {
1024             sb.append(c).append(" ");
1025         }
1026 
1027         return sb.toString();
1028     }
1029 
1030     private static record ImageHelper(Set<Archive> archives,
1031                                       Platform targetPlatform,
1032                                       Path packagedModulesPath,
1033                                       boolean generateRuntimeImage) implements ImageProvider {

1034         @Override
1035         public ExecutableImage retrieve(ImagePluginStack stack) throws IOException {
1036             ExecutableImage image = ImageFileCreator.create(archives,
1037                     targetPlatform.arch().byteOrder(), stack, generateRuntimeImage);
1038             if (packagedModulesPath != null) {
1039                 // copy the packaged modules to the given path
1040                 Files.createDirectories(packagedModulesPath);
1041                 for (Archive a : archives) {
1042                     Path file = a.getPath();
1043                     Path dest = packagedModulesPath.resolve(file.getFileName());
1044                     Files.copy(file, dest);
1045                 }
1046             }
1047             return image;
1048         }




















1049     }
1050 }

   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

 332             }
 333         } catch (IOException io) {
 334             log.println(taskHelper.getMessage("error.prefix") + " " + io.getMessage());
 335             if (DEBUG) {
 336                 io.printStackTrace(log);
 337             }
 338         }
 339     }
 340 
 341     /*
 342      * Jlink API entry point.
 343      */
 344     public static void createImage(JlinkConfiguration config,
 345                                    PluginsConfiguration plugins)
 346             throws Exception {
 347         Objects.requireNonNull(config);
 348         Objects.requireNonNull(config.getOutput());
 349         plugins = plugins == null ? new PluginsConfiguration() : plugins;
 350 
 351         // First create the image provider
 352         try (ImageHelper imageProvider =
 353                      createImageProvider(config,
 354                              null,
 355                              IGNORE_SIGNING_DEFAULT,
 356                              false,
 357                              null,
 358                              false,
 359                              new OptionsValues(),
 360                              null)) {
 361 
 362             // Then create the Plugin Stack
 363             ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(plugins);
 364 
 365             // Ask the stack to proceed;
 366             stack.operate(imageProvider);
 367         }
 368     }
 369 
 370     // the token for "all modules on the module path"
 371     private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
 372     private JlinkConfiguration initJlinkConfig() throws BadArgs {
 373         // Empty module path not allowed with ALL-MODULE-PATH in --add-modules
 374         if (options.addMods.contains(ALL_MODULE_PATH) && options.modulePath.isEmpty()) {
 375             throw taskHelper.newBadArgs("err.no.module.path");
 376         }
 377         ModuleFinder appModuleFinder = newModuleFinder(options.modulePath);
 378         ModuleFinder finder = appModuleFinder;
 379 
 380         boolean isLinkFromRuntime = false;
 381         if (!appModuleFinder.find("java.base").isPresent()) {
 382             // If the application module finder doesn't contain the
 383             // java.base module we have one of two cases:
 384             // 1. A custom module is being linked into a runtime, but the JDK
 385             //    modules have not been provided on the module path.
 386             // 2. We have a run-time image based link.
 387             //

 470 
 471     /*
 472      * Creates a ModuleFinder for the given module paths.
 473      */
 474     public static ModuleFinder newModuleFinder(List<Path> paths) {
 475         Runtime.Version version = Runtime.version();
 476         Path[] entries = paths.toArray(new Path[0]);
 477         return ModulePath.of(version, true, entries);
 478     }
 479 
 480     private void createImage(JlinkConfiguration config) throws Exception {
 481         if (options.output == null) {
 482             throw taskHelper.newBadArgs("err.output.must.be.specified").showUsage(true);
 483         }
 484         if (options.addMods.isEmpty()) {
 485             throw taskHelper.newBadArgs("err.mods.must.be.specified", "--add-modules")
 486                             .showUsage(true);
 487         }
 488 
 489         // First create the image provider
 490         try (ImageHelper imageProvider = createImageProvider(config,
 491                 options.packagedModulesPath,
 492                 options.ignoreSigning,
 493                 options.bindServices,
 494                 options.endian,
 495                 options.verbose,
 496                 options,
 497                 log)) {
 498             // Then create the Plugin Stack
 499             ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(
 500                     taskHelper.getPluginsConfig(
 501                             options.output,
 502                             options.launchers,
 503                             imageProvider.targetPlatform));
 504 
 505             //Ask the stack to proceed
 506             stack.operate(imageProvider);
 507         }
 508     }
 509 
 510     /**
 511      * @return the system module path or null
 512      */
 513     public static Path getDefaultModulePath() {
 514         Path jmods = Paths.get(System.getProperty("java.home"), "jmods");
 515         return Files.isDirectory(jmods)? jmods : null;
 516     }
 517 
 518     /*
 519      * Returns a module finder of the given module finder that limits the
 520      * observable modules to those in the transitive closure of the modules
 521      * specified in {@code limitMods} plus other modules specified in the
 522      * {@code roots} set.
 523      */
 524     public static ModuleFinder limitFinder(ModuleFinder finder,
 525                                            Set<String> limitMods,
 526                                            Set<String> roots) {
 527         // if limitMods is specified then limit the universe

1013             if (!names.isEmpty()) {
1014                 log.println(taskHelper.getMessage("warn.provider.notfound",
1015                     names.stream().sorted().collect(Collectors.joining(","))));
1016             }
1017 
1018             String msg = String.format("%n%s:", taskHelper.getMessage("suggested.providers.header"));
1019             printProviders(log, msg, mrefs, uses);
1020         }
1021     }
1022 
1023     private String getSaveOpts() {
1024         StringBuilder sb = new StringBuilder();
1025         sb.append('#').append(new Date()).append("\n");
1026         for (String c : optionsHelper.getInputCommand()) {
1027             sb.append(c).append(" ");
1028         }
1029 
1030         return sb.toString();
1031     }
1032 
1033     private record ImageHelper(Set<Archive> archives,
1034                                Platform targetPlatform,
1035                                Path packagedModulesPath,
1036                                boolean generateRuntimeImage)
1037             implements ImageProvider, AutoCloseable {
1038         @Override
1039         public ExecutableImage retrieve(ImagePluginStack stack) throws IOException {
1040             ExecutableImage image = ImageFileCreator.create(archives,
1041                     targetPlatform.arch().byteOrder(), stack, generateRuntimeImage);
1042             if (packagedModulesPath != null) {
1043                 // copy the packaged modules to the given path
1044                 Files.createDirectories(packagedModulesPath);
1045                 for (Archive a : archives) {
1046                     Path file = a.getPath();
1047                     Path dest = packagedModulesPath.resolve(file.getFileName());
1048                     Files.copy(file, dest);
1049                 }
1050             }
1051             return image;
1052         }
1053 
1054         @Override
1055         public void close() throws IOException {
1056             List<IOException> thrown = null;
1057             for (Archive archive : archives) {
1058                 try {
1059                     archive.close();
1060                 } catch (IOException ex) {
1061                     if (thrown == null) {
1062                         thrown = new ArrayList<>();
1063                     }
1064                     thrown.add(ex);
1065                 }
1066             }
1067             if (thrown != null) {
1068                 IOException ex = new IOException("Archives could not be closed", thrown.getFirst());
1069                 thrown.subList(1, thrown.size()).forEach(ex::addSuppressed);
1070                 throw ex;
1071             }
1072         }
1073     }
1074 }
< prev index next >