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 package jdk.tools.jlink;
26
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.io.FileNotFoundException;
30 import java.io.IOException;
31 import java.io.PrintWriter;
32 import java.lang.module.Configuration;
33 import java.lang.module.ModuleFinder;
34 import java.lang.reflect.Layer;
35 import java.nio.file.Path;
36 import java.nio.file.Paths;
37 import java.text.MessageFormat;
38 import java.util.ArrayList;
39 import java.util.HashMap;
40 import java.util.List;
41 import java.util.Locale;
42 import java.util.Map;
43 import java.util.Map.Entry;
44 import java.util.MissingResourceException;
45 import java.util.Properties;
46 import java.util.ResourceBundle;
47
48 import jdk.internal.module.ConfigurableModuleFinder;
49 import jdk.internal.module.ConfigurableModuleFinder.Phase;
50 import jdk.tools.jlink.internal.ImagePluginProviderRepository;
51 import jdk.tools.jlink.internal.ImagePluginConfiguration;
52 import jdk.tools.jlink.plugins.CmdPluginProvider;
53 import jdk.tools.jlink.plugins.CmdResourcePluginProvider;
54 import jdk.tools.jlink.plugins.ImageBuilderProvider;
55 import jdk.tools.jlink.plugins.OnOffImageFilePluginProvider;
56 import jdk.tools.jlink.plugins.OnOffResourcePluginProvider;
57 import jdk.tools.jlink.plugins.PluginProvider;
58
59 /**
60 *
61 * JLink and JImage tools shared helper.
62 */
63 public final class TaskHelper {
64
65 public static final String JLINK_BUNDLE = "jdk.tools.jlink.resources.jlink";
66 public static final String JIMAGE_BUNDLE = "jdk.tools.jimage.resources.jimage";
268 }
269 }
270 }
271
272 private PluginOption getOption(String name) throws BadArgs {
273 for (PluginOption o : pluginsOptions) {
274 if (o.matches(name)) {
275 return o;
276 }
277 }
278 return null;
279 }
280
281 private Properties getPluginsProperties() throws IOException {
282 Properties props = new Properties();
283 if (pluginsProperties != null) {
284 try (FileInputStream stream
285 = new FileInputStream(pluginsProperties);) {
286 props.load(stream);
287 } catch (FileNotFoundException ex) {
288 throw new IOException(bundleHelper.
289 getMessage("err.path.not.valid")
290 + " " + pluginsProperties);
291 }
292 }
293 for (Entry<PluginProvider, Map<String, String>> entry : plugins.entrySet()) {
294 PluginProvider provider = entry.getKey();
295 ImagePluginConfiguration.addPluginProperty(props, provider);
296 if (entry.getValue() != null) {
297 for (Entry<String, String> opts : entry.getValue().entrySet()) {
298 if (opts.getValue() != null) {
299 props.setProperty(provider.getName() + "."
300 + opts.getKey(), opts.getValue());
301 }
302 }
303 }
304 }
305 for (Entry<ImageBuilderProvider, Map<String, String>> provs : builders.entrySet()) {
306 ImageBuilderProvider provider = provs.getKey();
307 for (Entry<String, String> entry : provs.getValue().entrySet()) {
308 props.setProperty(provider.getName() + "."
309 + entry.getKey(), entry.getValue() == null ? ""
310 : entry.getValue());
571 line.append("\n ").append(provider.getDescription());
572 if (provider.getAdditionalOptions() != null) {
573 line.append("\n").append(bundleHelper.
574 getMessage("main.plugin.additional.options")).
575 append(": ");
576 for (Entry<String, String> entry : provider.getAdditionalOptions().entrySet()) {
577 line.append(" --").append(entry.getKey()).append(" ").
578 append(entry.getValue());
579 }
580 }
581 log.println(line.toString() + "\n");
582 }
583 }
584 }
585 if (showsImageBuilder) {
586 log.println(bundleHelper.getMessage("main.image.builders"));
587 for (ImageBuilderProvider prov
588 : ImagePluginProviderRepository.getImageBuilderProviders(getPluginsLayer())) {
589 log.println("\n" + bundleHelper.getMessage("main.image.builder.name")
590 + ": " + prov.getName());
591 logBuilderOptions(prov.getOptions());
592 }
593 }
594 }
595
596 public void showPlugins(PrintWriter log, boolean showsImageBuilder) {
597 for (PluginProvider prov : ImagePluginProviderRepository.getPluginProviders(getPluginsLayer())) {
598 if (showsPlugin(prov, showsImageBuilder)) {
599 CmdPluginProvider fact = (CmdPluginProvider) prov;
600 log.println("\n" + bundleHelper.getMessage("main.plugin.name")
601 + ": " + fact.getName());
602 Integer[] range = ImagePluginConfiguration.getRange(fact);
603 String cat = range == null ? fact.getCategory() : fact.getCategory()
604 + ". " + bundleHelper.getMessage("main.plugin.range.from")
605 + " " + range[0] + " " + bundleHelper.
606 getMessage("main.plugin.range.to") + " "
607 + range[1] + ".";
608 log.println(bundleHelper.getMessage("main.plugin.category")
609 + ": " + cat);
610 log.println(bundleHelper.getMessage("main.plugin.description")
658 String[] getExpandedCommand() {
659 return expandedCommand;
660 }
661
662 String[] getInputCommand() {
663 return command;
664 }
665
666 String getDefaults() {
667 return defaults;
668 }
669
670 String getPluginsConfig() throws IOException {
671 String ret = null;
672 if (pluginOptions.pluginsProperties != null) {
673 Properties props = new Properties();
674 try (FileInputStream fis
675 = new FileInputStream(pluginOptions.pluginsProperties)) {
676 props.load(fis);
677 } catch (FileNotFoundException ex) {
678 throw new IOException(bundleHelper.
679 getMessage("err.path.not.valid")
680 + " " + pluginOptions.pluginsProperties);
681 }
682 StringBuilder sb = new StringBuilder();
683 for (String str : props.stringPropertyNames()) {
684 sb.append(str).append(" = ").append(props.getProperty(str)).
685 append("\n");
686 }
687 ret = sb.toString();
688 }
689 return ret;
690 }
691
692 Layer getPluginsLayer() {
693 return pluginOptions.pluginsLayer;
694 }
695 }
696
697 private PluginsOptions pluginOptions;
698 private PrintWriter log;
699 private final ResourceBundleHelper bundleHelper;
700
772 remaining = "";
773 } else {
774 String option = defaults.substring(start, end);
775 arguments.add(option);
776 defaults = defaults.substring(end);
777 int nextOption = defaults.indexOf("--");
778 int argEnd = nextOption < 0 ? defaults.length() : nextOption;
779 String arg = defaults.substring(0, argEnd);
780 arg = arg.replaceAll(" ", "");
781 if (!arg.isEmpty()) {
782 arguments.add(arg);
783 }
784 remaining = defaults.substring(argEnd);
785 }
786
787 defaults = remaining;
788 }
789 return arguments;
790 }
791
792 static Layer createPluginsLayer(Path[] paths) {
793 ModuleFinder finder = ModuleFinder.of(paths);
794
795 // jmods are located at link-time
796 if (finder instanceof ConfigurableModuleFinder)
797 ((ConfigurableModuleFinder)finder).configurePhase(Phase.LINK_TIME);
798
799 Configuration cf
800 = Configuration.resolve(ModuleFinder.empty(), Layer.boot(), finder);
801 cf = cf.bind();
802 // The creation of this classloader is done outside privileged block in purpose
803 // If a security manager is set, then permission must be granted to jlink
804 // codebase to create a classloader. This is the expected behavior.
805 ClassLoader cl = new ModuleClassLoader(cf);
806 return Layer.create(cf, mn -> cl);
807 }
808
809 // Display all plugins or resource only.
810 private static boolean showsPlugin(PluginProvider prov, boolean showsImageBuilder) {
811 return (prov instanceof CmdPluginProvider && showsImageBuilder)
812 || (prov instanceof CmdResourcePluginProvider);
813 }
814 }
|
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 package jdk.tools.jlink;
26
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.io.FileNotFoundException;
30 import java.io.IOException;
31 import java.io.PrintWriter;
32 import java.lang.module.Configuration;
33 import java.lang.module.ModuleDescriptor;
34 import java.lang.module.ModuleFinder;
35 import java.lang.module.ModuleReference;
36 import java.lang.module.ResolutionException;
37 import java.lang.reflect.Layer;
38 import java.nio.file.Path;
39 import java.nio.file.Paths;
40 import java.text.MessageFormat;
41 import java.util.ArrayList;
42 import java.util.HashMap;
43 import java.util.List;
44 import java.util.Locale;
45 import java.util.Map;
46 import java.util.Map.Entry;
47 import java.util.MissingResourceException;
48 import java.util.Properties;
49 import java.util.ResourceBundle;
50 import java.util.Set;
51
52 import jdk.internal.module.ConfigurableModuleFinder;
53 import jdk.internal.module.ConfigurableModuleFinder.Phase;
54 import jdk.tools.jlink.internal.ImagePluginProviderRepository;
55 import jdk.tools.jlink.internal.ImagePluginConfiguration;
56 import jdk.tools.jlink.plugins.CmdPluginProvider;
57 import jdk.tools.jlink.plugins.CmdResourcePluginProvider;
58 import jdk.tools.jlink.plugins.ImageBuilderProvider;
59 import jdk.tools.jlink.plugins.OnOffImageFilePluginProvider;
60 import jdk.tools.jlink.plugins.OnOffResourcePluginProvider;
61 import jdk.tools.jlink.plugins.PluginProvider;
62
63 /**
64 *
65 * JLink and JImage tools shared helper.
66 */
67 public final class TaskHelper {
68
69 public static final String JLINK_BUNDLE = "jdk.tools.jlink.resources.jlink";
70 public static final String JIMAGE_BUNDLE = "jdk.tools.jimage.resources.jimage";
272 }
273 }
274 }
275
276 private PluginOption getOption(String name) throws BadArgs {
277 for (PluginOption o : pluginsOptions) {
278 if (o.matches(name)) {
279 return o;
280 }
281 }
282 return null;
283 }
284
285 private Properties getPluginsProperties() throws IOException {
286 Properties props = new Properties();
287 if (pluginsProperties != null) {
288 try (FileInputStream stream
289 = new FileInputStream(pluginsProperties);) {
290 props.load(stream);
291 } catch (FileNotFoundException ex) {
292 throw new IOException(bundleHelper.getMessage("err.path.not.valid", pluginsProperties));
293 }
294 }
295 for (Entry<PluginProvider, Map<String, String>> entry : plugins.entrySet()) {
296 PluginProvider provider = entry.getKey();
297 ImagePluginConfiguration.addPluginProperty(props, provider);
298 if (entry.getValue() != null) {
299 for (Entry<String, String> opts : entry.getValue().entrySet()) {
300 if (opts.getValue() != null) {
301 props.setProperty(provider.getName() + "."
302 + opts.getKey(), opts.getValue());
303 }
304 }
305 }
306 }
307 for (Entry<ImageBuilderProvider, Map<String, String>> provs : builders.entrySet()) {
308 ImageBuilderProvider provider = provs.getKey();
309 for (Entry<String, String> entry : provs.getValue().entrySet()) {
310 props.setProperty(provider.getName() + "."
311 + entry.getKey(), entry.getValue() == null ? ""
312 : entry.getValue());
573 line.append("\n ").append(provider.getDescription());
574 if (provider.getAdditionalOptions() != null) {
575 line.append("\n").append(bundleHelper.
576 getMessage("main.plugin.additional.options")).
577 append(": ");
578 for (Entry<String, String> entry : provider.getAdditionalOptions().entrySet()) {
579 line.append(" --").append(entry.getKey()).append(" ").
580 append(entry.getValue());
581 }
582 }
583 log.println(line.toString() + "\n");
584 }
585 }
586 }
587 if (showsImageBuilder) {
588 log.println(bundleHelper.getMessage("main.image.builders"));
589 for (ImageBuilderProvider prov
590 : ImagePluginProviderRepository.getImageBuilderProviders(getPluginsLayer())) {
591 log.println("\n" + bundleHelper.getMessage("main.image.builder.name")
592 + ": " + prov.getName());
593 log.println(bundleHelper.getMessage("main.image.builder.description")
594 + ": " + prov.getDescription());
595 logBuilderOptions(prov.getOptions());
596 }
597 }
598 }
599
600 public void showPlugins(PrintWriter log, boolean showsImageBuilder) {
601 for (PluginProvider prov : ImagePluginProviderRepository.getPluginProviders(getPluginsLayer())) {
602 if (showsPlugin(prov, showsImageBuilder)) {
603 CmdPluginProvider fact = (CmdPluginProvider) prov;
604 log.println("\n" + bundleHelper.getMessage("main.plugin.name")
605 + ": " + fact.getName());
606 Integer[] range = ImagePluginConfiguration.getRange(fact);
607 String cat = range == null ? fact.getCategory() : fact.getCategory()
608 + ". " + bundleHelper.getMessage("main.plugin.range.from")
609 + " " + range[0] + " " + bundleHelper.
610 getMessage("main.plugin.range.to") + " "
611 + range[1] + ".";
612 log.println(bundleHelper.getMessage("main.plugin.category")
613 + ": " + cat);
614 log.println(bundleHelper.getMessage("main.plugin.description")
662 String[] getExpandedCommand() {
663 return expandedCommand;
664 }
665
666 String[] getInputCommand() {
667 return command;
668 }
669
670 String getDefaults() {
671 return defaults;
672 }
673
674 String getPluginsConfig() throws IOException {
675 String ret = null;
676 if (pluginOptions.pluginsProperties != null) {
677 Properties props = new Properties();
678 try (FileInputStream fis
679 = new FileInputStream(pluginOptions.pluginsProperties)) {
680 props.load(fis);
681 } catch (FileNotFoundException ex) {
682 throw new IOException(bundleHelper.getMessage("err.path.not.valid",
683 pluginOptions.pluginsProperties));
684 }
685 StringBuilder sb = new StringBuilder();
686 for (String str : props.stringPropertyNames()) {
687 sb.append(str).append(" = ").append(props.getProperty(str)).
688 append("\n");
689 }
690 ret = sb.toString();
691 }
692 return ret;
693 }
694
695 Layer getPluginsLayer() {
696 return pluginOptions.pluginsLayer;
697 }
698 }
699
700 private PluginsOptions pluginOptions;
701 private PrintWriter log;
702 private final ResourceBundleHelper bundleHelper;
703
775 remaining = "";
776 } else {
777 String option = defaults.substring(start, end);
778 arguments.add(option);
779 defaults = defaults.substring(end);
780 int nextOption = defaults.indexOf("--");
781 int argEnd = nextOption < 0 ? defaults.length() : nextOption;
782 String arg = defaults.substring(0, argEnd);
783 arg = arg.replaceAll(" ", "");
784 if (!arg.isEmpty()) {
785 arguments.add(arg);
786 }
787 remaining = defaults.substring(argEnd);
788 }
789
790 defaults = remaining;
791 }
792 return arguments;
793 }
794
795 private static void checkExportedPackages(Set<ModuleReference> modules) {
796 Map<String, ModuleReference> packageToModule = new HashMap<>();
797 for (ModuleReference module : modules) {
798 for (String pack: module.descriptor().packages()) {
799 ModuleReference other = packageToModule.putIfAbsent(pack, module);
800 if (other != null) {
801 String module1 = module.descriptor().name();
802 String module2 = other.descriptor().name();
803 throw new ResolutionException("Modules "
804 + module1 + " and " + module2 + " both contain package " + pack);
805 }
806 }
807 }
808 }
809
810 static Layer createPluginsLayer(Path[] paths) {
811 ModuleFinder finder = ModuleFinder.of(paths);
812
813 // jmods are located at link-time
814 if (finder instanceof ConfigurableModuleFinder)
815 ((ConfigurableModuleFinder)finder).configurePhase(Phase.LINK_TIME);
816
817 Configuration cf
818 = Configuration.resolve(ModuleFinder.empty(), Layer.boot(), finder);
819 cf = cf.bind();
820 checkExportedPackages(cf.modules());
821 // The creation of this classloader is done outside privileged block in purpose
822 // If a security manager is set, then permission must be granted to jlink
823 // codebase to create a classloader. This is the expected behavior.
824 ClassLoader cl = new ModuleClassLoader(cf);
825 return Layer.create(cf, mn -> cl);
826 }
827
828 // Display all plugins or resource only.
829 private static boolean showsPlugin(PluginProvider prov, boolean showsImageBuilder) {
830 return (prov instanceof CmdPluginProvider && showsImageBuilder)
831 || (prov instanceof CmdResourcePluginProvider);
832 }
833 }
|