/*
* 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);
}
}
}