/*
 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package jdk.tools.jlink.internal;

import java.lang.module.Configuration;
import java.lang.module.ModuleFinder;
import java.nio.ByteOrder;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import jdk.internal.module.ModulePath;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.builder.ImageBuilder;

API to call jlink.
/** * API to call jlink. */
public final class Jlink {
Create a plugin.
Params:
  • name – Plugin name
  • configuration – Plugin configuration.
  • pluginsLayer – Plugins Layer. null means boot layer.
Returns:A new plugin or null if plugin is unknown.
/** * Create a plugin. * * @param name Plugin name * @param configuration Plugin configuration. * @param pluginsLayer Plugins Layer. null means boot layer. * @return A new plugin or null if plugin is unknown. */
public static Plugin newPlugin(String name, Map<String, String> configuration, ModuleLayer pluginsLayer) { Objects.requireNonNull(name); Objects.requireNonNull(configuration); pluginsLayer = pluginsLayer == null ? ModuleLayer.boot() : pluginsLayer; return PluginRepository.newPlugin(configuration, name, pluginsLayer); }
A complete plugin configuration. Instances of this class are used to configure jlink.
/** * A complete plugin configuration. Instances of this class are used to * configure jlink. */
public static final class PluginsConfiguration { private final List<Plugin> plugins; private final ImageBuilder imageBuilder; private final String lastSorterPluginName;
Empty plugins configuration.
/** * Empty plugins configuration. */
public PluginsConfiguration() { this(Collections.emptyList()); }
Plugins configuration.
Params:
  • plugins – List of plugins.
/** * Plugins configuration. * * @param plugins List of plugins. */
public PluginsConfiguration(List<Plugin> plugins) { this(plugins, null, null); }
Plugins configuration with a last sorter and an ImageBuilder. No sorting can occur after the last sorter plugin. The ImageBuilder is in charge to layout the image content on disk.
Params:
  • plugins – List of transformer plugins.
  • imageBuilder – Image builder.
  • lastSorterPluginName – Name of last sorter plugin, no sorting can occur after it.
/** * Plugins configuration with a last sorter and an ImageBuilder. No * sorting can occur after the last sorter plugin. The ImageBuilder is * in charge to layout the image content on disk. * * @param plugins List of transformer plugins. * @param imageBuilder Image builder. * @param lastSorterPluginName Name of last sorter plugin, no sorting * can occur after it. */
public PluginsConfiguration(List<Plugin> plugins, ImageBuilder imageBuilder, String lastSorterPluginName) { this.plugins = plugins == null ? Collections.emptyList() : plugins; this.imageBuilder = imageBuilder; this.lastSorterPluginName = lastSorterPluginName; }
Returns:the plugins
/** * @return the plugins */
public List<Plugin> getPlugins() { return plugins; }
Returns:the imageBuilder
/** * @return the imageBuilder */
public ImageBuilder getImageBuilder() { return imageBuilder; }
Returns:the lastSorterPluginName
/** * @return the lastSorterPluginName */
public String getLastSorterPluginName() { return lastSorterPluginName; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("imagebuilder=").append(imageBuilder).append("\n"); StringBuilder pluginsBuilder = new StringBuilder(); for (Plugin p : plugins) { pluginsBuilder.append(p).append(","); } builder.append("plugins=").append(pluginsBuilder).append("\n"); builder.append("lastsorter=").append(lastSorterPluginName).append("\n"); return builder.toString(); } }
Jlink configuration. Instances of this class are used to configure jlink.
/** * Jlink configuration. Instances of this class are used to configure jlink. */
public static final class JlinkConfiguration { private final List<Path> modulepaths; private final Path output; private final Set<String> modules; private final Set<String> limitmods; private final ByteOrder endian; private final ModuleFinder finder;
jlink configuration,
Params:
  • output – Output directory, must not exist.
  • modulepaths – Modules paths
  • modules – The possibly-empty set of root modules to resolve
  • limitmods – Limit the universe of observable modules
  • endian – Jimage byte order. Native order by default
/** * jlink configuration, * * @param output Output directory, must not exist. * @param modulepaths Modules paths * @param modules The possibly-empty set of root modules to resolve * @param limitmods Limit the universe of observable modules * @param endian Jimage byte order. Native order by default */
public JlinkConfiguration(Path output, List<Path> modulepaths, Set<String> modules, Set<String> limitmods, ByteOrder endian) { if (Objects.requireNonNull(modulepaths).isEmpty()) { throw new IllegalArgumentException("Empty module path"); } this.output = output; this.modulepaths = modulepaths; this.modules = Objects.requireNonNull(modules); this.limitmods = Objects.requireNonNull(limitmods); this.endian = Objects.requireNonNull(endian); this.finder = moduleFinder(); }
Returns:the modulepaths
/** * @return the modulepaths */
public List<Path> getModulepaths() { return modulepaths; }
Returns:the byte ordering
/** * @return the byte ordering */
public ByteOrder getByteOrder() { return endian; }
Returns:the output
/** * @return the output */
public Path getOutput() { return output; }
Returns:the modules
/** * @return the modules */
public Set<String> getModules() { return modules; }
Returns:the limitmods
/** * @return the limitmods */
public Set<String> getLimitmods() { return limitmods; }
Returns ModuleFinder that finds all observable modules for this jlink configuration.
/** * Returns {@link ModuleFinder} that finds all observable modules * for this jlink configuration. */
public ModuleFinder finder() { return finder; }
Returns a Configuration of the given module path, root modules with full service binding.
/** * Returns a {@link Configuration} of the given module path, * root modules with full service binding. */
public Configuration resolveAndBind() { return Configuration.empty().resolveAndBind(finder, ModuleFinder.of(), modules); }
Returns a Configuration of the given module path, root modules with no service binding.
/** * Returns a {@link Configuration} of the given module path, * root modules with no service binding. */
public Configuration resolve() { return Configuration.empty().resolve(finder, ModuleFinder.of(), modules); } private ModuleFinder moduleFinder() { Path[] entries = modulepaths.toArray(new Path[0]); ModuleFinder finder = ModulePath.of(Runtime.version(), true, entries); if (!limitmods.isEmpty()) { finder = JlinkTask.limitFinder(finder, limitmods, modules); } return finder; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("output=").append(output).append("\n"); StringBuilder pathsBuilder = new StringBuilder(); for (Path p : modulepaths) { pathsBuilder.append(p).append(","); } builder.append("modulepaths=").append(pathsBuilder).append("\n"); StringBuilder modsBuilder = new StringBuilder(); for (String p : modules) { modsBuilder.append(p).append(","); } builder.append("modules=").append(modsBuilder).append("\n"); StringBuilder limitsBuilder = new StringBuilder(); for (String p : limitmods) { limitsBuilder.append(p).append(","); } builder.append("limitmodules=").append(limitsBuilder).append("\n"); builder.append("endian=").append(endian).append("\n"); return builder.toString(); } }
Jlink instance constructor, if a security manager is set, the jlink permission is checked.
/** * Jlink instance constructor, if a security manager is set, the jlink * permission is checked. */
public Jlink() { if (System.getSecurityManager() != null) { System.getSecurityManager(). checkPermission(new JlinkPermission("jlink")); } }
Build the image.
Params:
  • config – Jlink config, must not be null.
Throws:
/** * Build the image. * * @param config Jlink config, must not be null. * @throws PluginException */
public void build(JlinkConfiguration config) { build(config, null); }
Build the image with a plugin configuration.
Params:
  • config – Jlink config, must not be null.
  • pluginsConfig – Plugins config, can be null
Throws:
/** * Build the image with a plugin configuration. * * @param config Jlink config, must not be null. * @param pluginsConfig Plugins config, can be null * @throws PluginException */
public void build(JlinkConfiguration config, PluginsConfiguration pluginsConfig) { Objects.requireNonNull(config); if (pluginsConfig == null) { pluginsConfig = new PluginsConfiguration(); } // add all auto-enabled plugins from boot layer pluginsConfig = addAutoEnabledPlugins(pluginsConfig); try { JlinkTask.createImage(config, pluginsConfig); } catch (Exception ex) { throw new PluginException(ex); } } private PluginsConfiguration addAutoEnabledPlugins(PluginsConfiguration pluginsConfig) { List<Plugin> plugins = new ArrayList<>(pluginsConfig.getPlugins()); List<Plugin> bootPlugins = PluginRepository.getPlugins(ModuleLayer.boot()); for (Plugin bp : bootPlugins) { if (Utils.isAutoEnabled(bp)) { try { bp.configure(Collections.emptyMap()); } catch (IllegalArgumentException e) { if (JlinkTask.DEBUG) { System.err.println("Plugin " + bp.getName() + " threw exception with config: {}"); e.printStackTrace(); } throw e; } plugins.add(bp); } } return new PluginsConfiguration(plugins, pluginsConfig.getImageBuilder(), pluginsConfig.getLastSorterPluginName()); }
Post process the image with a plugin configuration.
Params:
  • image – Existing image.
  • plugins – Plugins cannot be null
/** * Post process the image with a plugin configuration. * * @param image Existing image. * @param plugins Plugins cannot be null */
public void postProcess(ExecutableImage image, List<Plugin> plugins) { Objects.requireNonNull(image); Objects.requireNonNull(plugins); try { JlinkTask.postProcessImage(image, plugins); } catch (Exception ex) { throw new PluginException(ex); } } }