8156914: jlink API minor cleanups

Reviewed-by: mchung
This commit is contained in:
Athijegannathan Sundararajan 2016-05-16 14:47:27 +05:30
parent a3cdceaa83
commit 905d21fe76
73 changed files with 2077 additions and 1911 deletions

View File

@ -34,11 +34,9 @@ import java.util.Objects;
import java.util.Set;
import jdk.tools.jlink.internal.JlinkTask;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginContext;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ExecutableImage;
import jdk.tools.jlink.builder.ImageBuilder;
import jdk.tools.jlink.internal.PluginContextImpl;
import jdk.tools.jlink.internal.PluginRepository;
/**
@ -71,7 +69,6 @@ public final class Jlink {
private final List<Plugin> plugins;
private final ImageBuilder imageBuilder;
private final String lastSorterPluginName;
private final PluginContext pluginContext;
/**
* Empty plugins configuration.
@ -86,7 +83,7 @@ public final class Jlink {
* @param plugins List of plugins.
*/
public PluginsConfiguration(List<Plugin> plugins) {
this(plugins, null, null, null);
this(plugins, null, null);
}
/**
@ -101,28 +98,10 @@ public final class Jlink {
*/
public PluginsConfiguration(List<Plugin> plugins,
ImageBuilder imageBuilder, String lastSorterPluginName) {
this(plugins, imageBuilder, lastSorterPluginName, 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.
*
* @param plugins List of transformer plugins.
* @param imageBuilder Image builder.
* @param lastSorterPluginName Name of last sorter plugin, no sorting
* @param ctx the plugin context
* can occur after it.
*/
public PluginsConfiguration(List<Plugin> plugins,
ImageBuilder imageBuilder, String lastSorterPluginName,
PluginContext ctx) {
this.plugins = plugins == null ? Collections.emptyList()
: plugins;
this.imageBuilder = imageBuilder;
this.lastSorterPluginName = lastSorterPluginName;
this.pluginContext = ctx != null? ctx : new PluginContextImpl();
}
/**
@ -146,13 +125,6 @@ public final class Jlink {
return lastSorterPluginName;
}
/**
* @return the pluginContext
*/
public PluginContext getPluginContext() {
return pluginContext;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();

View File

@ -1,3 +1,4 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@ -24,8 +25,6 @@
*/
package jdk.tools.jlink.builder;
import jdk.tools.jlink.plugin.ExecutableImage;
import jdk.tools.jlink.plugin.PluginException;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
@ -47,8 +46,10 @@ import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
@ -56,23 +57,40 @@ import java.util.Set;
import jdk.tools.jlink.internal.BasicImageWriter;
import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
import jdk.tools.jlink.internal.plugins.FileCopierPlugin.SymImageFile;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.Module;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ExecutableImage;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.PluginException;
/**
*
* Default Image Builder. This builder creates the default runtime image layout.
*/
public class DefaultImageBuilder implements ImageBuilder {
public final class DefaultImageBuilder implements ImageBuilder {
/**
* The default java executable Image.
*/
static class DefaultExecutableImage extends ExecutableImage {
static final class DefaultExecutableImage implements ExecutableImage {
private final Path home;
private final List<String> args;
private final Set<String> modules;
public DefaultExecutableImage(Path home, Set<String> modules) {
super(home, modules, createArgs(home));
this(home, modules, createArgs(home));
}
private DefaultExecutableImage(Path home, Set<String> modules,
List<String> args) {
Objects.requireNonNull(home);
Objects.requireNonNull(args);
if (!Files.exists(home)) {
throw new IllegalArgumentException("Invalid image home");
}
this.home = home;
this.modules = Collections.unmodifiableSet(modules);
this.args = Collections.unmodifiableList(args);
}
private static List<String> createArgs(Path home) {
@ -83,6 +101,21 @@ public class DefaultImageBuilder implements ImageBuilder {
return javaArgs;
}
@Override
public Path getHome() {
return home;
}
@Override
public Set<String> getModules() {
return modules;
}
@Override
public List<String> getExecutionArgs() {
return args;
}
@Override
public void storeLaunchArgs(List<String> args) {
try {
@ -111,17 +144,19 @@ public class DefaultImageBuilder implements ImageBuilder {
Files.createDirectories(mdir);
}
private void storeFiles(Set<String> modules, Properties release) throws IOException {
private void storeFiles(Set<String> modules, Map<String, String> release) throws IOException {
if (release != null) {
addModules(release, modules);
Properties props = new Properties();
props.putAll(release);
addModules(props, modules);
File r = new File(root.toFile(), "release");
try (FileOutputStream fo = new FileOutputStream(r)) {
release.store(fo, null);
props.store(fo, null);
}
}
}
private void addModules(Properties release, Set<String> modules) throws IOException {
private void addModules(Properties props, Set<String> modules) throws IOException {
StringBuilder builder = new StringBuilder();
int i = 0;
for (String m : modules) {
@ -131,28 +166,32 @@ public class DefaultImageBuilder implements ImageBuilder {
}
i++;
}
release.setProperty("MODULES", builder.toString());
props.setProperty("MODULES", builder.toString());
}
@Override
public void storeFiles(Pool files, Properties release) {
public void storeFiles(ModulePool files) {
try {
for (ModuleData f : files.getContent()) {
if (!f.getType().equals(Pool.ModuleDataType.CLASS_OR_RESOURCE)) {
accept(f);
files.entries().forEach(f -> {
if (!f.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
try {
accept(f);
} catch (IOException ioExp) {
throw new UncheckedIOException(ioExp);
}
}
}
for (Module m : files.getModules()) {
});
files.modules().forEach(m -> {
// Only add modules that contain packages
if (!m.getAllPackages().isEmpty()) {
// Skip the fake module used by FileCopierPlugin when copying files.
if (m.getName().equals(FileCopierPlugin.FAKE_MODULE)) {
continue;
return;
}
modules.add(m.getName());
}
}
storeFiles(modules, release);
});
storeFiles(modules, files.getReleaseProperties());
if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
// launchers in the bin directory need execute permission
@ -168,8 +207,8 @@ public class DefaultImageBuilder implements ImageBuilder {
Path lib = root.resolve("lib");
if (Files.isDirectory(lib)) {
Files.find(lib, 2, (path, attrs) -> {
return path.getFileName().toString().equals("jspawnhelper") ||
path.getFileName().toString().equals("jexec");
return path.getFileName().toString().equals("jspawnhelper")
|| path.getFileName().toString().equals("jexec");
}).forEach(this::setExecutable);
}
}
@ -180,27 +219,23 @@ public class DefaultImageBuilder implements ImageBuilder {
}
}
@Override
public void storeFiles(Pool files) {
storeFiles(files, new Properties());
}
/**
* Generates launcher scripts.
*
* @param imageContent The image content.
* @param modules The set of modules that the runtime image contains.
* @throws IOException
*/
protected void prepareApplicationFiles(Pool imageContent, Set<String> modules) throws IOException {
protected void prepareApplicationFiles(ModulePool imageContent, Set<String> modules) throws IOException {
// generate launch scripts for the modules with a main class
for (String module : modules) {
String path = "/" + module + "/module-info.class";
ModuleData res = imageContent.get(path);
if (res == null) {
Optional<ModuleEntry> res = imageContent.findEntry(path);
if (!res.isPresent()) {
throw new IOException("module-info.class not found for " + module + " module");
}
Optional<String> mainClass;
ByteArrayInputStream stream = new ByteArrayInputStream(res.getBytes());
ByteArrayInputStream stream = new ByteArrayInputStream(res.get().getBytes());
mainClass = ModuleDescriptor.read(stream).mainClass();
if (mainClass.isPresent()) {
Path cmd = root.resolve("bin").resolve(module);
@ -263,9 +298,9 @@ public class DefaultImageBuilder implements ImageBuilder {
}
}
private void accept(ModuleData file) throws IOException {
private void accept(ModuleEntry file) throws IOException {
String fullPath = file.getPath();
String module = "/" + file.getModule()+ "/";
String module = "/" + file.getModule() + "/";
String filename = fullPath.substring(module.length());
// Remove radical native|config|...
filename = filename.substring(filename.indexOf('/') + 1);
@ -404,8 +439,7 @@ public class DefaultImageBuilder implements ImageBuilder {
public static ExecutableImage getExecutableImage(Path root) {
if (Files.exists(root.resolve("bin").resolve(getJavaProcessName()))) {
return new DefaultImageBuilder.DefaultExecutableImage(root,
retrieveModules(root));
return new DefaultExecutableImage(root, retrieveModules(root));
}
return null;
}

View File

@ -29,7 +29,7 @@ import java.util.Properties;
import jdk.tools.jlink.plugin.ExecutableImage;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModulePool;
/**
* Implement this interface to develop your own image layout. First the jimage
@ -45,7 +45,7 @@ public interface ImageBuilder {
* @param release the release properties
* @throws PluginException
*/
public default void storeFiles(Pool content, Properties release) {
public default void storeFiles(ModulePool content, Properties release) {
storeFiles(content);
}
@ -55,7 +55,7 @@ public interface ImageBuilder {
* @param content Pool of module content.
* @throws PluginException
*/
public default void storeFiles(Pool content) {
public default void storeFiles(ModulePool content) {
throw new UnsupportedOperationException("storeFiles");
}

View File

@ -44,12 +44,11 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.tools.jlink.internal.Archive.Entry;
import jdk.tools.jlink.internal.Archive.Entry.EntryType;
import jdk.tools.jlink.internal.PoolImpl.CompressedModuleData;
import jdk.tools.jlink.internal.ModulePoolImpl.CompressedModuleData;
import jdk.tools.jlink.plugin.ExecutableImage;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ModuleEntry;
/**
* An image (native endian.)
@ -145,7 +144,7 @@ public final class ImageFileCreator {
}));
ByteOrder order = ByteOrder.nativeOrder();
BasicImageWriter writer = new BasicImageWriter(order);
PoolImpl pool = createPools(archives, entriesForModule, order, writer);
ModulePoolImpl pool = createPools(archives, entriesForModule, order, writer);
try (OutputStream fos = Files.newOutputStream(jimageFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
DataOutputStream out = new DataOutputStream(bos)) {
@ -163,9 +162,9 @@ public final class ImageFileCreator {
ByteOrder byteOrder)
throws IOException {
BasicImageWriter writer = new BasicImageWriter(byteOrder);
PoolImpl allContent = createPools(archives,
ModulePoolImpl allContent = createPools(archives,
entriesForModule, byteOrder, writer);
PoolImpl result = generateJImage(allContent,
ModulePoolImpl result = generateJImage(allContent,
writer, plugins, plugins.getJImageFileOutputStream());
//Handle files.
@ -176,12 +175,12 @@ public final class ImageFileCreator {
}
}
private static PoolImpl generateJImage(PoolImpl allContent,
private static ModulePoolImpl generateJImage(ModulePoolImpl allContent,
BasicImageWriter writer,
ImagePluginStack pluginSupport,
DataOutputStream out
) throws IOException {
PoolImpl resultResources;
ModulePoolImpl resultResources;
try {
resultResources = pluginSupport.visitResources(allContent);
} catch (PluginException pe) {
@ -190,14 +189,14 @@ public final class ImageFileCreator {
throw new IOException(ex);
}
Set<String> duplicates = new HashSet<>();
long offset = 0;
long[] offset = new long[1];
List<ModuleData> content = new ArrayList<>();
List<ModuleEntry> content = new ArrayList<>();
List<String> paths = new ArrayList<>();
// the order of traversing the resources and the order of
// the module content being written must be the same
for (ModuleData res : resultResources.getContent()) {
if (res.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)) {
resultResources.entries().forEach(res -> {
if (res.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
String path = res.getPath();
content.add(res);
long uncompressedSize = res.getLength();
@ -216,24 +215,24 @@ public final class ImageFileCreator {
// TODO Need to hang bytes on resource and write
// from resource not zip.
// Skipping resource throws off writing from zip.
offset += onFileSize;
continue;
offset[0] += onFileSize;
return;
}
duplicates.add(path);
writer.addLocation(path, offset, compressedSize, uncompressedSize);
writer.addLocation(path, offset[0], compressedSize, uncompressedSize);
paths.add(path);
offset += onFileSize;
offset[0] += onFileSize;
}
}
});
ImageResourcesTree tree = new ImageResourcesTree(offset, writer, paths);
ImageResourcesTree tree = new ImageResourcesTree(offset[0], writer, paths);
// write header and indices
byte[] bytes = writer.getBytes();
out.write(bytes, 0, bytes.length);
// write module content
for (ModuleData res : content) {
for (ModuleEntry res : content) {
byte[] buf = res.getBytes();
out.write(buf, 0, buf.length);
}
@ -245,26 +244,26 @@ public final class ImageFileCreator {
return resultResources;
}
private static Pool.ModuleDataType mapImageFileType(EntryType type) {
private static ModuleEntry.Type mapImageFileType(EntryType type) {
switch(type) {
case CONFIG: {
return Pool.ModuleDataType.CONFIG;
return ModuleEntry.Type.CONFIG;
}
case NATIVE_CMD: {
return Pool.ModuleDataType.NATIVE_CMD;
return ModuleEntry.Type.NATIVE_CMD;
}
case NATIVE_LIB: {
return Pool.ModuleDataType.NATIVE_LIB;
return ModuleEntry.Type.NATIVE_LIB;
}
}
return null;
}
private static PoolImpl createPools(Set<Archive> archives,
private static ModulePoolImpl createPools(Set<Archive> archives,
Map<String, List<Entry>> entriesForModule,
ByteOrder byteOrder,
BasicImageWriter writer) throws IOException {
PoolImpl resources = new PoolImpl(byteOrder, new StringTable() {
ModulePoolImpl resources = new ModulePoolImpl(byteOrder, new StringTable() {
@Override
public int addString(String str) {
@ -291,7 +290,7 @@ public final class ImageFileCreator {
path = "/" + mn + "/" + path;
}
try {
resources.add(Pool.newResource(path, bytes));
resources.add(ModuleEntry.create(path, bytes));
} catch (Exception ex) {
throw new IOException(ex);
}
@ -300,7 +299,7 @@ public final class ImageFileCreator {
try {
// Entry.path() contains the kind of file native, conf, bin, ...
// Keep it to avoid naming conflict (eg: native/jvm.cfg and config/jvm.cfg
resources.add(Pool.newImageFile(mn,
resources.add(ModuleEntry.create(mn,
"/" + mn + "/" + entry.path(), mapImageFileType(entry.type()),
entry.stream(), entry.size()));
} catch (Exception ex) {

View File

@ -28,22 +28,17 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Properties;
import jdk.tools.jlink.plugin.ExecutableImage;
import jdk.tools.jlink.builder.ImageBuilder;
import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginContext;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Plugin.CATEGORY;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Plugin.Category;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.PostProcessorPlugin;
import jdk.tools.jlink.plugin.TransformerPlugin;
@ -52,17 +47,18 @@ import jdk.tools.jlink.plugin.TransformerPlugin;
*/
public final class ImagePluginConfiguration {
private static final List<Plugin.CATEGORY> CATEGORIES_ORDER = new ArrayList<>();
private static final List<Plugin.Category> CATEGORIES_ORDER = new ArrayList<>();
static {
CATEGORIES_ORDER.add(Plugin.CATEGORY.FILTER);
CATEGORIES_ORDER.add(Plugin.CATEGORY.TRANSFORMER);
CATEGORIES_ORDER.add(Plugin.CATEGORY.MODULEINFO_TRANSFORMER);
CATEGORIES_ORDER.add(Plugin.CATEGORY.SORTER);
CATEGORIES_ORDER.add(Plugin.CATEGORY.COMPRESSOR);
CATEGORIES_ORDER.add(Plugin.CATEGORY.VERIFIER);
CATEGORIES_ORDER.add(Plugin.CATEGORY.PROCESSOR);
CATEGORIES_ORDER.add(Plugin.CATEGORY.PACKAGER);
CATEGORIES_ORDER.add(Plugin.Category.FILTER);
CATEGORIES_ORDER.add(Plugin.Category.TRANSFORMER);
CATEGORIES_ORDER.add(Plugin.Category.MODULEINFO_TRANSFORMER);
CATEGORIES_ORDER.add(Plugin.Category.SORTER);
CATEGORIES_ORDER.add(Plugin.Category.COMPRESSOR);
CATEGORIES_ORDER.add(Plugin.Category.METAINFO_ADDER);
CATEGORIES_ORDER.add(Plugin.Category.VERIFIER);
CATEGORIES_ORDER.add(Plugin.Category.PROCESSOR);
CATEGORIES_ORDER.add(Plugin.Category.PACKAGER);
}
private ImagePluginConfiguration() {
@ -76,8 +72,8 @@ public final class ImagePluginConfiguration {
if (pluginsConfiguration == null) {
return new ImagePluginStack();
}
Map<Plugin.CATEGORY, List<Plugin>> plugins = new LinkedHashMap<>();
for (Plugin.CATEGORY cat : CATEGORIES_ORDER) {
Map<Plugin.Category, List<Plugin>> plugins = new LinkedHashMap<>();
for (Plugin.Category cat : CATEGORIES_ORDER) {
plugins.put(cat, new ArrayList<>());
}
@ -89,7 +85,7 @@ public final class ImagePluginConfiguration {
+ " added more than once to stack ");
}
seen.add(plug.getName());
CATEGORY category = Utils.getCategory(plug);
Category category = Utils.getCategory(plug);
if (category == null) {
throw new PluginException("Invalid category for "
+ plug.getName());
@ -100,10 +96,10 @@ public final class ImagePluginConfiguration {
List<TransformerPlugin> transformerPlugins = new ArrayList<>();
List<PostProcessorPlugin> postProcessingPlugins = new ArrayList<>();
for (Entry<Plugin.CATEGORY, List<Plugin>> entry : plugins.entrySet()) {
for (Entry<Plugin.Category, List<Plugin>> entry : plugins.entrySet()) {
// Sort according to plugin constraints
List<Plugin> orderedPlugins = PluginOrderingGraph.sort(entry.getValue());
CATEGORY category = entry.getKey();
Category category = entry.getKey();
for (Plugin p : orderedPlugins) {
if (Utils.isPostProcessor(category)) {
@SuppressWarnings("unchecked")
@ -143,14 +139,13 @@ public final class ImagePluginConfiguration {
}
@Override
public void storeFiles(Pool files) {
public void storeFiles(ModulePool files) {
throw new PluginException("No directory setup to store files");
}
};
}
PluginContext ctxt = pluginsConfiguration.getPluginContext();
return new ImagePluginStack(builder, transformerPlugins,
lastSorter, postProcessingPlugins, ctxt);
lastSorter, postProcessingPlugins);
}
}

View File

@ -37,20 +37,21 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.internal.jimage.decompressor.Decompressor;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginContext;
import jdk.tools.jlink.plugin.ExecutableImage;
import jdk.tools.jlink.builder.ImageBuilder;
import jdk.tools.jlink.plugin.TransformerPlugin;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.LinkModule;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.PostProcessorPlugin;
/**
@ -64,9 +65,9 @@ public final class ImagePluginStack {
ExecutableImage retrieve(ImagePluginStack stack) throws IOException;
}
public static final class OrderedResourcePool extends PoolImpl {
public static final class OrderedResourcePool extends ModulePoolImpl {
private final List<ModuleData> orderedList = new ArrayList<>();
private final List<ModuleEntry> orderedList = new ArrayList<>();
public OrderedResourcePool(ByteOrder order, StringTable table) {
super(order, table);
@ -78,22 +79,22 @@ public final class ImagePluginStack {
* @param resource The Resource to add.
*/
@Override
public void add(ModuleData resource) {
public void add(ModuleEntry resource) {
super.add(resource);
orderedList.add(resource);
}
List<ModuleData> getOrderedList() {
List<ModuleEntry> getOrderedList() {
return Collections.unmodifiableList(orderedList);
}
}
private final static class CheckOrderResourcePool extends PoolImpl {
private final static class CheckOrderResourcePool extends ModulePoolImpl {
private final List<ModuleData> orderedList;
private final List<ModuleEntry> orderedList;
private int currentIndex;
public CheckOrderResourcePool(ByteOrder order, List<ModuleData> orderedList, StringTable table) {
public CheckOrderResourcePool(ByteOrder order, List<ModuleEntry> orderedList, StringTable table) {
super(order, table);
this.orderedList = orderedList;
}
@ -104,8 +105,8 @@ public final class ImagePluginStack {
* @param resource The Resource to add.
*/
@Override
public void add(ModuleData resource) {
ModuleData ordered = orderedList.get(currentIndex);
public void add(ModuleEntry resource) {
ModuleEntry ordered = orderedList.get(currentIndex);
if (!resource.equals(ordered)) {
throw new PluginException("Resource " + resource.getPath() + " not in the right order");
}
@ -166,26 +167,16 @@ public final class ImagePluginStack {
private final List<ResourcePrevisitor> resourcePrevisitors = new ArrayList<>();
private final ImageBuilder imageBuilder;
private final Properties release;
public ImagePluginStack() {
this(null, Collections.emptyList(), null,
Collections.emptyList(), null);
Collections.emptyList());
}
public ImagePluginStack(ImageBuilder imageBuilder,
List<TransformerPlugin> contentPlugins,
Plugin lastSorter,
List<PostProcessorPlugin> postprocessingPlugins) {
this(imageBuilder, contentPlugins, lastSorter,
postprocessingPlugins, null);
}
public ImagePluginStack(ImageBuilder imageBuilder,
List<TransformerPlugin> contentPlugins,
Plugin lastSorter,
List<PostProcessorPlugin> postprocessingPlugins,
PluginContext ctxt) {
Objects.requireNonNull(contentPlugins);
this.lastSorter = lastSorter;
for (TransformerPlugin p : contentPlugins) {
@ -200,7 +191,6 @@ public final class ImagePluginStack {
this.postProcessingPlugins.add(p);
}
this.imageBuilder = imageBuilder;
this.release = ctxt != null? ctxt.getReleaseProperties() : new Properties();
}
public void operate(ImageProvider provider) throws Exception {
@ -231,12 +221,12 @@ public final class ImagePluginStack {
* @return The result of the visit.
* @throws IOException
*/
public PoolImpl visitResources(PoolImpl resources)
public ModulePoolImpl visitResources(ModulePoolImpl resources)
throws Exception {
Objects.requireNonNull(resources);
resources.setReadOnly();
if (resources.isEmpty()) {
return new PoolImpl(resources.getByteOrder(),
return new ModulePoolImpl(resources.getByteOrder(),
resources.getStringTable());
}
PreVisitStrings previsit = new PreVisitStrings();
@ -250,11 +240,11 @@ public final class ImagePluginStack {
resources.getStringTable().addString(s);
}
PoolImpl current = resources;
List<Pool.ModuleData> frozenOrder = null;
ModulePoolImpl current = resources;
List<ModuleEntry> frozenOrder = null;
for (TransformerPlugin p : contentPlugins) {
current.setReadOnly();
PoolImpl output = null;
ModulePoolImpl output = null;
if (p == lastSorter) {
if (frozenOrder != null) {
throw new Exception("Order of resources is already frozen. Plugin "
@ -268,7 +258,7 @@ public final class ImagePluginStack {
output = new CheckOrderResourcePool(current.getByteOrder(),
frozenOrder, resources.getStringTable());
} else {
output = new PoolImpl(current.getByteOrder(),
output = new ModulePoolImpl(current.getByteOrder(),
resources.getStringTable());
}
}
@ -287,15 +277,15 @@ public final class ImagePluginStack {
}
/**
* This pool wrap the original pool and automatically uncompress moduledata
* This pool wrap the original pool and automatically uncompress ModuleEntry
* if needed.
*/
private class LastPool extends Pool {
private class LastModule implements Module {
private class LastPool implements ModulePool {
private class LastModule implements LinkModule {
private final Module module;
final LinkModule module;
LastModule(Module module) {
LastModule(LinkModule module) {
this.module = module;
}
@ -305,9 +295,9 @@ public final class ImagePluginStack {
}
@Override
public ModuleData get(String path) {
ModuleData d = module.get(path);
return getUncompressed(d);
public Optional<ModuleEntry> findEntry(String path) {
Optional<ModuleEntry> d = module.findEntry(path);
return d.isPresent()? Optional.of(getUncompressed(d.get())) : Optional.empty();
}
@Override
@ -316,7 +306,7 @@ public final class ImagePluginStack {
}
@Override
public void add(ModuleData data) {
public void add(ModuleEntry data) {
throw new PluginException("pool is readonly");
}
@ -331,19 +321,24 @@ public final class ImagePluginStack {
}
@Override
public Collection<ModuleData> getContent() {
List<ModuleData> lst = new ArrayList<>();
for(ModuleData md : module.getContent()) {
public Stream<ModuleEntry> entries() {
List<ModuleEntry> lst = new ArrayList<>();
module.entries().forEach(md -> {
lst.add(getUncompressed(md));
}
return lst;
});
return lst.stream();
}
@Override
public int getEntryCount() {
return module.getEntryCount();
}
}
private final PoolImpl pool;
private final ModulePoolImpl pool;
Decompressor decompressor = new Decompressor();
Collection<ModuleData> content;
Collection<ModuleEntry> content;
LastPool(PoolImpl pool) {
LastPool(ModulePoolImpl pool) {
this.pool = pool;
}
@ -353,23 +348,14 @@ public final class ImagePluginStack {
}
@Override
public void add(ModuleData resource) {
public void add(ModuleEntry resource) {
throw new PluginException("pool is readonly");
}
/**
* Retrieves the module of the provided name.
*
* @param name The module name
* @return the module or null if the module doesn't exist.
*/
@Override
public Module getModule(String name) {
Module module = pool.getModule(name);
if (module != null) {
module = new LastModule(module);
}
return module;
public Optional<LinkModule> findModule(String name) {
Optional<LinkModule> module = pool.findModule(name);
return module.isPresent()? Optional.of(new LastModule(module.get())) : Optional.empty();
}
/**
@ -378,45 +364,55 @@ public final class ImagePluginStack {
* @return The collection of modules.
*/
@Override
public Collection<Module> getModules() {
List<Module> modules = new ArrayList<>();
for (Module m : pool.getModules()) {
public Stream<? extends LinkModule> modules() {
List<LinkModule> modules = new ArrayList<>();
pool.modules().forEach(m -> {
modules.add(new LastModule(m));
}
return modules;
});
return modules.stream();
}
@Override
public int getModuleCount() {
return pool.getModuleCount();
}
/**
* Get all resources contained in this pool instance.
*
* @return The collection of resources;
* @return The stream of resources;
*/
@Override
public Collection<ModuleData> getContent() {
public Stream<? extends ModuleEntry> entries() {
if (content == null) {
content = new ArrayList<>();
for (ModuleData md : pool.getContent()) {
pool.entries().forEach(md -> {
content.add(getUncompressed(md));
}
});
}
return content;
return content.stream();
}
@Override
public int getEntryCount() {
return pool.getEntryCount();
}
/**
* Get the resource for the passed path.
*
* @param path A resource path
* @return A Resource instance or null if the resource is not found
* @return A Resource instance if the resource is found
*/
@Override
public ModuleData get(String path) {
public Optional<ModuleEntry> findEntry(String path) {
Objects.requireNonNull(path);
Pool.ModuleData res = pool.get(path);
return getUncompressed(res);
Optional<ModuleEntry> res = pool.findEntry(path);
return res.isPresent()? Optional.of(getUncompressed(res.get())) : Optional.empty();
}
@Override
public boolean contains(ModuleData res) {
public boolean contains(ModuleEntry res) {
return pool.contains(res);
}
@ -426,8 +422,8 @@ public final class ImagePluginStack {
}
@Override
public void visit(Visitor visitor, Pool output) {
pool.visit(visitor, output);
public void transformAndCopy(Function<ModuleEntry, ModuleEntry> visitor, ModulePool output) {
pool.transformAndCopy(visitor, output);
}
@Override
@ -435,14 +431,19 @@ public final class ImagePluginStack {
return pool.getByteOrder();
}
private ModuleData getUncompressed(ModuleData res) {
@Override
public Map<String, String> getReleaseProperties() {
return Collections.unmodifiableMap(pool.getReleaseProperties());
}
private ModuleEntry getUncompressed(ModuleEntry res) {
if (res != null) {
if (res instanceof PoolImpl.CompressedModuleData) {
if (res instanceof ModulePoolImpl.CompressedModuleData) {
try {
byte[] bytes = decompressor.decompressResource(getByteOrder(),
(int offset) -> pool.getStringTable().getString(offset),
res.getBytes());
res = Pool.newResource(res.getPath(),
res = ModuleEntry.create(res.getPath(),
new ByteArrayInputStream(bytes),
bytes.length);
} catch (IOException ex) {
@ -462,20 +463,24 @@ public final class ImagePluginStack {
* @param writer
* @throws java.lang.Exception
*/
public void storeFiles(PoolImpl original, PoolImpl transformed,
public void storeFiles(ModulePoolImpl original, ModulePoolImpl transformed,
BasicImageWriter writer)
throws Exception {
Objects.requireNonNull(original);
try {
// fill release information available from transformed "java.base" module!
ModuleDescriptor desc = transformed.getModule("java.base").getDescriptor();
desc.osName().ifPresent(s -> release.put("OS_NAME", s));
desc.osVersion().ifPresent(s -> release.put("OS_VERSION", s));
desc.osArch().ifPresent(s -> release.put("OS_ARCH", s));
} catch (Exception ignored) {
}
Objects.requireNonNull(transformed);
Optional<LinkModule> javaBase = transformed.findModule("java.base");
javaBase.ifPresent(mod -> {
try {
Map<String, String> release = transformed.getReleaseProperties();
// fill release information available from transformed "java.base" module!
ModuleDescriptor desc = mod.getDescriptor();
desc.osName().ifPresent(s -> release.put("OS_NAME", s));
desc.osVersion().ifPresent(s -> release.put("OS_VERSION", s));
desc.osArch().ifPresent(s -> release.put("OS_ARCH", s));
} catch (Exception ignored) {}
});
imageBuilder.storeFiles(new LastPool(transformed), release);
imageBuilder.storeFiles(new LastPool(transformed));
}
public ExecutableImage getExecutableImage() throws IOException {

View File

@ -0,0 +1,164 @@
/*
* Copyright (c) 2016, 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.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.Objects;
import jdk.tools.jlink.plugin.ModuleEntry;
/**
* A LinkModuleEntry is the elementary unit of data inside an image. It is
* generally a file. e.g.: a java class file, a resource file, a shared library,
* ...
* <br>
* A LinkModuleEntry is identified by a path of the form:
* <ul>
* <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
* name}</li>
* <li>For other files (shared lib, launchers, config, ...):/{module name}/
* {@literal bin|conf|native}/{dir1}>/.../{dirN}/{file name}</li>
* </ul>
*/
public class ModuleEntryImpl implements ModuleEntry {
private final Type type;
private final String path;
private final String module;
private final long length;
private final InputStream stream;
private byte[] buffer;
/**
* Create a new LinkModuleEntry.
*
* @param module The module name.
* @param path The data path identifier.
* @param type The data type.
* @param stream The data content stream.
* @param length The stream length.
*/
public ModuleEntryImpl(String module, String path, Type type, InputStream stream, long length) {
Objects.requireNonNull(module);
Objects.requireNonNull(path);
Objects.requireNonNull(type);
Objects.requireNonNull(stream);
this.path = path;
this.type = type;
this.module = module;
this.stream = stream;
this.length = length;
}
/**
* The LinkModuleEntry module name.
*
* @return The module name.
*/
@Override
public final String getModule() {
return module;
}
/**
* The LinkModuleEntry path.
*
* @return The module path.
*/
@Override
public final String getPath() {
return path;
}
/**
* The LinkModuleEntry's type.
*
* @return The data type.
*/
@Override
public final Type getType() {
return type;
}
/**
* The LinkModuleEntry content as an array of byte.
*
* @return An Array of bytes.
*/
@Override
public byte[] getBytes() {
if (buffer == null) {
try (InputStream is = stream) {
buffer = is.readAllBytes();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
return buffer;
}
/**
* The LinkModuleEntry content length.
*
* @return The length.
*/
@Override
public long getLength() {
return length;
}
/**
* The LinkModuleEntry stream.
*
* @return The module data stream.
*/
@Override
public InputStream stream() {
return stream;
}
@Override
public int hashCode() {
int hash = 7;
hash = 89 * hash + Objects.hashCode(this.path);
return hash;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof ModuleEntryImpl)) {
return false;
}
ModuleEntryImpl f = (ModuleEntryImpl) other;
return f.path.equals(path);
}
@Override
public String toString() {
return getPath();
}
}

View File

@ -0,0 +1,421 @@
/*
* Copyright (c) 2015, 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.io.ByteArrayInputStream;
import java.io.InputStream;
import java.lang.module.ModuleDescriptor;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;
import jdk.internal.jimage.decompressor.CompressedResourceHeader;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.LinkModule;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
/**
* Pool of module data.
*/
public class ModulePoolImpl implements ModulePool {
private class ModuleImpl implements LinkModule {
final Map<String, ModuleEntry> moduleContent = new LinkedHashMap<>();
private ModuleDescriptor descriptor;
final String name;
private ModuleImpl(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public Optional<ModuleEntry> findEntry(String path) {
if (!path.startsWith("/")) {
path = "/" + path;
}
if (!path.startsWith("/" + name)) {
path = "/" + name + path;
}
return Optional.ofNullable(moduleContent.get(path));
}
@Override
public ModuleDescriptor getDescriptor() {
if (descriptor == null) {
String p = "/" + name + "/module-info.class";
Optional<ModuleEntry> content = findEntry(p);
if (!content.isPresent()) {
throw new PluginException("No module-info for " + name
+ " module");
}
ByteBuffer bb = ByteBuffer.wrap(content.get().getBytes());
descriptor = ModuleDescriptor.read(bb);
}
return descriptor;
}
@Override
public void add(ModuleEntry data) {
if (isReadOnly()) {
throw new PluginException("LinkConfiguration is readonly");
}
Objects.requireNonNull(data);
if (!data.getModule().equals(name)) {
throw new PluginException("Can't add resource " + data.getPath()
+ " to module " + name);
}
ModulePoolImpl.this.add(data);
}
@Override
public Set<String> getAllPackages() {
Set<String> pkgs = new HashSet<>();
moduleContent.values().stream().filter(m -> m.getType().
equals(ModuleEntry.Type.CLASS_OR_RESOURCE)).forEach(res -> {
// Module metadata only contains packages with .class files
if (ImageFileCreator.isClassPackage(res.getPath())) {
String[] split = ImageFileCreator.splitPath(res.getPath());
String pkg = split[1];
if (pkg != null && !pkg.isEmpty()) {
pkgs.add(pkg);
}
}
});
return pkgs;
}
@Override
public String toString() {
return getName();
}
@Override
public Stream<? extends ModuleEntry> entries() {
return moduleContent.values().stream();
}
@Override
public int getEntryCount() {
return moduleContent.values().size();
}
}
private final Map<String, ModuleEntry> resources = new LinkedHashMap<>();
private final Map<String, ModuleImpl> modules = new LinkedHashMap<>();
private final ModuleImpl fileCopierModule = new ModuleImpl(FileCopierPlugin.FAKE_MODULE);
private Map<String, String> releaseProps = new HashMap<>();
private final ByteOrder order;
private boolean isReadOnly;
private final StringTable table;
public ModulePoolImpl() {
this(ByteOrder.nativeOrder());
}
public ModulePoolImpl(ByteOrder order) {
this(order, new StringTable() {
@Override
public int addString(String str) {
return -1;
}
@Override
public String getString(int id) {
return null;
}
});
}
public ModulePoolImpl(ByteOrder order, StringTable table) {
this.order = order;
this.table = table;
}
/**
* Add a ModuleEntry.
*
* @param data The ModuleEntry to add.
*/
@Override
public void add(ModuleEntry data) {
if (isReadOnly()) {
throw new PluginException("LinkConfiguration is readonly");
}
Objects.requireNonNull(data);
if (resources.get(data.getPath()) != null) {
throw new PluginException("Resource " + data.getPath()
+ " already present");
}
String modulename = data.getModule();
ModuleImpl m = modules.get(modulename);
// ## TODO: FileCopierPlugin should not add content to a module
// FAKE_MODULE is not really a module to be added in the image
if (FileCopierPlugin.FAKE_MODULE.equals(modulename)) {
m = fileCopierModule;
}
if (m == null) {
m = new ModuleImpl(modulename);
modules.put(modulename, m);
}
resources.put(data.getPath(), data);
m.moduleContent.put(data.getPath(), data);
}
/**
* Retrieves the module for the provided name.
*
* @param name The module name
* @return the module of matching name, if found
*/
@Override
public Optional<LinkModule> findModule(String name) {
Objects.requireNonNull(name);
return Optional.ofNullable(modules.get(name));
}
/**
* The stream of modules contained in this LinkConfiguration.
*
* @return The stream of modules.
*/
@Override
public Stream<? extends LinkModule> modules() {
return modules.values().stream();
}
/**
* Return the number of LinkModule count in this LinkConfiguration.
*
* @return the module count.
*/
@Override
public int getModuleCount() {
return modules.size();
}
/**
* Get all ModuleEntry contained in this LinkConfiguration instance.
*
* @return The stream of LinkModuleEntries.
*/
@Override
public Stream<? extends ModuleEntry> entries() {
return resources.values().stream();
}
/**
* Return the number of ModuleEntry count in this LinkConfiguration.
*
* @return the entry count.
*/
@Override
public int getEntryCount() {
return resources.values().size();
}
/**
* Get the ModuleEntry for the passed path.
*
* @param path A data path
* @return A ModuleEntry instance or null if the data is not found
*/
@Override
public Optional<ModuleEntry> findEntry(String path) {
Objects.requireNonNull(path);
return Optional.ofNullable(resources.get(path));
}
/**
* Check if the LinkConfiguration contains the given ModuleEntry.
*
* @param data The module data to check existence for.
* @return The module data or null if not found.
*/
@Override
public boolean contains(ModuleEntry data) {
Objects.requireNonNull(data);
return findEntry(data.getPath()).isPresent();
}
/**
* Check if the LinkConfiguration contains some content at all.
*
* @return True, no content, false otherwise.
*/
@Override
public boolean isEmpty() {
return resources.isEmpty();
}
/**
* Visit each ModuleEntry in this LinkConfiguration to transform it and
* copy the transformed ModuleEntry to the output LinkConfiguration.
*
* @param transform The function called for each ModuleEntry found in
* the LinkConfiguration. The transform function should return a
* ModuleEntry instance which will be added to the output or it should
* return null if the passed ModuleEntry is to be ignored for the
* output.
*
* @param output The LinkConfiguration to be filled with Visitor returned
* ModuleEntry.
*/
@Override
public void transformAndCopy(Function<ModuleEntry, ModuleEntry> transform,
ModulePool output) {
entries().forEach(resource -> {
ModuleEntry res = transform.apply(resource);
if (res != null) {
output.add(res);
}
});
}
/**
* The ByteOrder currently in use when generating the jimage file.
*
* @return The ByteOrder.
*/
@Override
public ByteOrder getByteOrder() {
return order;
}
@Override
public Map<String, String> getReleaseProperties() {
return isReadOnly()? Collections.unmodifiableMap(releaseProps) : releaseProps;
}
public StringTable getStringTable() {
return table;
}
/**
* Make this Resources instance read-only. No resource can be added.
*/
public void setReadOnly() {
isReadOnly = true;
}
/**
* Read only state.
*
* @return true if readonly false otherwise.
*/
@Override
public boolean isReadOnly() {
return isReadOnly;
}
/**
* A resource that has been compressed.
*/
public static final class CompressedModuleData extends ModuleEntryImpl {
final long uncompressed_size;
private CompressedModuleData(String module, String path,
InputStream stream, long size,
long uncompressed_size) {
super(module, path, ModuleEntry.Type.CLASS_OR_RESOURCE, stream, size);
this.uncompressed_size = uncompressed_size;
}
public long getUncompressedSize() {
return uncompressed_size;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof CompressedModuleData)) {
return false;
}
CompressedModuleData f = (CompressedModuleData) other;
return f.getPath().equals(getPath());
}
@Override
public int hashCode() {
return super.hashCode();
}
}
public static CompressedModuleData newCompressedResource(ModuleEntry original,
ByteBuffer compressed,
String plugin, String pluginConfig, StringTable strings,
ByteOrder order) {
Objects.requireNonNull(original);
Objects.requireNonNull(compressed);
Objects.requireNonNull(plugin);
boolean isTerminal = !(original instanceof CompressedModuleData);
long uncompressed_size = original.getLength();
if (original instanceof CompressedModuleData) {
CompressedModuleData comp = (CompressedModuleData) original;
uncompressed_size = comp.getUncompressedSize();
}
int nameOffset = strings.addString(plugin);
int configOffset = -1;
if (pluginConfig != null) {
configOffset = strings.addString(plugin);
}
CompressedResourceHeader rh
= new CompressedResourceHeader(compressed.limit(), original.getLength(),
nameOffset, configOffset, isTerminal);
// Merge header with content;
byte[] h = rh.getBytes(order);
ByteBuffer bb = ByteBuffer.allocate(compressed.limit() + h.length);
bb.order(order);
bb.put(h);
bb.put(compressed);
byte[] contentWithHeader = bb.array();
CompressedModuleData compressedResource
= new CompressedModuleData(original.getModule(), original.getPath(),
new ByteArrayInputStream(contentWithHeader),
contentWithHeader.length, uncompressed_size);
return compressedResource;
}
}

View File

@ -1,37 +0,0 @@
/*
* Copyright (c) 2016, 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.util.Properties;
import jdk.tools.jlink.plugin.PluginContext;
public final class PluginContextImpl implements PluginContext {
private final Properties releaseProps = new Properties();
public Properties getReleaseProperties() {
return releaseProps;
}
}

View File

@ -1,167 +0,0 @@
/*
* Copyright (c) 2015, 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.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Objects;
import jdk.internal.jimage.decompressor.CompressedResourceHeader;
import jdk.tools.jlink.plugin.Pool;
/**
* Pool of module data.
*/
public class PoolImpl extends Pool {
/**
* A resource that has been compressed.
*/
public static final class CompressedModuleData extends ModuleData {
private final long uncompressed_size;
private CompressedModuleData(String module, String path,
InputStream stream, long size,
long uncompressed_size) {
super(module, path, ModuleDataType.CLASS_OR_RESOURCE, stream, size);
this.uncompressed_size = uncompressed_size;
}
public long getUncompressedSize() {
return uncompressed_size;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof CompressedModuleData)) {
return false;
}
CompressedModuleData f = (CompressedModuleData) other;
return f.getPath().equals(getPath());
}
@Override
public int hashCode() {
return super.hashCode();
}
}
private boolean isReadOnly;
private final StringTable table;
public PoolImpl() {
this(ByteOrder.nativeOrder(), new StringTable() {
@Override
public int addString(String str) {
return -1;
}
@Override
public String getString(int id) {
return null;
}
});
}
public PoolImpl(ByteOrder order) {
this(order, new StringTable() {
@Override
public int addString(String str) {
return -1;
}
@Override
public String getString(int id) {
return null;
}
});
}
public PoolImpl(ByteOrder order, StringTable table) {
super(order);
this.table = table;
}
public StringTable getStringTable() {
return table;
}
/**
* Make this Resources instance read-only. No resource can be added.
*/
public void setReadOnly() {
isReadOnly = true;
}
/**
* Read only state.
*
* @return true if readonly false otherwise.
*/
@Override
public boolean isReadOnly() {
return isReadOnly;
}
public static CompressedModuleData newCompressedResource(ModuleData original,
ByteBuffer compressed,
String plugin, String pluginConfig, StringTable strings,
ByteOrder order) {
Objects.requireNonNull(original);
Objects.requireNonNull(compressed);
Objects.requireNonNull(plugin);
boolean isTerminal = !(original instanceof CompressedModuleData);
long uncompressed_size = original.getLength();
if (original instanceof CompressedModuleData) {
CompressedModuleData comp = (CompressedModuleData) original;
uncompressed_size = comp.getUncompressedSize();
}
int nameOffset = strings.addString(plugin);
int configOffset = -1;
if (pluginConfig != null) {
configOffset = strings.addString(plugin);
}
CompressedResourceHeader rh
= new CompressedResourceHeader(compressed.limit(), original.getLength(),
nameOffset, configOffset, isTerminal);
// Merge header with content;
byte[] h = rh.getBytes(order);
ByteBuffer bb = ByteBuffer.allocate(compressed.limit() + h.length);
bb.order(order);
bb.put(h);
bb.put(compressed);
byte[] contentWithHeader = bb.array();
CompressedModuleData compressedResource
= new CompressedModuleData(original.getModule(), original.getPath(),
new ByteArrayInputStream(contentWithHeader),
contentWithHeader.length, uncompressed_size);
return compressedResource;
}
}

View File

@ -24,7 +24,7 @@
*/
package jdk.tools.jlink.internal;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModulePool;
/**
* Plugin wishing to pre-visit the resources must implement this interface.
@ -44,5 +44,5 @@ public interface ResourcePrevisitor {
* usage.
* @throws PluginException
*/
public void previsit(Pool resources, StringTable strings);
public void previsit(ModulePool resources, StringTable strings);
}

View File

@ -52,7 +52,7 @@ import jdk.internal.module.ConfigurableModuleFinder.Phase;
import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.Plugin.CATEGORY;
import jdk.tools.jlink.plugin.Plugin.Category;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.builder.ImageBuilder;
import jdk.tools.jlink.plugin.PluginException;
@ -346,7 +346,6 @@ public final class TaskHelper {
}
}
PluginContextImpl pluginContext = new PluginContextImpl();
List<Plugin> pluginsList = new ArrayList<>();
for (Entry<Plugin, List<Map<String, String>>> entry : pluginToMaps.entrySet()) {
Plugin plugin = entry.getKey();
@ -356,7 +355,7 @@ public final class TaskHelper {
// we call configure once for each occurrence. It is upto the plugin
// to 'merge' and/or 'override' arguments.
for (Map<String, String> map : argsMaps) {
plugin.configure(Collections.unmodifiableMap(map), pluginContext);
plugin.configure(Collections.unmodifiableMap(map));
}
if (!Utils.isDisabled(plugin)) {
@ -371,7 +370,7 @@ public final class TaskHelper {
}
return new Jlink.PluginsConfiguration(pluginsList,
builder, lastSorter, pluginContext);
builder, lastSorter);
}
}
@ -594,7 +593,7 @@ public final class TaskHelper {
+ ": " + plugin.getClass().getName());
log.println(bundleHelper.getMessage("main.plugin.module")
+ ": " + plugin.getClass().getModule().getName());
CATEGORY category = Utils.getCategory(plugin);
Category category = Utils.getCategory(plugin);
log.println(bundleHelper.getMessage("main.plugin.category")
+ ": " + category.getName());
log.println(bundleHelper.getMessage("main.plugin.state")

View File

@ -30,7 +30,6 @@ import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.Plugin.PluginType;
public class Utils {
@ -50,25 +49,26 @@ public class Utils {
return arguments;
};
public static boolean isPostProcessor(Plugin.CATEGORY category) {
return category.equals(Plugin.CATEGORY.VERIFIER)
|| category.equals(Plugin.CATEGORY.PROCESSOR)
|| category.equals(Plugin.CATEGORY.PACKAGER);
public static boolean isPostProcessor(Plugin.Category category) {
return category.equals(Plugin.Category.VERIFIER)
|| category.equals(Plugin.Category.PROCESSOR)
|| category.equals(Plugin.Category.PACKAGER);
}
public static boolean isPreProcessor(Plugin.CATEGORY category) {
return category.equals(Plugin.CATEGORY.COMPRESSOR)
|| category.equals(Plugin.CATEGORY.FILTER)
|| category.equals(Plugin.CATEGORY.MODULEINFO_TRANSFORMER)
|| category.equals(Plugin.CATEGORY.SORTER)
|| category.equals(Plugin.CATEGORY.TRANSFORMER);
public static boolean isPreProcessor(Plugin.Category category) {
return category.equals(Plugin.Category.COMPRESSOR)
|| category.equals(Plugin.Category.FILTER)
|| category.equals(Plugin.Category.MODULEINFO_TRANSFORMER)
|| category.equals(Plugin.Category.SORTER)
|| category.equals(Plugin.Category.TRANSFORMER)
|| category.equals(Plugin.Category.METAINFO_ADDER);
}
public static boolean isPostProcessor(Plugin prov) {
if (prov.getType() != null) {
for (PluginType pt : prov.getType()) {
if (pt instanceof Plugin.CATEGORY) {
return isPostProcessor((Plugin.CATEGORY) pt);
for (Plugin.Category pt : prov.getType()) {
if (pt instanceof Plugin.Category) {
return isPostProcessor(pt);
}
}
}
@ -77,20 +77,20 @@ public class Utils {
public static boolean isPreProcessor(Plugin prov) {
if (prov.getType() != null) {
for (PluginType pt : prov.getType()) {
if (pt instanceof Plugin.CATEGORY) {
return isPreProcessor((Plugin.CATEGORY) pt);
for (Plugin.Category pt : prov.getType()) {
if (pt instanceof Plugin.Category) {
return isPreProcessor(pt);
}
}
}
return false;
}
public static Plugin.CATEGORY getCategory(Plugin provider) {
public static Plugin.Category getCategory(Plugin provider) {
if (provider.getType() != null) {
for (Plugin.PluginType t : provider.getType()) {
if (t instanceof Plugin.CATEGORY) {
return (Plugin.CATEGORY) t;
for (Plugin.Category t : provider.getType()) {
if (t instanceof Plugin.Category) {
return t;
}
}
}
@ -140,15 +140,15 @@ public class Utils {
}
public static boolean isFunctional(Plugin prov) {
return prov.getState().contains(Plugin.STATE.FUNCTIONAL);
return prov.getState().contains(Plugin.State.FUNCTIONAL);
}
public static boolean isAutoEnabled(Plugin prov) {
return prov.getState().contains(Plugin.STATE.AUTO_ENABLED);
return prov.getState().contains(Plugin.State.AUTO_ENABLED);
}
public static boolean isDisabled(Plugin prov) {
return prov.getState().contains(Plugin.STATE.DISABLED);
return prov.getState().contains(Plugin.State.DISABLED);
}
// is this a builtin (jdk.jlink) plugin?

View File

@ -30,7 +30,7 @@ import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.builder.ImageBuilder;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.builder.*;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModulePool;
import java.io.ByteArrayOutputStream;
import java.io.File;

View File

@ -26,16 +26,13 @@ package jdk.tools.jlink.internal.plugins;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePrevisitor;
@ -62,10 +59,10 @@ public final class DefaultCompressPlugin implements TransformerPlugin, ResourceP
}
@Override
public void visit(Pool in, Pool out) {
public void visit(ModulePool in, ModulePool out) {
if (ss != null && zip != null) {
Pool output = new ImagePluginStack.OrderedResourcePool(in.getByteOrder(),
((PoolImpl) in).getStringTable());
ModulePool output = new ImagePluginStack.OrderedResourcePool(in.getByteOrder(),
((ModulePoolImpl) in).getStringTable());
ss.visit(in, output);
zip.visit(output, out);
} else if (ss != null) {
@ -76,16 +73,16 @@ public final class DefaultCompressPlugin implements TransformerPlugin, ResourceP
}
@Override
public void previsit(Pool resources, StringTable strings) {
public void previsit(ModulePool resources, StringTable strings) {
if (ss != null) {
ss.previsit(resources, strings);
}
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.COMPRESSOR);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.COMPRESSOR);
return Collections.unmodifiableSet(set);
}

View File

@ -32,8 +32,8 @@ import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import jdk.tools.jlink.plugin.TransformerPlugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.internal.Utils;
/**
@ -51,9 +51,9 @@ public final class ExcludeFilesPlugin implements TransformerPlugin {
}
@Override
public void visit(Pool in, Pool out) {
in.visit((file) -> {
if (!file.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)) {
public void visit(ModulePool in, ModulePool out) {
in.transformAndCopy((file) -> {
if (!file.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
file = predicate.test(file.getPath()) ? file : null;
}
return file;
@ -61,9 +61,9 @@ public final class ExcludeFilesPlugin implements TransformerPlugin {
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.FILTER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.FILTER);
return Collections.unmodifiableSet(set);
}

View File

@ -32,7 +32,8 @@ import java.util.Set;
import java.util.function.Predicate;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.TransformerPlugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.internal.Utils;
/**
@ -50,9 +51,9 @@ public final class ExcludePlugin implements TransformerPlugin {
}
@Override
public void visit(Pool in, Pool out) {
in.visit((resource) -> {
if (resource.getType().equals(Pool.ModuleDataType.CLASS_OR_RESOURCE)) {
public void visit(ModulePool in, ModulePool out) {
in.transformAndCopy((resource) -> {
if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
resource = predicate.test(resource.getPath()) ? resource : null;
}
return resource;
@ -75,9 +76,9 @@ public final class ExcludePlugin implements TransformerPlugin {
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.FILTER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.FILTER);
return Collections.unmodifiableSet(set);
}

View File

@ -40,9 +40,10 @@ import java.util.TreeSet;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import jdk.tools.jlink.plugin.TransformerPlugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.internal.Utils;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.PluginException;
/**
@ -102,24 +103,24 @@ public final class ExcludeVMPlugin implements TransformerPlugin {
* e.g.: /java.base/native/amd64/server/libjvm.so
* /java.base/native/server/libjvm.dylib
*/
private List<Pool.ModuleData> getVMs(Pool in) {
private List<ModuleEntry> getVMs(ModulePool in) {
String jvmlib = jvmlib();
List<Pool.ModuleData> ret = in.getModule("java.base").getContent().stream().filter((t) -> {
List<ModuleEntry> ret = in.findModule("java.base").get().entries().filter((t) -> {
return t.getPath().endsWith("/" + jvmlib);
}).collect(Collectors.toList());
return ret;
}
@Override
public void visit(Pool in, Pool out) {
public void visit(ModulePool in, ModulePool out) {
String jvmlib = jvmlib();
TreeSet<Jvm> existing = new TreeSet<>(new JvmComparator());
TreeSet<Jvm> removed = new TreeSet<>(new JvmComparator());
if (!keepAll) {
// First retrieve all available VM names and removed VM
List<Pool.ModuleData> jvms = getVMs(in);
List<ModuleEntry> jvms = getVMs(in);
for (Jvm jvm : Jvm.values()) {
for (Pool.ModuleData md : jvms) {
for (ModuleEntry md : jvms) {
if (md.getPath().endsWith("/" + jvm.getName() + "/" + jvmlib)) {
existing.add(jvm);
if (isRemoved(md)) {
@ -137,9 +138,9 @@ public final class ExcludeVMPlugin implements TransformerPlugin {
}
// Rewrite the jvm.cfg file.
in.visit((file) -> {
in.transformAndCopy((file) -> {
if (!keepAll) {
if (file.getType().equals(ModuleDataType.NATIVE_LIB)) {
if (file.getType().equals(ModuleEntry.Type.NATIVE_LIB)) {
if (file.getPath().endsWith(JVM_CFG)) {
try {
file = handleJvmCfgFile(file, existing, removed);
@ -155,14 +156,14 @@ public final class ExcludeVMPlugin implements TransformerPlugin {
}
private boolean isRemoved(Pool.ModuleData file) {
private boolean isRemoved(ModuleEntry file) {
return !predicate.test(file.getPath());
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.FILTER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.FILTER);
return Collections.unmodifiableSet(set);
}
@ -217,7 +218,7 @@ public final class ExcludeVMPlugin implements TransformerPlugin {
}
}
private Pool.ModuleData handleJvmCfgFile(Pool.ModuleData orig,
private ModuleEntry handleJvmCfgFile(ModuleEntry orig,
TreeSet<Jvm> existing,
TreeSet<Jvm> removed) throws IOException {
if (keepAll) {
@ -253,7 +254,7 @@ public final class ExcludeVMPlugin implements TransformerPlugin {
byte[] content = builder.toString().getBytes(StandardCharsets.UTF_8);
return Pool.newImageFile(orig.getModule(),
return ModuleEntry.create(orig.getModule(),
orig.getPath(),
orig.getType(),
new ByteArrayInputStream(content), content.length);

View File

@ -41,10 +41,10 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import jdk.tools.jlink.internal.ModuleEntryImpl;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
import jdk.tools.jlink.internal.Utils;
@ -68,12 +68,12 @@ public class FileCopierPlugin implements TransformerPlugin {
/**
* Symbolic link to another path.
*/
public static abstract class SymImageFile extends Pool.ModuleData {
public static abstract class SymImageFile extends ModuleEntryImpl {
private final String targetPath;
public SymImageFile(String targetPath, String module, String path,
Pool.ModuleDataType type, InputStream stream, long size) {
ModuleEntry.Type type, InputStream stream, long size) {
super(module, path, type, stream, size);
this.targetPath = targetPath;
}
@ -86,7 +86,7 @@ public class FileCopierPlugin implements TransformerPlugin {
private static final class SymImageFileImpl extends SymImageFile {
public SymImageFileImpl(String targetPath, Path file, String module,
String path, ModuleDataType type) {
String path, ModuleEntry.Type type) {
super(targetPath, module, path, type, newStream(file), length(file));
}
}
@ -110,11 +110,11 @@ public class FileCopierPlugin implements TransformerPlugin {
private static final class DirectoryCopy implements FileVisitor<Path> {
private final Path source;
private final Pool pool;
private final ModulePool pool;
private final String targetDir;
private final List<SymImageFile> symlinks = new ArrayList<>();
DirectoryCopy(Path source, Pool pool, String targetDir) {
DirectoryCopy(Path source, ModulePool pool, String targetDir) {
this.source = source;
this.pool = pool;
this.targetDir = targetDir;
@ -148,7 +148,7 @@ public class FileCopierPlugin implements TransformerPlugin {
}
SymImageFileImpl impl = new SymImageFileImpl(symTarget.toString(),
file, path, Objects.requireNonNull(file.getFileName()).toString(),
Pool.ModuleDataType.OTHER);
ModuleEntry.Type.OTHER);
symlinks.add(impl);
} else {
addFile(pool, file, path);
@ -172,14 +172,14 @@ public class FileCopierPlugin implements TransformerPlugin {
}
}
private static void addFile(Pool pool, Path file, String path)
private static void addFile(ModulePool pool, Path file, String path)
throws IOException {
Objects.requireNonNull(pool);
Objects.requireNonNull(file);
Objects.requireNonNull(path);
ModuleData impl = Pool.newImageFile(FAKE_MODULE,
ModuleEntry impl = ModuleEntry.create(FAKE_MODULE,
"/" + FAKE_MODULE + "/other/" + path,
Pool.ModuleDataType.OTHER, newStream(file), length(file));
ModuleEntry.Type.OTHER, newStream(file), length(file));
try {
pool.add(impl);
} catch (Exception ex) {
@ -188,9 +188,9 @@ public class FileCopierPlugin implements TransformerPlugin {
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.TRANSFORMER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.TRANSFORMER);
return Collections.unmodifiableSet(set);
}
@ -239,8 +239,8 @@ public class FileCopierPlugin implements TransformerPlugin {
}
@Override
public void visit(Pool in, Pool out) {
in.visit((file) -> {
public void visit(ModulePool in, ModulePool out) {
in.transformAndCopy((file) -> {
return file;
}, out);

View File

@ -33,8 +33,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
/**
@ -60,8 +61,8 @@ public final class GenerateJLIClassesPlugin implements TransformerPlugin {
}
@Override
public Set<PluginType> getType() {
return Collections.singleton(CATEGORY.TRANSFORMER);
public Set<Category> getType() {
return Collections.singleton(Category.TRANSFORMER);
}
@Override
@ -75,8 +76,8 @@ public final class GenerateJLIClassesPlugin implements TransformerPlugin {
}
@Override
public Set<STATE> getState() {
return EnumSet.of(STATE.AUTO_ENABLED, STATE.FUNCTIONAL);
public Set<State> getState() {
return EnumSet.of(State.AUTO_ENABLED, State.FUNCTIONAL);
}
@Override
@ -151,8 +152,8 @@ public final class GenerateJLIClassesPlugin implements TransformerPlugin {
}
@Override
public void visit(Pool in, Pool out) {
for (Pool.ModuleData data : in.getContent()) {
public void visit(ModulePool in, ModulePool out) {
in.entries().forEach(data -> {
if (("/java.base/" + BMH + ".class").equals(data.getPath())) {
// Add BoundMethodHandle unchanged
out.add(data);
@ -162,11 +163,11 @@ public final class GenerateJLIClassesPlugin implements TransformerPlugin {
out.add(data);
}
}
}
});
}
@SuppressWarnings("unchecked")
private void generateConcreteClass(String types, Pool.ModuleData data, Pool out) {
private void generateConcreteClass(String types, ModuleEntry data, ModulePool out) {
try {
// Generate class
Map.Entry<String, byte[]> result = (Map.Entry<String, byte[]>)
@ -175,9 +176,9 @@ public final class GenerateJLIClassesPlugin implements TransformerPlugin {
byte[] bytes = result.getValue();
// Add class to pool
Pool.ModuleData ndata = new Pool.ModuleData(data.getModule(),
ModuleEntry ndata = ModuleEntry.create(data.getModule(),
"/java.base/" + className + ".class",
Pool.ModuleDataType.CLASS_OR_RESOURCE,
ModuleEntry.Type.CLASS_OR_RESOURCE,
new ByteArrayInputStream(bytes), bytes.length);
if (!out.contains(ndata)) {
out.add(ndata);

View File

@ -34,6 +34,7 @@ import java.util.IllformedLocaleException;
import java.util.Locale;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Pattern;
@ -44,9 +45,10 @@ import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.tools.jlink.internal.ResourcePrevisitor;
import jdk.tools.jlink.internal.StringTable;
import jdk.tools.jlink.internal.Utils;
import jdk.tools.jlink.plugin.LinkModule;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
/**
@ -112,19 +114,19 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr
}
@Override
public void visit(Pool in, Pool out) {
in.visit((resource) -> {
public void visit(ModulePool in, ModulePool out) {
in.transformAndCopy((resource) -> {
if (resource.getModule().equals(MODULENAME)) {
String path = resource.getPath();
resource = predicate.test(path) ? resource: null;
if (resource != null &&
resource.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)) {
resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
byte[] bytes = resource.getBytes();
ClassReader cr = new ClassReader(bytes);
if (Arrays.stream(cr.getInterfaces())
.anyMatch(i -> i.contains(METAINFONAME)) &&
stripUnsupportedLocales(bytes, cr)) {
resource = new Pool.ModuleData(MODULENAME, path,
resource = ModuleEntry.create(MODULENAME, path,
resource.getType(),
new ByteArrayInputStream(bytes), bytes.length);
}
@ -135,9 +137,9 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.FILTER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.FILTER);
return Collections.unmodifiableSet(set);
}
@ -172,12 +174,13 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr
}
@Override
public void previsit(Pool resources, StringTable strings) {
public void previsit(ModulePool resources, StringTable strings) {
final Pattern p = Pattern.compile(".*((Data_)|(Names_))(?<tag>.*)\\.class");
Pool.Module module = resources.getModule(MODULENAME);
Optional<LinkModule> optMod = resources.findModule(MODULENAME);
// jdk.localedata module validation
if (module != null) {
if (optMod.isPresent()) {
LinkModule module = optMod.get();
Set<String> packages = module.getAllPackages();
if (!packages.containsAll(LOCALEDATA_PACKAGES)) {
throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".missingpackages") +
@ -186,7 +189,7 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr
.collect(Collectors.joining(",\n\t")));
}
available = Stream.concat(module.getContent().stream()
available = Stream.concat(module.entries()
.map(md -> p.matcher(md.getPath()))
.filter(m -> m.matches())
.map(m -> m.group("tag").replaceAll("_", "-")),

View File

@ -24,7 +24,6 @@
*/
package jdk.tools.jlink.internal.plugins;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
@ -287,9 +286,9 @@ public final class OptimizationPlugin extends AsmPlugin {
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.TRANSFORMER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.TRANSFORMER);
return Collections.unmodifiableSet(set);
}
}

View File

@ -36,9 +36,8 @@ import java.util.Map;
import java.util.Set;
import java.util.function.ToIntFunction;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
import jdk.tools.jlink.internal.Utils;
@ -62,15 +61,15 @@ public final class OrderResourcesPlugin implements TransformerPlugin {
}
static class SortWrapper {
private final ModuleData resource;
private final ModuleEntry resource;
private final int ordinal;
SortWrapper(ModuleData resource, int ordinal) {
SortWrapper(ModuleEntry resource, int ordinal) {
this.resource = resource;
this.ordinal = ordinal;
}
ModuleData getResource() {
ModuleEntry getResource() {
return resource;
}
@ -95,7 +94,7 @@ public final class OrderResourcesPlugin implements TransformerPlugin {
return path;
}
private int getOrdinal(ModuleData resource) {
private int getOrdinal(ModuleEntry resource) {
String path = resource.getPath();
Integer value = orderedPaths.get(stripModule(path));
@ -126,23 +125,23 @@ public final class OrderResourcesPlugin implements TransformerPlugin {
}
@Override
public void visit(Pool in, Pool out) {
in.getContent().stream()
public void visit(ModulePool in, ModulePool out) {
in.entries()
.filter(resource -> resource.getType()
.equals(ModuleDataType.CLASS_OR_RESOURCE))
.equals(ModuleEntry.Type.CLASS_OR_RESOURCE))
.map((resource) -> new SortWrapper(resource, getOrdinal(resource)))
.sorted(OrderResourcesPlugin::compare)
.forEach((wrapper) -> out.add(wrapper.getResource()));
in.getContent().stream()
in.entries()
.filter(other -> !other.getType()
.equals(ModuleDataType.CLASS_OR_RESOURCE))
.equals(ModuleEntry.Type.CLASS_OR_RESOURCE))
.forEach((other) -> out.add(other));
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.SORTER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.SORTER);
return Collections.unmodifiableSet(set);
}

View File

@ -24,34 +24,33 @@
*/
package jdk.tools.jlink.internal.plugins;
import java.lang.module.ModuleDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Properties;
import java.util.Set;
import java.util.function.Function;
import jdk.tools.jlink.internal.Utils;
import jdk.tools.jlink.plugin.ExecutableImage;
import jdk.tools.jlink.plugin.PluginContext;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.PostProcessorPlugin;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.Plugin.Category;
import jdk.tools.jlink.plugin.Plugin.State;
import jdk.tools.jlink.plugin.TransformerPlugin;
/**
* This plugin adds/deletes information for 'release' file.
*/
public final class ReleaseInfoPlugin implements PostProcessorPlugin {
public final class ReleaseInfoPlugin implements TransformerPlugin {
// option name
public static final String NAME = "release-info";
public static final String KEYS = "keys";
private final Map<String, String> release = new HashMap<>();
@Override
public Set<PluginType> getType() {
return Collections.singleton(CATEGORY.PROCESSOR);
public Set<Category> getType() {
return Collections.singleton(Category.METAINFO_ADDER);
}
@Override
@ -65,8 +64,8 @@ public final class ReleaseInfoPlugin implements PostProcessorPlugin {
}
@Override
public Set<STATE> getState() {
return EnumSet.of(STATE.FUNCTIONAL);
public Set<State> getState() {
return EnumSet.of(State.FUNCTIONAL);
}
@Override
@ -80,49 +79,49 @@ public final class ReleaseInfoPlugin implements PostProcessorPlugin {
}
@Override
public void configure(Map<String, String> config, PluginContext ctx) {
Properties release = ctx != null? ctx.getReleaseProperties() : null;
if (release != null) {
String operation = config.get(NAME);
switch (operation) {
case "add": {
// leave it to open-ended! source, java_version, java_full_version
// can be passed via this option like:
//
// --release-info add:build_type=fastdebug,source=openjdk,java_version=9
// and put whatever value that was passed in command line.
public void configure(Map<String, String> config) {
String operation = config.get(NAME);
switch (operation) {
case "add": {
// leave it to open-ended! source, java_version, java_full_version
// can be passed via this option like:
//
// --release-info add:build_type=fastdebug,source=openjdk,java_version=9
// and put whatever value that was passed in command line.
config.keySet().stream().
filter(s -> !NAME.equals(s)).
forEach(s -> release.put(s, config.get(s)));
}
break;
case "del": {
// --release-info del:keys=openjdk,java_version
String[] keys = Utils.listParser.apply(config.get(KEYS));
for (String k : keys) {
release.remove(k);
}
}
break;
default: {
// --release-info <file>
try (FileInputStream fis = new FileInputStream(operation)) {
release.load(fis);
} catch (IOException exp) {
throw new RuntimeException(exp);
}
}
break;
config.keySet().stream().
filter(s -> !NAME.equals(s)).
forEach(s -> release.put(s, config.get(s)));
}
break;
case "del": {
// --release-info del:keys=openjdk,java_version
String[] keys = Utils.listParser.apply(config.get(KEYS));
for (String k : keys) {
release.remove(k);
}
}
break;
default: {
// --release-info <file>
Properties props = new Properties();
try (FileInputStream fis = new FileInputStream(operation)) {
props.load(fis);
} catch (IOException exp) {
throw new RuntimeException(exp);
}
props.forEach((k, v) -> release.put(k.toString(), v.toString()));
}
break;
}
}
@Override
public List<String> process(ExecutableImage image) {
// Nothing to do! Release info copied already during configure!
return Collections.emptyList();
public void visit(ModulePool in, ModulePool out) {
in.transformAndCopy(Function.identity(), out);
out.getReleaseProperties().putAll(in.getReleaseProperties());
out.getReleaseProperties().putAll(release);
}
}

View File

@ -56,11 +56,11 @@ import java.util.stream.Collectors;
import jdk.internal.jimage.decompressor.CompressIndexes;
import jdk.internal.jimage.decompressor.SignatureParser;
import jdk.internal.jimage.decompressor.StringSharingDecompressor;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.plugin.TransformerPlugin;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.internal.ResourcePrevisitor;
import jdk.tools.jlink.internal.StringTable;
import jdk.tools.jlink.internal.Utils;
@ -228,7 +228,7 @@ public class StringSharingPlugin implements TransformerPlugin, ResourcePrevisito
}
}
public byte[] transform(ModuleData resource, Pool out,
public byte[] transform(ModuleEntry resource, ModulePool out,
StringTable strings) throws IOException, Exception {
byte[] content = resource.getBytes();
ClassFile cf;
@ -243,7 +243,7 @@ public class StringSharingPlugin implements TransformerPlugin, ResourcePrevisito
}
@SuppressWarnings("fallthrough")
private byte[] optimize(ModuleData resource, Pool resources,
private byte[] optimize(ModuleEntry resource, ModulePool resources,
StringTable strings,
Set<Integer> descriptorIndexes, byte[] content) throws Exception {
DataInputStream stream = new DataInputStream(new ByteArrayInputStream(content));
@ -348,27 +348,27 @@ public class StringSharingPlugin implements TransformerPlugin, ResourcePrevisito
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.COMPRESSOR);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.COMPRESSOR);
return Collections.unmodifiableSet(set);
}
@Override
public void visit(Pool in, Pool result) {
public void visit(ModulePool in, ModulePool result) {
CompactCPHelper visit = new CompactCPHelper();
in.visit((resource) -> {
ModuleData res = resource;
in.transformAndCopy((resource) -> {
ModuleEntry res = resource;
if (predicate.test(resource.getPath()) && resource.getPath().endsWith(".class")) {
byte[] compressed = null;
try {
compressed = visit.transform(resource, result, ((PoolImpl) in).getStringTable());
compressed = visit.transform(resource, result, ((ModulePoolImpl) in).getStringTable());
} catch (Exception ex) {
throw new PluginException(ex);
}
res = PoolImpl.newCompressedResource(resource,
res = ModulePoolImpl.newCompressedResource(resource,
ByteBuffer.wrap(compressed), getName(), null,
((PoolImpl) in).getStringTable(), in.getByteOrder());
((ModulePoolImpl) in).getStringTable(), in.getByteOrder());
}
return res;
}, result);
@ -405,10 +405,10 @@ public class StringSharingPlugin implements TransformerPlugin, ResourcePrevisito
}
@Override
public void previsit(Pool resources, StringTable strings) {
public void previsit(ModulePool resources, StringTable strings) {
CompactCPHelper preVisit = new CompactCPHelper();
for (ModuleData resource : resources.getContent()) {
if (resource.getType().equals(Pool.ModuleDataType.CLASS_OR_RESOURCE)
resources.entries().forEach(resource -> {
if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)
&& resource.getPath().endsWith(".class") && predicate.test(resource.getPath())) {
try {
preVisit.transform(resource, null, strings);
@ -416,6 +416,6 @@ public class StringSharingPlugin implements TransformerPlugin, ResourcePrevisito
throw new PluginException(ex);
}
}
}
});
}
}

View File

@ -29,14 +29,12 @@ import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
/**
@ -61,9 +59,9 @@ public final class StripDebugPlugin implements TransformerPlugin {
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.TRANSFORMER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.TRANSFORMER);
return Collections.unmodifiableSet(set);
}
@ -73,11 +71,11 @@ public final class StripDebugPlugin implements TransformerPlugin {
}
@Override
public void visit(Pool in, Pool out) {
public void visit(ModulePool in, ModulePool out) {
//remove *.diz files as well as debug attributes.
in.visit((resource) -> {
ModuleData res = resource;
if (resource.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)) {
in.transformAndCopy((resource) -> {
ModuleEntry res = resource;
if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
String path = resource.getPath();
if (path.endsWith(".class")) {
if (path.endsWith("module-info.class")) {
@ -87,7 +85,7 @@ public final class StripDebugPlugin implements TransformerPlugin {
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
reader.accept(writer, ClassReader.SKIP_DEBUG);
byte[] content = writer.toByteArray();
res = Pool.newResource(path, new ByteArrayInputStream(content), content.length);
res = ModuleEntry.create(path, new ByteArrayInputStream(content), content.length);
}
}
} else if (predicate.test(res.getPath())) {

View File

@ -26,9 +26,9 @@ package jdk.tools.jlink.internal.plugins;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
/**
@ -45,16 +45,16 @@ public final class StripNativeCommandsPlugin implements TransformerPlugin {
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.FILTER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.FILTER);
return Collections.unmodifiableSet(set);
}
@Override
public void visit(Pool in, Pool out) {
in.visit((file) -> {
return file.getType() == Pool.ModuleDataType.NATIVE_CMD ? null : file;
public void visit(ModulePool in, ModulePool out) {
in.transformAndCopy((file) -> {
return file.getType() == ModuleEntry.Type.NATIVE_CMD ? null : file;
}, out);
}

View File

@ -36,6 +36,7 @@ import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -50,9 +51,10 @@ import jdk.internal.org.objectweb.asm.Opcodes;
import static jdk.internal.org.objectweb.asm.Opcodes.*;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
import jdk.tools.jlink.internal.plugins.SystemModuleDescriptorPlugin.Builder.*;
import jdk.tools.jlink.plugin.ModuleEntry;
/**
* Jlink plugin to reconstitute module descriptors for installed modules.
@ -81,8 +83,8 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin {
}
@Override
public Set<PluginType> getType() {
return Collections.singleton(CATEGORY.TRANSFORMER);
public Set<Category> getType() {
return Collections.singleton(Category.TRANSFORMER);
}
@Override
@ -96,9 +98,9 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin {
}
@Override
public Set<STATE> getState() {
return enabled ? EnumSet.of(STATE.AUTO_ENABLED, STATE.FUNCTIONAL)
: EnumSet.of(STATE.DISABLED);
public Set<State> getState() {
return enabled ? EnumSet.of(State.AUTO_ENABLED, State.FUNCTIONAL)
: EnumSet.of(State.DISABLED);
}
@Override
@ -110,7 +112,7 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin {
@Override
public void visit(Pool in, Pool out) {
public void visit(ModulePool in, ModulePool out) {
if (!enabled) {
throw new PluginException(NAME + " was set");
}
@ -119,13 +121,14 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin {
// generate the byte code to create ModuleDescriptors
// skip parsing module-info.class and skip name check
for (Pool.Module module : in.getModules()) {
Pool.ModuleData data = module.get("module-info.class");
if (data == null) {
in.modules().forEach(module -> {
Optional<ModuleEntry> optData = module.findEntry("module-info.class");
if (! optData.isPresent()) {
// automatic module not supported yet
throw new PluginException("module-info.class not found for " +
module.getName() + " module");
}
ModuleEntry data = optData.get();
assert module.getName().equals(data.getModule());
try {
ByteArrayInputStream bain = new ByteArrayInputStream(data.getBytes());
@ -141,7 +144,7 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin {
ModuleInfoRewriter minfoWriter =
new ModuleInfoRewriter(bain, mbuilder.conceals());
// replace with the overridden version
data = new Pool.ModuleData(data.getModule(),
data = ModuleEntry.create(data.getModule(),
data.getPath(),
data.getType(),
minfoWriter.stream(),
@ -151,19 +154,17 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin {
} catch (IOException e) {
throw new PluginException(e);
}
}
});
// Generate the new class
ClassWriter cwriter = builder.build();
for (Pool.ModuleData data : in.getContent()) {
in.entries().forEach(data -> {
if (data.getPath().endsWith("module-info.class"))
continue;
return;
if (builder.isOverriddenClass(data.getPath())) {
byte[] bytes = cwriter.toByteArray();
Pool.ModuleData ndata =
new Pool.ModuleData(data.getModule(),
ModuleEntry ndata =
ModuleEntry.create(data.getModule(),
data.getPath(),
data.getType(),
new ByteArrayInputStream(bytes),
@ -172,7 +173,7 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin {
} else {
out.add(data);
}
}
});
}
/*

View File

@ -34,10 +34,9 @@ import java.util.Set;
import java.util.function.Predicate;
import java.util.zip.Deflater;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
import jdk.tools.jlink.internal.Utils;
@ -68,9 +67,9 @@ public final class ZipPlugin implements TransformerPlugin {
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.COMPRESSOR);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.COMPRESSOR);
return Collections.unmodifiableSet(set);
}
@ -124,16 +123,16 @@ public final class ZipPlugin implements TransformerPlugin {
}
@Override
public void visit(Pool in, Pool out) {
in.visit((resource) -> {
ModuleData res = resource;
if (resource.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)
public void visit(ModulePool in, ModulePool out) {
in.transformAndCopy((resource) -> {
ModuleEntry res = resource;
if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)
&& predicate.test(resource.getPath())) {
byte[] compressed;
compressed = compress(resource.getBytes());
res = PoolImpl.newCompressedResource(resource,
res = ModulePoolImpl.newCompressedResource(resource,
ByteBuffer.wrap(compressed), getName(), null,
((PoolImpl) in).getStringTable(), in.getByteOrder());
((ModulePoolImpl) in).getStringTable(), in.getByteOrder());
}
return res;
}, out);

View File

@ -26,9 +26,9 @@ package jdk.tools.jlink.internal.plugins.asm;
import java.util.Objects;
import jdk.tools.jlink.plugin.TransformerPlugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.internal.ModulePoolImpl;
/**
* Extend this class to develop your own plugin in order to transform jimage
@ -41,17 +41,17 @@ public abstract class AsmPlugin implements TransformerPlugin {
}
@Override
public void visit(Pool allContent, Pool outResources) {
public void visit(ModulePool allContent, ModulePool outResources) {
Objects.requireNonNull(allContent);
Objects.requireNonNull(outResources);
PoolImpl resources = new PoolImpl(allContent.getByteOrder());
for(ModuleData md : allContent.getContent()) {
if(md.getType().equals(Pool.ModuleDataType.CLASS_OR_RESOURCE)) {
ModulePoolImpl resources = new ModulePoolImpl(allContent.getByteOrder());
allContent.entries().forEach(md -> {
if(md.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
resources.add(md);
} else {
outResources.add(md);
}
}
});
AsmPools pools = new AsmPools(resources);
visit(pools);
pools.fillOutputResources(outResources);

View File

@ -24,13 +24,12 @@
*/
package jdk.tools.jlink.internal.plugins.asm;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.List;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
/**
* A pool of ClassReader and other resource files.
@ -138,14 +137,14 @@ public interface AsmPool {
* @return The ClassReader or null if the class is not found.
* @throws jdk.tools.jlink.plugin.PluginException
*/
public ClassReader getClassReader(Pool.ModuleData res);
public ClassReader getClassReader(ModuleEntry res);
/**
* Returns all the classes contained in the writable pool.
*
* @return The collection of classes.
*/
public Collection<Pool.ModuleData> getClasses();
public Collection<ModuleEntry> getClasses();
}
/**
@ -185,14 +184,14 @@ public interface AsmPool {
* @param res The java resource
* @return The Resource or null if the resource is not found.
*/
public ResourceFile getResourceFile(Pool.ModuleData res);
public ResourceFile getResourceFile(ModuleEntry res);
/**
* Returns all the resources contained in the writable pool.
*
* @return The array of resources.
*/
public Collection<Pool.ModuleData> getResourceFiles();
public Collection<ModuleEntry> getResourceFiles();
}
/**
@ -206,7 +205,7 @@ public interface AsmPool {
* @return The resource paths ordered in the way to use for storage in the jimage.
* @throws jdk.tools.jlink.plugin.PluginException
*/
public List<String> sort(Pool resources);
public List<String> sort(ModulePool resources);
}
/**
@ -237,7 +236,7 @@ public interface AsmPool {
*
* @return The classes.
*/
public Collection<Pool.ModuleData> getClasses();
public Collection<ModuleEntry> getClasses();
/**
* Returns the resources contained in the pool. Resources are all the file
@ -245,7 +244,7 @@ public interface AsmPool {
*
* @return The array of resource files.
*/
public Collection<Pool.ModuleData> getResourceFiles();
public Collection<ModuleEntry> getResourceFiles();
/**
* Retrieves a resource based on the binary name. This name doesn't contain
@ -266,7 +265,7 @@ public interface AsmPool {
* @param res The resource
* @return The resource file or null if it doesn't exist.
*/
public ResourceFile getResourceFile(Pool.ModuleData res);
public ResourceFile getResourceFile(ModuleEntry res);
/**
* Retrieve a ClassReader from the pool.
@ -284,7 +283,7 @@ public interface AsmPool {
* @return A reader or null if the class is unknown
* @throws jdk.tools.jlink.plugin.PluginException
*/
public ClassReader getClassReader(Pool.ModuleData res);
public ClassReader getClassReader(ModuleEntry res);
/**
* To visit the set of ClassReaders.
@ -310,6 +309,6 @@ public interface AsmPool {
* @param output The pool used to fill the jimage.
* @throws jdk.tools.jlink.plugin.PluginException
*/
public void fillOutputResources(Pool output);
public void fillOutputResources(ModulePool output);
}

View File

@ -41,15 +41,14 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.tools.jlink.internal.ImageFileCreator;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModulePool;
/**
* A pool of ClassReader and other resource files. This class allows to
@ -94,7 +93,7 @@ final class AsmPoolImpl implements AsmModulePool {
}
byte[] content = writer.toByteArray();
ModuleData res = Pool.newResource(path,
ModuleEntry res = ModuleEntry.create(path,
new ByteArrayInputStream(content), content.length);
transformedClasses.put(className, res);
}
@ -108,7 +107,7 @@ final class AsmPoolImpl implements AsmModulePool {
public void forgetClass(String className) {
Objects.requireNonNull(className);
// do we have a resource?
ModuleData res = transformedClasses.get(className);
ModuleEntry res = transformedClasses.get(className);
if (res == null) {
res = inputClasses.get(className);
if (res == null) {
@ -130,7 +129,7 @@ final class AsmPoolImpl implements AsmModulePool {
@Override
public ClassReader getClassReader(String binaryName) {
Objects.requireNonNull(binaryName);
ModuleData res = transformedClasses.get(binaryName);
ModuleEntry res = transformedClasses.get(binaryName);
ClassReader reader = null;
if (res != null) {
reader = getClassReader(res);
@ -144,16 +143,16 @@ final class AsmPoolImpl implements AsmModulePool {
* @return The array of transformed classes.
*/
@Override
public Collection<ModuleData> getClasses() {
List<ModuleData> classes = new ArrayList<>();
for (Entry<String, ModuleData> entry : transformedClasses.entrySet()) {
public Collection<ModuleEntry> getClasses() {
List<ModuleEntry> classes = new ArrayList<>();
for (Entry<String, ModuleEntry> entry : transformedClasses.entrySet()) {
classes.add(entry.getValue());
}
return classes;
}
@Override
public ClassReader getClassReader(ModuleData res) {
public ClassReader getClassReader(ModuleEntry res) {
return newClassReader(res.getBytes());
}
}
@ -176,7 +175,7 @@ final class AsmPoolImpl implements AsmModulePool {
public void addResourceFile(ResourceFile resFile) {
Objects.requireNonNull(resFile);
String path = toResourceNamePath(resFile.getPath());
ModuleData res = Pool.newResource(path, resFile.getContent());
ModuleEntry res = ModuleEntry.create(path, resFile.getContent());
transformedResources.put(resFile.getPath(), res);
}
@ -191,7 +190,7 @@ final class AsmPoolImpl implements AsmModulePool {
Objects.requireNonNull(resourceName);
String path = toResourceNamePath(resourceName);
// do we have a resource?
ModuleData res = transformedResources.get(resourceName);
ModuleEntry res = transformedResources.get(resourceName);
if (res == null) {
res = inputResources.get(resourceName);
if (res == null) {
@ -212,7 +211,7 @@ final class AsmPoolImpl implements AsmModulePool {
@Override
public ResourceFile getResourceFile(String name) {
Objects.requireNonNull(name);
ModuleData res = transformedResources.get(name);
ModuleEntry res = transformedResources.get(name);
ResourceFile resFile = null;
if (res != null) {
resFile = getResourceFile(res);
@ -226,24 +225,24 @@ final class AsmPoolImpl implements AsmModulePool {
* @return The array of transformed classes.
*/
@Override
public Collection<ModuleData> getResourceFiles() {
List<ModuleData> resources = new ArrayList<>();
for (Entry<String, ModuleData> entry : transformedResources.entrySet()) {
public Collection<ModuleEntry> getResourceFiles() {
List<ModuleEntry> resources = new ArrayList<>();
for (Entry<String, ModuleEntry> entry : transformedResources.entrySet()) {
resources.add(entry.getValue());
}
return resources;
}
@Override
public ResourceFile getResourceFile(ModuleData res) {
public ResourceFile getResourceFile(ModuleEntry res) {
return new ResourceFile(toJavaBinaryResourceName(res.getPath()),
res.getBytes());
}
}
private final Pool jimageResources;
private final Map<String, ModuleData> inputClasses;
private final Map<String, ModuleData> inputResources;
private final ModulePool jimageResources;
private final Map<String, ModuleEntry> inputClasses;
private final Map<String, ModuleEntry> inputResources;
private final Map<String, String> inputClassPackageMapping;
private final Map<String, String> inputOtherPackageMapping;
@ -254,9 +253,9 @@ final class AsmPoolImpl implements AsmModulePool {
private Sorter sorter;
private final Map<String, ModuleData> transformedClasses
private final Map<String, ModuleEntry> transformedClasses
= new LinkedHashMap<>();
private final Map<String, ModuleData> transformedResources
private final Map<String, ModuleEntry> transformedResources
= new LinkedHashMap<>();
private final List<String> forgetResources = new ArrayList<>();
private final Map<String, String> newPackageMapping = new HashMap<>();
@ -274,7 +273,7 @@ final class AsmPoolImpl implements AsmModulePool {
* @param pools The resource pools.
* @param descriptor The module descriptor.
*/
AsmPoolImpl(Pool inputResources, String moduleName,
AsmPoolImpl(ModulePool inputResources, String moduleName,
AsmPools pools,
ModuleDescriptor descriptor) {
Objects.requireNonNull(inputResources);
@ -285,11 +284,11 @@ final class AsmPoolImpl implements AsmModulePool {
this.moduleName = moduleName;
this.pools = pools;
this.descriptor = descriptor;
Map<String, ModuleData> classes = new LinkedHashMap<>();
Map<String, ModuleData> resources = new LinkedHashMap<>();
Map<String, ModuleEntry> classes = new LinkedHashMap<>();
Map<String, ModuleEntry> resources = new LinkedHashMap<>();
Map<String, String> packageClassToModule = new HashMap<>();
Map<String, String> packageOtherToModule = new HashMap<>();
for (ModuleData res : inputResources.getContent()) {
inputResources.entries().forEach(res -> {
if (res.getPath().endsWith(".class")) {
classes.put(toJavaBinaryClassName(res.getPath()), res);
} else {
@ -305,7 +304,7 @@ final class AsmPoolImpl implements AsmModulePool {
packageOtherToModule.put(split[1], res.getModule());
}
}
}
});
this.inputClasses = Collections.unmodifiableMap(classes);
this.inputResources = Collections.unmodifiableMap(resources);
@ -356,7 +355,7 @@ final class AsmPoolImpl implements AsmModulePool {
* @return The array of classes.
*/
@Override
public Collection<ModuleData> getClasses() {
public Collection<ModuleEntry> getClasses() {
return inputClasses.values();
}
@ -367,7 +366,7 @@ final class AsmPoolImpl implements AsmModulePool {
* @return The array of classes.
*/
@Override
public Collection<ModuleData> getResourceFiles() {
public Collection<ModuleEntry> getResourceFiles() {
return inputResources.values();
}
@ -385,7 +384,7 @@ final class AsmPoolImpl implements AsmModulePool {
@Override
public ResourceFile getResourceFile(String binaryName) {
Objects.requireNonNull(binaryName);
ModuleData res = inputResources.get(binaryName);
ModuleEntry res = inputResources.get(binaryName);
ResourceFile resFile = null;
if (res != null) {
resFile = getResourceFile(res);
@ -402,7 +401,7 @@ final class AsmPoolImpl implements AsmModulePool {
@Override
public ClassReader getClassReader(String binaryName) {
Objects.requireNonNull(binaryName);
ModuleData res = inputClasses.get(binaryName);
ModuleEntry res = inputClasses.get(binaryName);
ClassReader reader = null;
if (res != null) {
reader = getClassReader(res);
@ -411,13 +410,13 @@ final class AsmPoolImpl implements AsmModulePool {
}
@Override
public ResourceFile getResourceFile(ModuleData res) {
public ResourceFile getResourceFile(ModuleEntry res) {
return new ResourceFile(toJavaBinaryResourceName(res.getPath()),
res.getBytes());
}
@Override
public ClassReader getClassReader(ModuleData res) {
public ClassReader getClassReader(ModuleEntry res) {
return newClassReader(res.getBytes());
}
@ -505,7 +504,7 @@ final class AsmPoolImpl implements AsmModulePool {
@Override
public void visitClassReaders(ClassReaderVisitor visitor) {
Objects.requireNonNull(visitor);
for (ModuleData res : getClasses()) {
for (ModuleEntry res : getClasses()) {
ClassReader reader = newClassReader(res.getBytes());
ClassWriter writer = visitor.visit(reader);
if (writer != null) {
@ -523,7 +522,7 @@ final class AsmPoolImpl implements AsmModulePool {
@Override
public void visitResourceFiles(ResourceFileVisitor visitor) {
Objects.requireNonNull(visitor);
for (ModuleData resource : getResourceFiles()) {
for (ModuleEntry resource : getResourceFiles()) {
ResourceFile resFile
= new ResourceFile(toJavaBinaryResourceName(resource.getPath()),
resource.getBytes());
@ -540,18 +539,18 @@ final class AsmPoolImpl implements AsmModulePool {
* been set, it is used to sort the returned resources. *
*/
@Override
public void fillOutputResources(Pool outputResources) {
public void fillOutputResources(ModulePool outputResources) {
List<String> added = new ArrayList<>();
// If the sorter is null, use the input order.
// New resources are added at the end
// First input classes that have not been removed
Pool output = new PoolImpl(outputResources.getByteOrder(),
((PoolImpl)outputResources).getStringTable());
for (ModuleData inResource : jimageResources.getContent()) {
ModulePool output = new ModulePoolImpl(outputResources.getByteOrder(),
((ModulePoolImpl)outputResources).getStringTable());
jimageResources.entries().forEach(inResource -> {
if (!forgetResources.contains(inResource.getPath())) {
ModuleData resource = inResource;
ModuleEntry resource = inResource;
// Do we have a transformed class with the same name?
ModuleData res = transformedResources.
ModuleEntry res = transformedResources.
get(toJavaBinaryResourceName(inResource.getPath()));
if (res != null) {
resource = res;
@ -565,10 +564,10 @@ final class AsmPoolImpl implements AsmModulePool {
output.add(resource);
added.add(resource.getPath());
}
}
});
// Then new resources
for (Map.Entry<String, ModuleData> entry : transformedResources.entrySet()) {
ModuleData resource = entry.getValue();
for (Map.Entry<String, ModuleEntry> entry : transformedResources.entrySet()) {
ModuleEntry resource = entry.getValue();
if (!forgetResources.contains(resource.getPath())) {
if (!added.contains(resource.getPath())) {
output.add(resource);
@ -576,8 +575,8 @@ final class AsmPoolImpl implements AsmModulePool {
}
}
// And new classes
for (Map.Entry<String, ModuleData> entry : transformedClasses.entrySet()) {
ModuleData resource = entry.getValue();
for (Map.Entry<String, ModuleEntry> entry : transformedClasses.entrySet()) {
ModuleEntry resource = entry.getValue();
if (!forgetResources.contains(resource.getPath())) {
if (!added.contains(resource.getPath())) {
output.add(resource);

View File

@ -41,11 +41,11 @@ import java.util.Objects;
import java.util.Set;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.plugins.asm.AsmPool.Sorter;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModulePool;
/**
* A container for pools of ClassReader and other resource files. A pool of all
@ -97,10 +97,10 @@ public final class AsmPools {
}
@Override
public Collection<Pool.ModuleData> getClasses() {
List<Pool.ModuleData> all = new ArrayList<>();
public Collection<ModuleEntry> getClasses() {
List<ModuleEntry> all = new ArrayList<>();
visitAllPools((AsmModulePool pool) -> {
for (Pool.ModuleData rf : pool.getTransformedClasses().getClasses()) {
for (ModuleEntry rf : pool.getTransformedClasses().getClasses()) {
all.add(rf);
}
});
@ -108,7 +108,7 @@ public final class AsmPools {
}
@Override
public ClassReader getClassReader(Pool.ModuleData res) {
public ClassReader getClassReader(ModuleEntry res) {
return visitPools((AsmModulePool pool) -> {
return pool.getTransformedClasses().getClassReader(res);
});
@ -140,10 +140,10 @@ public final class AsmPools {
}
@Override
public Collection<Pool.ModuleData> getResourceFiles() {
List<Pool.ModuleData> all = new ArrayList<>();
public Collection<ModuleEntry> getResourceFiles() {
List<ModuleEntry> all = new ArrayList<>();
visitAllPools((AsmModulePool pool) -> {
for (Pool.ModuleData rf : pool.getTransformedResourceFiles().getResourceFiles()) {
for (ModuleEntry rf : pool.getTransformedResourceFiles().getResourceFiles()) {
all.add(rf);
}
});
@ -151,7 +151,7 @@ public final class AsmPools {
}
@Override
public ResourceFile getResourceFile(Pool.ModuleData res) {
public ResourceFile getResourceFile(ModuleEntry res) {
return visitPools((AsmModulePool pool) -> {
return pool.getTransformedResourceFiles().getResourceFile(res);
});
@ -175,10 +175,10 @@ public final class AsmPools {
}
@Override
public Collection<Pool.ModuleData> getClasses() {
List<Pool.ModuleData> all = new ArrayList<>();
public Collection<ModuleEntry> getClasses() {
List<ModuleEntry> all = new ArrayList<>();
visitAllPools((AsmModulePool pool) -> {
for (Pool.ModuleData rf : pool.getClasses()) {
for (ModuleEntry rf : pool.getClasses()) {
all.add(rf);
}
});
@ -186,10 +186,10 @@ public final class AsmPools {
}
@Override
public Collection<Pool.ModuleData> getResourceFiles() {
List<Pool.ModuleData> all = new ArrayList<>();
public Collection<ModuleEntry> getResourceFiles() {
List<ModuleEntry> all = new ArrayList<>();
visitAllPools((AsmModulePool pool) -> {
for (Pool.ModuleData rf : pool.getResourceFiles()) {
for (ModuleEntry rf : pool.getResourceFiles()) {
all.add(rf);
}
});
@ -211,14 +211,14 @@ public final class AsmPools {
}
@Override
public ResourceFile getResourceFile(Pool.ModuleData res) {
public ResourceFile getResourceFile(ModuleEntry res) {
return visitPools((AsmModulePool pool) -> {
return pool.getResourceFile(res);
});
}
@Override
public ClassReader getClassReader(Pool.ModuleData res) {
public ClassReader getClassReader(ModuleEntry res) {
return visitPoolsEx((AsmModulePool pool) -> {
return pool.getClassReader(res);
});
@ -239,7 +239,7 @@ public final class AsmPools {
}
@Override
public void fillOutputResources(Pool outputResources) {
public void fillOutputResources(ModulePool outputResources) {
AsmPools.this.fillOutputResources(outputResources);
}
@ -324,15 +324,15 @@ public final class AsmPools {
*
* @param inputResources The raw resources to build the pool from.
*/
public AsmPools(Pool inputResources) {
public AsmPools(ModulePool inputResources) {
Objects.requireNonNull(inputResources);
Map<String, Pool> resPools = new LinkedHashMap<>();
Map<String, ModulePool> resPools = new LinkedHashMap<>();
Map<String, ModuleDescriptor> descriptors = new HashMap<>();
for (Pool.ModuleData res : inputResources.getContent()) {
Pool p = resPools.get(res.getModule());
inputResources.entries().forEach(res -> {
ModulePool p = resPools.get(res.getModule());
if (p == null) {
p = new PoolImpl(inputResources.getByteOrder(),
((PoolImpl)inputResources).getStringTable());
p = new ModulePoolImpl(inputResources.getByteOrder(),
((ModulePoolImpl)inputResources).getStringTable());
resPools.put(res.getModule(), p);
}
if (res.getPath().endsWith("module-info.class")) {
@ -341,11 +341,11 @@ public final class AsmPools {
descriptors.put(res.getModule(), descriptor);
}
p.add(res);
}
});
poolsArray = new AsmModulePool[resPools.size()];
int i = 0;
for (Entry<String, Pool> entry : resPools.entrySet()) {
for (Entry<String, ModulePool> entry : resPools.entrySet()) {
ModuleDescriptor descriptor = descriptors.get(entry.getKey());
if (descriptor == null) {
throw new PluginException("module-info.class not found for " + entry.getKey() + " module");
@ -405,7 +405,7 @@ public final class AsmPools {
*
* @param outputResources The pool used to fill the jimage.
*/
public void fillOutputResources(Pool outputResources) {
public void fillOutputResources(ModulePool outputResources) {
// First sort modules
List<String> modules = new ArrayList<>();
for (String k : pools.keySet()) {
@ -414,8 +414,8 @@ public final class AsmPools {
if (moduleSorter != null) {
modules = moduleSorter.sort(modules);
}
Pool output = new PoolImpl(outputResources.getByteOrder(),
((PoolImpl)outputResources).getStringTable());
ModulePool output = new ModulePoolImpl(outputResources.getByteOrder(),
((ModulePoolImpl)outputResources).getStringTable());
for (String mn : modules) {
AsmPool pool = pools.get(mn);
pool.fillOutputResources(output);
@ -423,17 +423,17 @@ public final class AsmPools {
sort(outputResources, output, global.sorter);
}
static void sort(Pool outputResources,
Pool transientOutput, Sorter sorter) {
static void sort(ModulePool outputResources,
ModulePool transientOutput, Sorter sorter) {
if (sorter != null) {
List<String> order = sorter.sort(transientOutput);
for (String s : order) {
outputResources.add(transientOutput.get(s));
outputResources.add(transientOutput.findEntry(s).get());
}
} else {
for (ModuleData res : transientOutput.getContent()) {
transientOutput.entries().forEach(res-> {
outputResources.add(res);
}
});
}
}

View File

@ -24,66 +24,41 @@
*/
package jdk.tools.jlink.plugin;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* An executable runtime image. Instance of this class contains the information
* needed to create image processes.
* An executable runtime image. Contains the information about the executable
* image created.
*/
public abstract class ExecutableImage {
private final Path home;
private final List<String> args;
private final Set<String> modules;
protected ExecutableImage(Path home, Set<String> modules,
List<String> args) {
Objects.requireNonNull(home);
Objects.requireNonNull(args);
if (!Files.exists(home)) {
throw new IllegalArgumentException("Invalid image home");
}
this.home = home;
this.modules = Collections.unmodifiableSet(modules);
this.args = Collections.unmodifiableList(args);
}
public interface ExecutableImage {
/**
* Image home directory,
*
* @return The home directory.
*/
public Path getHome() {
return home;
}
public Path getHome();
/**
* The names of the modules located in the image.
*
* @return The set of modules.
*/
public Set<String> getModules() {
return modules;
}
public Set<String> getModules();
/**
* The list of arguments required to execute the image.
*
* @return The list of arguments.
*/
public List<String> getExecutionArgs() {
return args;
}
public List<String> getExecutionArgs();
/**
* Store new arguments required to execute the image.
*
* @param args Additional arguments
*/
public abstract void storeLaunchArgs(List<String> args);
public void storeLaunchArgs(List<String> args);
}

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2016, 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.plugin;
import java.lang.module.ModuleDescriptor;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
/**
* Link-time representation of a Java module.
*/
public interface LinkModule {
/**
* The module name.
*
* @return The name.
*/
public String getName();
/**
* Retrieves a LinkModuleEntry from the given path (e.g:
* /mymodule/com.foo.bar/MyClass.class)
*
* @param path The piece of data path.
* @return A LinkModuleEntry of the given path, if found.
*/
public Optional<ModuleEntry> findEntry(String path);
/**
* The module descriptor of this module.
*
* @return The module descriptor.
*/
public ModuleDescriptor getDescriptor();
/**
* Add a LinkModuleEntry to this module.
*
* @param data The LinkModuleEntry to add.
*/
public void add(ModuleEntry data);
/**
* Retrieves all the packages located in this module.
*
* @return The set of packages.
*/
public Set<String> getAllPackages();
/**
* Retrieves the stream of LinkModuleEntry.
*
* @return The LinkModuleEntry stream.
*/
public Stream<? extends ModuleEntry> entries();
/**
* Return the number of LinkModuleEntry count in this LinkModule.
*
* @return the entry count.
*/
public int getEntryCount();
}

View File

@ -0,0 +1,155 @@
/*
* Copyright (c) 2016, 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.plugin;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Objects;
import jdk.tools.jlink.internal.ImageFileCreator;
import jdk.tools.jlink.internal.ModuleEntryImpl;
/**
* A LinkModuleEntry is the elementary unit of data inside an image. It is
* generally a file. e.g.: a java class file, a resource file, a shared library,
* ...
* <br>
* A LinkModuleEntry is identified by a path of the form:
* <ul>
* <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
* name}</li>
* <li>For other files (shared lib, launchers, config, ...):/{module name}/
* {@literal bin|conf|native}/{dir1}>/.../{dirN}/{file name}</li>
* </ul>
*/
public interface ModuleEntry {
/**
* Type of module data.
* <li>
* <ul>CLASS_OR_RESOURCE: A java class or resource file.</ul>
* <ul>CONFIG: A configuration file.</ul>
* <ul>NATIVE_CMD: A native process launcher.</ul>
* <ul>NATIVE_LIB: A native library.</ul>
* <ul>OTHER: Other kind of file.</ul>
* </li>
*/
public enum Type {
CLASS_OR_RESOURCE,
CONFIG,
NATIVE_CMD,
NATIVE_LIB,
OTHER
}
/**
* The LinkModuleEntry module name.
*
* @return The module name.
*/
public String getModule();
/**
* The LinkModuleEntry path.
*
* @return The module path.
*/
public String getPath();
/**
* The LinkModuleEntry's type.
*
* @return The data type.
*/
public Type getType();
/**
* The LinkModuleEntry content as an array of byte.
*
* @return An Array of bytes.
*/
public byte[] getBytes();
/**
* The LinkModuleEntry content length.
*
* @return The length.
*/
public long getLength();
/**
* The LinkModuleEntry stream.
*
* @return The module data stream.
*/
public InputStream stream();
/**
* Create a LinkModuleEntry located inside a jimage file. Such
* LinkModuleEntry has a Type being equals to CLASS_OR_RESOURCE.
*
* @param path The complete resource path (contains the module radical).
* @param content The resource content.
* @param size The content size.
* @return A new LinkModuleEntry.
*/
public static ModuleEntry create(String path, InputStream content, long size) {
Objects.requireNonNull(path);
Objects.requireNonNull(content);
String[] split = ImageFileCreator.splitPath(path);
String module = split[0];
return new ModuleEntryImpl(module, path, Type.CLASS_OR_RESOURCE, content, size);
}
/**
* Create a LinkModuleEntry for a file that will be located inside a jimage
* file.
*
* @param path The resource path.
* @param content The resource content.
* @return A new LinkModuleEntry.
*/
public static ModuleEntry create(String path, byte[] content) {
return create(path, new ByteArrayInputStream(content),
content.length);
}
/**
* Create a LinkModuleEntry for a file that will be located outside a jimage
* file.
*
* @param module The module in which this files is located.
* @param path The file path locator (doesn't contain the module name).
* @param type The LinkModuleEntry type.
* @param content The file content.
* @param size The content size.
* @return A new LinkModuleEntry.
*/
public static ModuleEntry create(String module, String path, ModuleEntry.Type type,
InputStream content, long size) {
Objects.requireNonNull(path);
Objects.requireNonNull(content);
return new ModuleEntryImpl(module, path, type, content, size);
}
}

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 2015, 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.plugin;
import java.nio.ByteOrder;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Stream;
/**
* Pool of module data.
*/
public interface ModulePool {
/**
* Is this a read-only ModulePool?
*
* @return true if this is a read-only configuration.
*/
public boolean isReadOnly();
/**
* Add a ModuleEntry.
*
* @param data The ModuleEntry to add.
*/
public void add(ModuleEntry data);
/**
* Retrieves the module for the provided name.
*
* @param name The module name
* @return the module of matching name, if found
*/
public Optional<LinkModule> findModule(String name);
/**
* The stream of modules contained in this ModulePool.
*
* @return The stream of modules.
*/
public Stream<? extends LinkModule> modules();
/**
* Return the number of LinkModule count in this ModulePool.
*
* @return the module count.
*/
public int getModuleCount();
/**
* Get all ModuleEntry contained in this ModulePool instance.
*
* @return The stream of LinkModuleEntries.
*/
public Stream<? extends ModuleEntry> entries();
/**
* Return the number of ModuleEntry count in this ModulePool.
*
* @return the entry count.
*/
public int getEntryCount();
/**
* Get the ModuleEntry for the passed path.
*
* @param path A data path
* @return A ModuleEntry instance or null if the data is not found
*/
public Optional<ModuleEntry> findEntry(String path);
/**
* Check if the ModulePool contains the given ModuleEntry.
*
* @param data The module data to check existence for.
* @return The module data or null if not found.
*/
public boolean contains(ModuleEntry data);
/**
* Check if the ModulePool contains some content at all.
*
* @return True, no content, false otherwise.
*/
public boolean isEmpty();
/**
* Visit each ModuleEntry in this ModulePool to transform it and copy
* the transformed ModuleEntry to the output ModulePool.
*
* @param transform The function called for each ModuleEntry found in the
* ModulePool. The transform function should return a ModuleEntry
* instance which will be added to the output or it should return null if
* the passed ModuleEntry is to be ignored for the output.
*
* @param output The ModulePool to be filled with Visitor returned
* ModuleEntry.
*/
public void transformAndCopy(Function<ModuleEntry, ModuleEntry> transform, ModulePool output);
/**
* The ByteOrder currently in use when generating the jimage file.
*
* @return The ByteOrder.
*/
public ByteOrder getByteOrder();
/**
* Release properties such as OS, CPU name, version etc.
*
* @return the release properties
*/
public Map<String, String> getReleaseProperties();
}

View File

@ -26,7 +26,6 @@ package jdk.tools.jlink.plugin;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jdk.tools.jlink.internal.plugins.PluginsResourceBundle;
@ -36,14 +35,6 @@ import jdk.tools.jlink.internal.plugins.PluginsResourceBundle;
*/
public interface Plugin {
/**
* Type of plugin.
*/
public interface PluginType {
public String getName();
}
/**
* Order of categories:
* <ol>
@ -53,28 +44,29 @@ public interface Plugin {
* <li>MODULEINFO_TRANSFORMER: Transform only module-info.class</li>
* <li>SORTER: Sort resources within the resource container.</li>
* <li>COMPRESSOR: Compress resource within the resouce containers.</li>
* <li>METAINFO_ADDER: Added meta info (like release, copyright etc.)</li>
* <li>VERIFIER: Does some image verification.</li>
* <li>PROCESSOR: Does some post processing on image.</li>
* <li>PACKAGER: Final processing</li>
* </ol>
*/
public enum CATEGORY implements PluginType {
public enum Category {
FILTER("FILTER"),
TRANSFORMER("TRANSFORMER"),
MODULEINFO_TRANSFORMER("MODULEINFO_TRANSFORMER"),
SORTER("SORTER"),
COMPRESSOR("COMPRESSOR"),
METAINFO_ADDER("METAINFO_ADDER"),
VERIFIER("VERIFIER"),
PROCESSOR("PROCESSOR"),
PACKAGER("PACKAGER");
private final String name;
CATEGORY(String name) {
Category(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@ -91,7 +83,7 @@ public interface Plugin {
* {@link #getStateDescription() getStateDescription} method</li>
* </ul>
*/
public enum STATE {
public enum State {
DISABLED,
AUTO_ENABLED,
FUNCTIONAL
@ -101,7 +93,7 @@ public interface Plugin {
* The Plugin set of types.
* @return The set of types.
*/
public default Set<PluginType> getType() {
public default Set<Category> getType() {
return Collections.emptySet();
}
@ -109,8 +101,8 @@ public interface Plugin {
* The Plugin set of states.
* @return The set of states.
*/
public default Set<STATE> getState() {
return EnumSet.of(STATE.FUNCTIONAL);
public default Set<State> getState() {
return EnumSet.of(State.FUNCTIONAL);
}
/**
@ -191,7 +183,7 @@ public interface Plugin {
* @return A status description.
*/
public default String getStateDescription() {
return getState().contains(STATE.FUNCTIONAL)
return getState().contains(State.FUNCTIONAL)
? PluginsResourceBundle.getMessage("main.status.ok")
: PluginsResourceBundle.getMessage("main.status.not.ok");
}
@ -206,18 +198,4 @@ public interface Plugin {
*/
public default void configure(Map<String, String> config) {
}
/**
* Configure the plugin based on the passed configuration.
* This method is called prior to invoke the plugin.
*
* @param config The plugin configuration.
* @param ctx The plugin context
* @throws IllegalArgumentException if a mandatory argument is missing or
* if an argument has invalid value.
*
*/
public default void configure(Map<String, String> config, PluginContext ctx) {
configure(config);
}
}

View File

@ -1,37 +0,0 @@
/*
* Copyright (c) 2016, 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.plugin;
import java.util.Properties;
/**
* Interface to plugin (container) context.
*/
public interface PluginContext {
/**
* Returns 'release' properties
*/
public Properties getReleaseProperties();
}

View File

@ -1,528 +0,0 @@
/*
* Copyright (c) 2015, 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.plugin;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.lang.module.ModuleDescriptor;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import jdk.tools.jlink.internal.ImageFileCreator;
import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
/**
* Pool of module data.
*
*/
public abstract class Pool {
/**
* Interface to visit the content of a Pool.
*/
public interface Visitor {
/**
* Called for each visited ModuleData.
*
* @param content A ModuleData
* @return A ModuleData instance or null if the passed ModuleData is to
* be removed from the image.
* @throws PluginException
*/
public ModuleData visit(ModuleData content);
}
/**
* Type of module data.
* <li>
* <ul>CLASS_OR_RESOURCE: A java class or resource file.</ul>
* <ul>CONFIG: A configuration file.</ul>
* <ul>NATIVE_CMD: A native process launcher.</ul>
* <ul>NATIVE_LIB: A native library.</ul>
* <ul>OTHER: Other kind of file.</ul>
* </li>
*/
public static enum ModuleDataType {
CLASS_OR_RESOURCE,
CONFIG,
NATIVE_CMD,
NATIVE_LIB,
OTHER;
}
/**
* A module in the pool.
*/
public interface Module {
/**
* The module name.
*
* @return The name.
*/
public String getName();
/**
* Retrieves a ModuleData from a path (e.g:
* /mymodule/com.foo.bar/MyClass.class)
*
* @param path The piece of data path.
* @return A ModuleData or null if the path doesn't identify a
* ModuleData.
*/
public ModuleData get(String path);
/**
* The module descriptor of this module.
*
* @return The module descriptor.
*/
public ModuleDescriptor getDescriptor();
/**
* Add a ModuleData to this module.
*
* @param data The ModuleData to add.
*/
public void add(ModuleData data);
/**
* Retrieves all the packages located in this module.
*
* @return The set of packages.
*/
public Set<String> getAllPackages();
/**
* Retrieves the collection of ModuleData.
*
* @return The ModuleData collection.
*/
public Collection<ModuleData> getContent();
}
private class ModuleImpl implements Module {
private final Map<String, ModuleData> moduleContent = new LinkedHashMap<>();
private ModuleDescriptor descriptor;
private final String name;
private ModuleImpl(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public ModuleData get(String path) {
if (!path.startsWith("/")) {
path = "/" + path;
}
if (!path.startsWith("/" + name)) {
path = "/" + name + path;
}
return moduleContent.get(path);
}
@Override
public ModuleDescriptor getDescriptor() {
if (descriptor == null) {
String p = "/" + name + "/module-info.class";
ModuleData content = moduleContent.get(p);
if (content == null) {
throw new PluginException("No module-info for " + name
+ " module");
}
ByteBuffer bb = ByteBuffer.wrap(content.getBytes());
descriptor = ModuleDescriptor.read(bb);
}
return descriptor;
}
@Override
public void add(ModuleData data) {
if (isReadOnly()) {
throw new PluginException("pool is readonly");
}
Objects.requireNonNull(data);
if (!data.getModule().equals(name)) {
throw new PluginException("Can't add resource " + data.getPath()
+ " to module " + name);
}
Pool.this.add(data);
}
@Override
public Set<String> getAllPackages() {
Set<String> pkgs = new HashSet<>();
moduleContent.values().stream().filter(m -> m.getType().
equals(ModuleDataType.CLASS_OR_RESOURCE)).forEach((res) -> {
// Module metadata only contains packages with .class files
if (ImageFileCreator.isClassPackage(res.getPath())) {
String[] split = ImageFileCreator.splitPath(res.getPath());
String pkg = split[1];
if (pkg != null && !pkg.isEmpty()) {
pkgs.add(pkg);
}
}
});
return pkgs;
}
@Override
public String toString() {
return getName();
}
@Override
public Collection<ModuleData> getContent() {
return Collections.unmodifiableCollection(moduleContent.values());
}
}
/**
* A ModuleData is the elementary unit of data inside an image. It is
* generally a file. e.g.: a java class file, a resource file, a shared
* library, ...
* <br>
* A ModuleData is identified by a path of the form:
* <ul>
* <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
* name}</li>
* <li>For other files (shared lib, launchers, config, ...):/{module name}/
* {@literal bin|conf|native}/{dir1}/.../{dirN}/{file name}</li>
* </ul>
*/
public static class ModuleData {
private final ModuleDataType type;
private final String path;
private final String module;
private final long length;
private final InputStream stream;
private byte[] buffer;
/**
* Create a new ModuleData.
*
* @param module The module name.
* @param path The data path identifier.
* @param type The data type.
* @param stream The data content stream.
* @param length The stream length.
*/
public ModuleData(String module, String path, ModuleDataType type,
InputStream stream, long length) {
Objects.requireNonNull(module);
Objects.requireNonNull(path);
Objects.requireNonNull(type);
Objects.requireNonNull(stream);
this.path = path;
this.type = type;
this.module = module;
this.stream = stream;
this.length = length;
}
/**
* The ModuleData module name.
*
* @return The module name.
*/
public final String getModule() {
return module;
}
/**
* The ModuleData path.
*
* @return The module path.
*/
public final String getPath() {
return path;
}
/**
* The ModuleData type.
*
* @return The data type.
*/
public final ModuleDataType getType() {
return type;
}
/**
* The ModuleData content as an array of byte.
*
* @return An Array of bytes.
*/
public byte[] getBytes() {
if (buffer == null) {
try {
buffer = stream.readAllBytes();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
return buffer;
}
/**
* The ModuleData content length.
*
* @return The length.
*/
public long getLength() {
return length;
}
/**
* The ModuleData stream.
*
* @return The module data stream.
*/
public InputStream stream() {
return stream;
}
@Override
public int hashCode() {
int hash = 7;
hash = 89 * hash + Objects.hashCode(this.path);
return hash;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof ModuleData)) {
return false;
}
ModuleData f = (ModuleData) other;
return f.path.equals(path);
}
@Override
public String toString() {
return getPath();
}
}
private final Map<String, ModuleData> resources = new LinkedHashMap<>();
private final Map<String, ModuleImpl> modules = new LinkedHashMap<>();
private final ModuleImpl fileCopierModule = new ModuleImpl(FileCopierPlugin.FAKE_MODULE);
private final ByteOrder order;
protected Pool() {
this(ByteOrder.nativeOrder());
}
protected Pool(ByteOrder order) {
Objects.requireNonNull(order);
this.order = order;
}
/**
* Read only state. No data can be added to a ReadOnly Pool.
*
* @return true if readonly false otherwise.
*/
public abstract boolean isReadOnly();
/**
* Add a ModuleData.
*
* @param data The ModuleData to add.
*/
public void add(ModuleData data) {
if (isReadOnly()) {
throw new PluginException("pool is readonly");
}
Objects.requireNonNull(data);
if (resources.get(data.getPath()) != null) {
throw new PluginException("Resource " + data.getPath()
+ " already present");
}
String modulename = data.getModule();
ModuleImpl m = modules.get(modulename);
// ## TODO: FileCopierPlugin should not add content to a module
// FAKE_MODULE is not really a module to be added in the image
if (FileCopierPlugin.FAKE_MODULE.equals(modulename)) {
m = fileCopierModule;
}
if (m == null) {
m = new ModuleImpl(modulename);
modules.put(modulename, m);
}
resources.put(data.getPath(), data);
m.moduleContent.put(data.getPath(), data);
}
/**
* Retrieves the module for the provided name.
*
* @param name The module name
* @return the module or null if the module doesn't exist.
*/
public Module getModule(String name) {
Objects.requireNonNull(name);
return modules.get(name);
}
/**
* The collection of modules contained in this pool.
*
* @return The collection of modules.
*/
public Collection<Module> getModules() {
return Collections.unmodifiableCollection(modules.values());
}
/**
* Get all ModuleData contained in this pool instance.
*
* @return The collection of resources;
*/
public Collection<ModuleData> getContent() {
return Collections.unmodifiableCollection(resources.values());
}
/**
* Get the ModuleData for the passed path.
*
* @param path A data path
* @return A ModuleData instance or null if the data is not found
*/
public ModuleData get(String path) {
Objects.requireNonNull(path);
return resources.get(path);
}
/**
* Check if the pool contains this data.
*
* @param data The module data to check existence for.
* @return The module data or null if not found.
*/
public boolean contains(ModuleData data) {
Objects.requireNonNull(data);
return get(data.getPath()) != null;
}
/**
* Check if the Pool contains some content.
*
* @return True, no content, false otherwise.
*/
public boolean isEmpty() {
return resources.isEmpty();
}
/**
* Visit the pool.
*
* @param visitor The Visitor called for each ModuleData found in the pool.
* @param output The pool to be filled with Visitor returned ModuleData.
*/
public void visit(Visitor visitor, Pool output) {
for (ModuleData resource : getContent()) {
ModuleData res = visitor.visit(resource);
if (res != null) {
output.add(res);
}
}
}
/**
* The ByteOrder currently in use when generating the jimage file.
*
* @return The ByteOrder.
*/
public ByteOrder getByteOrder() {
return order;
}
/**
* Create a ModuleData located inside a jimage file. Such ModuleData has a
* ModuleDataType being equals to CLASS_OR_RESOURCE.
*
* @param path The complete resource path (contains the module radical).
* @param content The resource content.
* @param size The content size.
* @return A new ModuleData.
*/
public static ModuleData newResource(String path, InputStream content, long size) {
Objects.requireNonNull(path);
Objects.requireNonNull(content);
String[] split = ImageFileCreator.splitPath(path);
String module = split[0];
return new ModuleData(module, path, ModuleDataType.CLASS_OR_RESOURCE, content, size);
}
/**
* Create a ModuleData for a file that will be located inside a jimage file.
*
* @param path The resource path.
* @param content The resource content.
* @return A new ModuleData.
*/
public static ModuleData newResource(String path, byte[] content) {
return newResource(path, new ByteArrayInputStream(content),
content.length);
}
/**
* Create a ModuleData for a file that will be located outside a jimage
* file.
*
* @param module The module in which this files is located.
* @param path The file path locator (doesn't contain the module name).
* @param type The ModuleData type.
* @param content The file content.
* @param size The content size.
* @return A new ModuleData.
*/
public static ModuleData newImageFile(String module, String path, ModuleDataType type,
InputStream content, long size) {
Objects.requireNonNull(path);
Objects.requireNonNull(content);
return new ModuleData(module, path, type, content, size);
}
}

View File

@ -40,5 +40,5 @@ public interface TransformerPlugin extends Plugin {
*
* @throws PluginException
*/
public void visit(Pool in, Pool out);
public void visit(ModulePool in, ModulePool out);
}

View File

@ -24,9 +24,7 @@
*/
module jdk.jlink {
exports jdk.tools.jlink;
exports jdk.tools.jlink.plugin;
exports jdk.tools.jlink.builder;
requires jdk.internal.opt;
requires jdk.jdeps;
@ -46,5 +44,5 @@ module jdk.jlink {
provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.ExcludeVMPlugin;
provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.IncludeLocalesPlugin;
provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.GenerateJLIClassesPlugin;
provides jdk.tools.jlink.plugin.PostProcessorPlugin with jdk.tools.jlink.internal.plugins.ReleaseInfoPlugin;
provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.ReleaseInfoPlugin;
}

View File

@ -33,7 +33,7 @@ import java.util.Set;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
import tests.Helper;
@ -65,26 +65,26 @@ public class DefaultProviderTest {
private boolean enabled = true;
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.TRANSFORMER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.TRANSFORMER);
return Collections.unmodifiableSet(set);
}
@Override
public Set<STATE> getState() {
return enabled ? EnumSet.of(STATE.AUTO_ENABLED, STATE.FUNCTIONAL)
: EnumSet.of(STATE.DISABLED);
public Set<State> getState() {
return enabled ? EnumSet.of(State.AUTO_ENABLED, State.FUNCTIONAL)
: EnumSet.of(State.DISABLED);
}
@Override
public void visit(Pool in, Pool out) {
public void visit(ModulePool in, ModulePool out) {
if (!enabled) {
throw new PluginException(NAME + " was set");
}
DefaultProviderTest.isNewPluginsCalled = true;
in.visit((Pool.ModuleData content) -> {
in.transformAndCopy(content -> {
return content;
}, out);
}

View File

@ -39,7 +39,7 @@ import jdk.tools.jlink.internal.ImageFileCreator;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.plugin.ExecutableImage;
import jdk.tools.jlink.builder.ImageBuilder;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModulePool;
/*
@ -47,6 +47,7 @@ import jdk.tools.jlink.plugin.Pool;
* @summary ImageFileCreator class test
* @author Jean-Francois Denise
* @modules jdk.jlink/jdk.tools.jlink.internal
* jdk.jlink/jdk.tools.jlink.builder
* java.base/jdk.internal.jimage
* @run main/othervm -verbose:gc -Xmx1g ImageFileCreatorTest
*/
@ -214,7 +215,7 @@ public class ImageFileCreatorTest {
}
@Override
public void storeFiles(Pool content) {
public void storeFiles(ModulePool content) {
}
};

View File

@ -31,11 +31,12 @@
*/
import java.io.ByteArrayInputStream;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
import jdk.tools.jlink.plugin.Pool.Visitor;
import java.util.Optional;
import java.util.function.Function;
import jdk.tools.jlink.internal.ModuleEntryImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
public class ImageFilePoolTest {
public static void main(String[] args) throws Exception {
@ -50,45 +51,45 @@ public class ImageFilePoolTest {
private static final String SUFFIX = "END";
private void checkVisitor() throws Exception {
Pool input = new PoolImpl();
ModulePool input = new ModulePoolImpl();
for (int i = 0; i < 1000; ++i) {
String module = "module" + (i / 100);
input.add(new InMemoryImageFile(module, "/" + module + "/java/class" + i,
ModuleDataType.CONFIG, "class" + i));
ModuleEntry.Type.CONFIG, "class" + i));
}
if (input.getContent().size() != 1000) {
if (input.getEntryCount() != 1000) {
throw new AssertionError();
}
Pool output = new PoolImpl();
ModulePool output = new ModulePoolImpl();
ResourceVisitor visitor = new ResourceVisitor();
input.visit(visitor, output);
input.transformAndCopy(visitor, output);
if (visitor.getAmountBefore() == 0) {
throw new AssertionError("Resources not found");
}
if (visitor.getAmountBefore() != input.getContent().size()) {
if (visitor.getAmountBefore() != input.getEntryCount()) {
throw new AssertionError("Number of visited resources. Expected: " +
visitor.getAmountBefore() + ", got: " + input.getContent().size());
visitor.getAmountBefore() + ", got: " + input.getEntryCount());
}
if (visitor.getAmountAfter() != output.getContent().size()) {
if (visitor.getAmountAfter() != output.getEntryCount()) {
throw new AssertionError("Number of added resources. Expected: " +
visitor.getAmountAfter() + ", got: " + output.getContent().size());
visitor.getAmountAfter() + ", got: " + output.getEntryCount());
}
for (ModuleData outFile : output.getContent()) {
output.entries().forEach(outFile -> {
String path = outFile.getPath().replaceAll(SUFFIX + "$", "");
ModuleData inFile = input.get(path);
if (inFile == null) {
Optional<ModuleEntry> inFile = input.findEntry(path);
if (!inFile.isPresent()) {
throw new AssertionError("Unknown resource: " + path);
}
}
});
}
private static class ResourceVisitor implements Visitor {
private static class ResourceVisitor implements Function<ModuleEntry, ModuleEntry> {
private int amountBefore;
private int amountAfter;
@Override
public ModuleData visit(ModuleData file) {
public ModuleEntry apply(ModuleEntry file) {
int index = ++amountBefore % 3;
switch (index) {
case 0:
@ -113,7 +114,7 @@ public class ImageFilePoolTest {
}
private void checkNegative() throws Exception {
PoolImpl input = new PoolImpl();
ModulePoolImpl input = new ModulePoolImpl();
try {
input.add(null);
throw new AssertionError("NullPointerException is not thrown");
@ -126,30 +127,30 @@ public class ImageFilePoolTest {
} catch (NullPointerException e) {
// expected
}
if (input.get("unknown") != null) {
throw new AssertionError("ImageFilePool does not return null for unknown file");
if (input.findEntry("unknown").isPresent()) {
throw new AssertionError("ImageFileModulePool does not return null for unknown file");
}
if (input.contains(new InMemoryImageFile("", "unknown", ModuleDataType.CONFIG, "unknown"))) {
if (input.contains(new InMemoryImageFile("", "unknown", ModuleEntry.Type.CONFIG, "unknown"))) {
throw new AssertionError("'contain' returns true for unknown file");
}
input.add(new InMemoryImageFile("", "/aaa/bbb", ModuleDataType.CONFIG, ""));
input.add(new InMemoryImageFile("", "/aaa/bbb", ModuleEntry.Type.CONFIG, ""));
try {
input.add(new InMemoryImageFile("", "/aaa/bbb", ModuleDataType.CONFIG, ""));
input.add(new InMemoryImageFile("", "/aaa/bbb", ModuleEntry.Type.CONFIG, ""));
throw new AssertionError("Exception expected");
} catch (Exception e) {
// expected
}
input.setReadOnly();
try {
input.add(new InMemoryImageFile("", "/aaa/ccc", ModuleDataType.CONFIG, ""));
input.add(new InMemoryImageFile("", "/aaa/ccc", ModuleEntry.Type.CONFIG, ""));
throw new AssertionError("Exception expected");
} catch (Exception e) {
// expected
}
}
private static class InMemoryImageFile extends ModuleData {
public InMemoryImageFile(String module, String path, ModuleDataType type, String content) {
private static class InMemoryImageFile extends ModuleEntryImpl {
public InMemoryImageFile(String module, String path, ModuleEntry.Type type, String content) {
super(module, path, type, new ByteArrayInputStream(content.getBytes()), content.getBytes().length);
}
}

View File

@ -39,7 +39,7 @@ import jdk.tools.jlink.Jlink.JlinkConfiguration;
import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.plugin.ExecutableImage;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.PostProcessorPlugin;
import jdk.tools.jlink.plugin.TransformerPlugin;
import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin;
@ -56,6 +56,8 @@ import tests.JImageGenerator;
* @library ../lib
* @modules java.base/jdk.internal.jimage
* jdk.jdeps/com.sun.tools.classfile
* jdk.jlink/jdk.tools.jlink
* jdk.jlink/jdk.tools.jlink.builder
* jdk.jlink/jdk.tools.jlink.internal
* jdk.jlink/jdk.tools.jlink.internal.plugins
* jdk.jlink/jdk.tools.jmod
@ -88,9 +90,9 @@ public class IntegrationTest {
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.PROCESSOR);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.PROCESSOR);
return Collections.unmodifiableSet(set);
}
@ -128,18 +130,18 @@ public class IntegrationTest {
}
@Override
public void visit(Pool in, Pool out) {
public void visit(ModulePool in, ModulePool out) {
System.err.println(NAME + index);
ordered.add(index);
in.visit((file) -> {
in.transformAndCopy((file) -> {
return file;
}, out);
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.TRANSFORMER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.TRANSFORMER);
return Collections.unmodifiableSet(set);
}

View File

@ -23,15 +23,15 @@ import jdk.internal.org.objectweb.asm.tree.MethodInsnNode;
import jdk.internal.org.objectweb.asm.tree.MethodNode;
import jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.plugins.OptimizationPlugin;
import jdk.tools.jlink.internal.plugins.asm.AsmModulePool;
import jdk.tools.jlink.internal.plugins.asm.AsmPlugin;
import jdk.tools.jlink.internal.plugins.asm.AsmPools;
import jdk.tools.jlink.internal.plugins.optim.ControlFlow;
import jdk.tools.jlink.internal.plugins.optim.ControlFlow.Block;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import tests.Helper;
import tests.JImageGenerator;
@ -134,9 +134,9 @@ public class JLinkOptimTest {
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.TRANSFORMER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.TRANSFORMER);
return Collections.unmodifiableSet(set);
}
}
@ -150,13 +150,13 @@ public class JLinkOptimTest {
FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
Path root = fs.getPath("/modules/java.base");
// Access module-info.class to be reused as fake module-info.class
List<ModuleData> javabaseResources = new ArrayList<>();
List<ModuleEntry> javabaseResources = new ArrayList<>();
try (Stream<Path> stream = Files.walk(root)) {
for (Iterator<Path> iterator = stream.iterator(); iterator.hasNext();) {
Path p = iterator.next();
if (Files.isRegularFile(p)) {
try {
javabaseResources.add(Pool.newResource(p.toString().
javabaseResources.add(ModuleEntry.create(p.toString().
substring("/modules".length()), Files.readAllBytes(p)));
} catch (Exception ex) {
throw new RuntimeException(ex);
@ -166,18 +166,18 @@ public class JLinkOptimTest {
}
//forName folding
PoolImpl pool = new PoolImpl();
ModulePoolImpl pool = new ModulePoolImpl();
byte[] content = Files.readAllBytes(classes.
resolve("optim").resolve("ForNameTestCase.class"));
byte[] content2 = Files.readAllBytes(classes.
resolve("optim").resolve("AType.class"));
byte[] mcontent = Files.readAllBytes(classes.resolve("module-info.class"));
pool.add(Pool.newResource("/optimplugin/optim/ForNameTestCase.class", content));
pool.add(Pool.newResource("/optimplugin/optim/AType.class", content2));
pool.add(Pool.newResource("/optimplugin/module-info.class", mcontent));
pool.add(ModuleEntry.create("/optimplugin/optim/ForNameTestCase.class", content));
pool.add(ModuleEntry.create("/optimplugin/optim/AType.class", content2));
pool.add(ModuleEntry.create("/optimplugin/module-info.class", mcontent));
for (ModuleData r : javabaseResources) {
for (ModuleEntry r : javabaseResources) {
pool.add(r);
}
@ -186,10 +186,10 @@ public class JLinkOptimTest {
optional.put(OptimizationPlugin.NAME, OptimizationPlugin.FORNAME_REMOVAL);
optional.put(OptimizationPlugin.LOG, "forName.log");
plugin.configure(optional);
Pool out = new PoolImpl();
ModulePool out = new ModulePoolImpl();
plugin.visit(pool, out);
ModuleData result = out.getContent().iterator().next();
ModuleEntry result = out.entries().iterator().next();
ClassReader optimReader = new ClassReader(result.getBytes());
ClassNode optimClass = new ClassNode();

View File

@ -24,7 +24,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.plugin.TransformerPlugin;
@ -62,7 +62,7 @@ public class JLinkOptionsTest {
}
@Override
public void visit(Pool in, Pool out) {
public void visit(ModulePool in, ModulePool out) {
}

View File

@ -75,9 +75,9 @@ public class JLinkPostProcessingTest {
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.PROCESSOR);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.PROCESSOR);
return Collections.unmodifiableSet(set);
}

View File

@ -37,14 +37,14 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.Module;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
import jdk.tools.jlink.plugin.Pool.Visitor;
import java.util.function.Function;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.LinkModule;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
public class ResourcePoolTest {
@ -61,54 +61,53 @@ public class ResourcePoolTest {
private static final String SUFFIX = "END";
private void checkResourceVisitor() throws Exception {
Pool input = new PoolImpl();
ModulePool input = new ModulePoolImpl();
for (int i = 0; i < 1000; ++i) {
String module = "/module" + (i / 10);
String resourcePath = module + "/java/package" + i;
byte[] bytes = resourcePath.getBytes();
input.add(new ModuleData(module, resourcePath,
ModuleDataType.CLASS_OR_RESOURCE,
input.add(ModuleEntry.create(module, resourcePath,
ModuleEntry.Type.CLASS_OR_RESOURCE,
new ByteArrayInputStream(bytes), bytes.length));
}
Pool output = new PoolImpl();
ModulePool output = new ModulePoolImpl();
ResourceVisitor visitor = new ResourceVisitor();
input.visit(visitor, output);
input.transformAndCopy(visitor, output);
if (visitor.getAmountBefore() == 0) {
throw new AssertionError("Resources not found");
}
if (visitor.getAmountBefore() != input.getContent().size()) {
if (visitor.getAmountBefore() != input.getEntryCount()) {
throw new AssertionError("Number of visited resources. Expected: " +
visitor.getAmountBefore() + ", got: " + input.getContent().size());
visitor.getAmountBefore() + ", got: " + input.getEntryCount());
}
if (visitor.getAmountAfter() != output.getContent().size()) {
if (visitor.getAmountAfter() != output.getEntryCount()) {
throw new AssertionError("Number of added resources. Expected: " +
visitor.getAmountAfter() + ", got: " + output.getContent().size());
visitor.getAmountAfter() + ", got: " + output.getEntryCount());
}
for (ModuleData outResource : output.getContent()) {
output.entries().forEach(outResource -> {
String path = outResource.getPath().replaceAll(SUFFIX + "$", "");
ModuleData inResource = input.get(path);
if (inResource == null) {
if (!input.findEntry(path).isPresent()) {
throw new AssertionError("Unknown resource: " + path);
}
}
});
}
private static class ResourceVisitor implements Visitor {
private static class ResourceVisitor implements Function<ModuleEntry, ModuleEntry> {
private int amountBefore;
private int amountAfter;
@Override
public ModuleData visit(ModuleData resource) {
public ModuleEntry apply(ModuleEntry resource) {
int index = ++amountBefore % 3;
switch (index) {
case 0:
++amountAfter;
return new ModuleData(resource.getModule(), resource.getPath() + SUFFIX,
return ModuleEntry.create(resource.getModule(), resource.getPath() + SUFFIX,
resource.getType(), resource.stream(), resource.getLength());
case 1:
++amountAfter;
return new ModuleData(resource.getModule(), resource.getPath(),
return ModuleEntry.create(resource.getModule(), resource.getPath(),
resource.getType(), resource.stream(), resource.getLength());
}
return null;
@ -133,8 +132,8 @@ public class ResourcePoolTest {
samples.add("javax/management/ObjectName");
test(samples, (resources, module, path) -> {
try {
resources.add(new ModuleData(module, path,
ModuleDataType.CLASS_OR_RESOURCE,
resources.add(ModuleEntry.create(module, path,
ModuleEntry.Type.CLASS_OR_RESOURCE,
new ByteArrayInputStream(new byte[0]), 0));
} catch (Exception ex) {
throw new RuntimeException(ex);
@ -142,12 +141,12 @@ public class ResourcePoolTest {
});
test(samples, (resources, module, path) -> {
try {
resources.add(PoolImpl.
newCompressedResource(new ModuleData(module, path,
ModuleDataType.CLASS_OR_RESOURCE,
resources.add(ModulePoolImpl.
newCompressedResource(ModuleEntry.create(module, path,
ModuleEntry.Type.CLASS_OR_RESOURCE,
new ByteArrayInputStream(new byte[0]), 0),
ByteBuffer.allocate(99), "bitcruncher", null,
((PoolImpl)resources).getStringTable(), ByteOrder.nativeOrder()));
((ModulePoolImpl)resources).getStringTable(), ByteOrder.nativeOrder()));
} catch (Exception ex) {
throw new RuntimeException(ex);
}
@ -158,7 +157,7 @@ public class ResourcePoolTest {
if (samples.isEmpty()) {
throw new AssertionError("No sample to test");
}
Pool resources = new PoolImpl();
ModulePool resources = new ModulePoolImpl();
Set<String> modules = new HashSet<>();
for (int i = 0; i < samples.size(); i++) {
String module = samples.get(i);
@ -173,70 +172,69 @@ public class ResourcePoolTest {
i++;
String clazz = samples.get(i);
String path = "/" + module + "/" + clazz + ".class";
ModuleData res = resources.get(path);
checkModule(resources, res);
if (res == null) {
Optional<ModuleEntry> res = resources.findEntry(path);
if (!res.isPresent()) {
throw new AssertionError("Resource not found " + path);
}
ModuleData res2 = resources.get(clazz);
if (res2 != null) {
checkModule(resources, res.get());
if (resources.findEntry(clazz).isPresent()) {
throw new AssertionError("Resource found " + clazz);
}
}
if (resources.getContent().size() != samples.size() / 2) {
if (resources.getEntryCount() != samples.size() / 2) {
throw new AssertionError("Invalid number of resources");
}
}
private void checkModule(Pool resources, ModuleData res) {
Module m = resources.getModule(res.getModule());
if (m == null) {
private void checkModule(ModulePool resources, ModuleEntry res) {
Optional<LinkModule> optMod = resources.findModule(res.getModule());
if (!optMod.isPresent()) {
throw new AssertionError("No module " + res.getModule());
}
LinkModule m = optMod.get();
if (!m.getName().equals(res.getModule())) {
throw new AssertionError("Not right module name " + res.getModule());
}
if (m.get(res.getPath()) == null) {
if (!m.findEntry(res.getPath()).isPresent()) {
throw new AssertionError("resource " + res.getPath()
+ " not in module " + m.getName());
}
}
private void checkResourcesAfterCompression() throws Exception {
PoolImpl resources1 = new PoolImpl();
ModuleData res1 = new ModuleData("module1", "/module1/toto1",
ModuleDataType.CLASS_OR_RESOURCE,
ModulePoolImpl resources1 = new ModulePoolImpl();
ModuleEntry res1 = ModuleEntry.create("module1", "/module1/toto1",
ModuleEntry.Type.CLASS_OR_RESOURCE,
new ByteArrayInputStream(new byte[0]), 0);
ModuleData res2 = new ModuleData("module2", "/module2/toto1",
ModuleDataType.CLASS_OR_RESOURCE,
ModuleEntry res2 = ModuleEntry.create("module2", "/module2/toto1",
ModuleEntry.Type.CLASS_OR_RESOURCE,
new ByteArrayInputStream(new byte[0]), 0);
resources1.add(res1);
resources1.add(res2);
checkResources(resources1, res1, res2);
Pool resources2 = new PoolImpl();
ModuleData res3 = new ModuleData("module2", "/module2/toto1",
ModuleDataType.CLASS_OR_RESOURCE,
ModulePool resources2 = new ModulePoolImpl();
ModuleEntry res3 = ModuleEntry.create("module2", "/module2/toto1",
ModuleEntry.Type.CLASS_OR_RESOURCE,
new ByteArrayInputStream(new byte[7]), 7);
resources2.add(res3);
resources2.add(PoolImpl.newCompressedResource(res1,
resources2.add(ModulePoolImpl.newCompressedResource(res1,
ByteBuffer.allocate(7), "zip", null, resources1.getStringTable(),
ByteOrder.nativeOrder()));
checkResources(resources2, res1, res2);
}
private void checkResources(Pool resources, ModuleData... expected) {
Collection<Module> ms = resources.getModules();
private void checkResources(ModulePool resources, ModuleEntry... expected) {
List<String> modules = new ArrayList();
for(Module m : ms) {
resources.modules().forEach(m -> {
modules.add(m.getName());
}
for (ModuleData res : expected) {
});
for (ModuleEntry res : expected) {
if (!resources.contains(res)) {
throw new AssertionError("Resource not found: " + res);
}
if (resources.get(res.getPath()) == null) {
if (!resources.findEntry(res.getPath()).isPresent()) {
throw new AssertionError("Resource not found: " + res);
}
@ -244,7 +242,7 @@ public class ResourcePoolTest {
throw new AssertionError("Module not found: " + res.getModule());
}
if (!resources.getContent().contains(res)) {
if (!resources.contains(res)) {
throw new AssertionError("Resources not found: " + res);
}
@ -260,17 +258,17 @@ public class ResourcePoolTest {
throw new AssertionError("ReadOnly resources");
}
((PoolImpl) resources).setReadOnly();
((ModulePoolImpl) resources).setReadOnly();
try {
resources.add(new ModuleData("module2", "/module2/toto1",
ModuleDataType.CLASS_OR_RESOURCE, new ByteArrayInputStream(new byte[0]), 0));
throw new AssertionError("Pool is read-only, but an exception is not thrown");
resources.add(ModuleEntry.create("module2", "/module2/toto1",
ModuleEntry.Type.CLASS_OR_RESOURCE, new ByteArrayInputStream(new byte[0]), 0));
throw new AssertionError("ModulePool is read-only, but an exception is not thrown");
} catch (Exception ex) {
// Expected
}
}
interface ResourceAdder {
void add(Pool resources, String module, String path);
void add(ModulePool resources, String module, String path);
}
}

View File

@ -25,6 +25,7 @@
* @test
* @summary Test JlinkPermission
* @author Jean-Francois Denise
* @modules jdk.jlink/jdk.tools.jlink
* @run main/othervm SecurityTest
*/

View File

@ -55,8 +55,8 @@ import jdk.tools.jlink.internal.plugins.asm.AsmPool.ResourceFile;
import jdk.tools.jlink.internal.plugins.asm.AsmPool.WritableClassPool;
import jdk.tools.jlink.internal.plugins.asm.AsmPool.WritableResourcePool;
import jdk.tools.jlink.internal.plugins.asm.AsmPools;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
public class AddForgetResourcesTest extends AsmPluginTestBase {
@ -82,7 +82,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
new ComboPlugin()
};
for (TestPlugin p : plugins) {
Pool out = p.visit(getPool());
ModulePool out = p.visit(getPool());
p.test(getPool(), out);
}
}
@ -124,7 +124,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
AsmGlobalPool globalPool = pools.getGlobalPool();
WritableClassPool transformedClasses = globalPool.getTransformedClasses();
expected = globalPool.getClasses().size();
for (ModuleData res : globalPool.getClasses()) {
for (ModuleEntry res : globalPool.getClasses()) {
ClassReader reader = globalPool.getClassReader(res);
String className = reader.getClassName();
if (!className.endsWith("module-info")) {
@ -137,14 +137,14 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
}
@Override
public void test(Pool inResources, Pool outResources) {
Collection<ModuleData> inClasses = extractClasses(inResources);
Collection<ModuleData> outClasses = extractClasses(outResources);
public void test(ModulePool inResources, ModulePool outResources) {
Collection<ModuleEntry> inClasses = extractClasses(inResources);
Collection<ModuleEntry> outClasses = extractClasses(outResources);
if (expected != outClasses.size()) {
throw new AssertionError("Classes were not added. Expected: " + expected
+ ", got: " + outClasses.size());
}
for (ModuleData in : inClasses) {
for (ModuleEntry in : inClasses) {
String path = in.getPath();
if (!outClasses.contains(in)) {
throw new AssertionError("Class not found: " + path);
@ -153,7 +153,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
continue;
}
String modifiedPath = path.replace(".class", SUFFIX + ".class");
if (!outClasses.contains(Pool.newResource(modifiedPath, new byte[0]))) {
if (!outClasses.contains(ModuleEntry.create(modifiedPath, new byte[0]))) {
throw new AssertionError("Class not found: " + modifiedPath);
}
}
@ -166,7 +166,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
public void visit() {
AsmPools pools = getPools();
AsmGlobalPool globalPool = pools.getGlobalPool();
for (ModuleData res : globalPool.getResourceFiles()) {
for (ModuleEntry res : globalPool.getResourceFiles()) {
String path = res.getPath();
String moduleName = getModule(path);
AsmModulePool modulePool = pools.getModulePool(moduleName);
@ -177,20 +177,20 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
}
@Override
public void test(Pool in, Pool out) throws Exception {
Collection<ModuleData> inResources = extractResources(in);
Collection<ModuleData> outResources = extractResources(out);
public void test(ModulePool in, ModulePool out) throws Exception {
Collection<ModuleEntry> inResources = extractResources(in);
Collection<ModuleEntry> outResources = extractResources(out);
if (2 * inResources.size() != outResources.size()) {
throw new AssertionError("Classes were not added. Expected: " + (2 * inResources.size())
+ ", got: " + outResources.size());
}
for (ModuleData r : inResources) {
for (ModuleEntry r : inResources) {
String path = r.getPath();
if (!outResources.contains(r)) {
throw new AssertionError("Class not found: " + path);
}
String modifiedPath = path + SUFFIX;
if (!outResources.contains(Pool.newResource(modifiedPath, new byte[0]))) {
if (!outResources.contains(ModuleEntry.create(modifiedPath, new byte[0]))) {
throw new AssertionError("Class not found: " + modifiedPath);
}
}
@ -204,7 +204,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
AsmPools pools = getPools();
AsmGlobalPool globalPool = pools.getGlobalPool();
WritableClassPool transformedClasses = globalPool.getTransformedClasses();
for (ModuleData res : globalPool.getClasses()) {
for (ModuleEntry res : globalPool.getClasses()) {
ClassReader reader = globalPool.getClassReader(res);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_FRAMES);
reader.accept(new AddMethodClassVisitor(writer), ClassReader.EXPAND_FRAMES);
@ -213,14 +213,14 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
}
@Override
public void test(Pool inResources, Pool outResources) throws Exception {
Collection<ModuleData> inClasses = extractClasses(inResources);
Collection<ModuleData> outClasses = extractClasses(outResources);
public void test(ModulePool inResources, ModulePool outResources) throws Exception {
Collection<ModuleEntry> inClasses = extractClasses(inResources);
Collection<ModuleEntry> outClasses = extractClasses(outResources);
if (inClasses.size() != outClasses.size()) {
throw new AssertionError("Number of classes. Expected: " + (inClasses.size())
+ ", got: " + outClasses.size());
}
for (ModuleData out : outClasses) {
for (ModuleEntry out : outClasses) {
String path = out.getPath();
if (!inClasses.contains(out)) {
throw new AssertionError("Class not found: " + path);
@ -248,7 +248,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
public void visit() {
AsmPools pools = getPools();
AsmGlobalPool globalPool = pools.getGlobalPool();
for (ModuleData res : globalPool.getResourceFiles()) {
for (ModuleEntry res : globalPool.getResourceFiles()) {
String path = res.getPath();
AsmModulePool modulePool = pools.getModulePool(getModule(path));
modulePool.getTransformedResourceFiles().addResourceFile(new ResourceFile(removeModule(path),
@ -257,14 +257,14 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
}
@Override
public void test(Pool in, Pool out) throws Exception {
Collection<ModuleData> inResources = extractResources(in);
Collection<ModuleData> outResources = extractResources(out);
public void test(ModulePool in, ModulePool out) throws Exception {
Collection<ModuleEntry> inResources = extractResources(in);
Collection<ModuleEntry> outResources = extractResources(out);
if (inResources.size() != outResources.size()) {
throw new AssertionError("Number of resources. Expected: " + inResources.size()
+ ", got: " + outResources.size());
}
for (ModuleData r : outResources) {
for (ModuleEntry r : outResources) {
String path = r.getPath();
if (!inResources.contains(r)) {
throw new AssertionError("Resource not found: " + path);
@ -287,7 +287,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
AsmGlobalPool globalPool = pools.getGlobalPool();
WritableClassPool transformedClasses = globalPool.getTransformedClasses();
int i = 0;
for (ModuleData res : globalPool.getClasses()) {
for (ModuleEntry res : globalPool.getClasses()) {
String path = removeModule(res.getPath());
String className = path.replace(".class", "");
if ((i & 1) == 0 && !className.endsWith("module-info")) {
@ -300,8 +300,8 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
}
@Override
public void test(Pool inResources, Pool outResources) throws Exception {
Collection<ModuleData> outClasses = extractClasses(outResources);
public void test(ModulePool inResources, ModulePool outResources) throws Exception {
Collection<ModuleEntry> outClasses = extractClasses(outResources);
if (expected != outClasses.size()) {
throw new AssertionError("Number of classes. Expected: " + expected +
", got: " + outClasses.size());
@ -318,7 +318,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
AsmPools pools = getPools();
AsmGlobalPool globalPool = pools.getGlobalPool();
int i = 0;
for (ModuleData res : globalPool.getResourceFiles()) {
for (ModuleEntry res : globalPool.getResourceFiles()) {
String path = res.getPath();
if (!path.contains("META-INF/services")) {
if ((i & 1) == 0) {
@ -335,8 +335,8 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
}
@Override
public void test(Pool in, Pool out) throws Exception {
Collection<ModuleData> outResources = extractResources(out);
public void test(ModulePool in, ModulePool out) throws Exception {
Collection<ModuleEntry> outResources = extractResources(out);
if (expectedAmount != outResources.size()) {
throw new AssertionError("Number of classes. Expected: " + expectedAmount
+ ", got: " + outResources.size());
@ -354,7 +354,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
AsmGlobalPool globalPool = pools.getGlobalPool();
WritableClassPool transformedClasses = globalPool.getTransformedClasses();
int i = 0;
for (ModuleData res : globalPool.getClasses()) {
for (ModuleEntry res : globalPool.getClasses()) {
ClassReader reader = globalPool.getClassReader(res);
String className = reader.getClassName();
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_FRAMES);
@ -374,8 +374,8 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
}
@Override
public void test(Pool inResources, Pool outResources) throws Exception {
Collection<ModuleData> outClasses = extractClasses(outResources);
public void test(ModulePool inResources, ModulePool outResources) throws Exception {
Collection<ModuleEntry> outClasses = extractClasses(outResources);
if (expected != outClasses.size()) {
throw new AssertionError("Number of classes. Expected: " + expected
+ ", got: " + outClasses.size());
@ -392,7 +392,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
AsmPools pools = getPools();
AsmGlobalPool globalPool = pools.getGlobalPool();
int i = 0;
for (ModuleData res : globalPool.getResourceFiles()) {
for (ModuleEntry res : globalPool.getResourceFiles()) {
String path = res.getPath();
String moduleName = getModule(path);
if (!path.contains("META-INF")) {
@ -412,8 +412,8 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
}
@Override
public void test(Pool inResources, Pool out) throws Exception {
Collection<ModuleData> outResources = extractResources(out);
public void test(ModulePool inResources, ModulePool out) throws Exception {
Collection<ModuleEntry> outResources = extractResources(out);
if (expectedAmount != outResources.size()) {
throw new AssertionError("Number of classes. Expected: " + expectedAmount
+ ", got: " + outResources.size());
@ -446,7 +446,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
}
@Override
public void test(Pool inResources, Pool outResources) throws Exception {
public void test(ModulePool inResources, ModulePool outResources) throws Exception {
if (!isVisitCalled()) {
throw new AssertionError("Resources not visited");
}
@ -455,7 +455,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
throw new AssertionError("Number of transformed classes not equal to expected");
}
// Check that only renamed classes and resource files are in the result.
for (ModuleData r : outResources.getContent()) {
outResources.entries().forEach(r -> {
String resourceName = r.getPath();
if (resourceName.endsWith(".class") && !resourceName.endsWith("module-info.class")) {
if (!resourceName.endsWith(SUFFIX + ".class")) {
@ -467,7 +467,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
throw new AssertionError("Resource file not renamed " + resourceName);
}
}
}
});
}
private void renameResources() throws IOException {
@ -476,7 +476,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
for (Map.Entry<String, List<String>> mod : MODULES.entrySet()) {
String moduleName = mod.getKey();
AsmModulePool modulePool = pools.getModulePool(moduleName);
for (ModuleData res : modulePool.getResourceFiles()) {
for (ModuleEntry res : modulePool.getResourceFiles()) {
ResourceFile resFile = modulePool.getResourceFile(res);
if (resFile.getPath().startsWith("META-INF/services/")) {
String newContent = new String(resFile.getContent()) + SUFFIX;
@ -492,7 +492,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase {
AsmPools pools = getPools();
AsmGlobalPool globalPool = pools.getGlobalPool();
WritableClassPool transformedClasses = globalPool.getTransformedClasses();
for (ModuleData res : globalPool.getClasses()) {
for (ModuleEntry res : globalPool.getClasses()) {
if (res.getPath().endsWith("module-info.class")) {
continue;
}

View File

@ -38,23 +38,23 @@ import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.StringTable;
import jdk.tools.jlink.internal.plugins.asm.AsmPlugin;
import jdk.tools.jlink.internal.plugins.asm.AsmPools;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
public abstract class AsmPluginTestBase {
protected static final String TEST_MODULE = "jlink.test";
protected static final Map<String, List<String>> MODULES;
private static final Predicate<ModuleData> isClass = r -> r.getPath().endsWith(".class");
private static final Predicate<ModuleEntry> isClass = r -> r.getPath().endsWith(".class");
private final List<String> classes;
private final List<String> resources;
private final Pool pool;
private final ModulePool pool;
static {
Map<String, List<String>> map = new HashMap<>();
@ -75,7 +75,7 @@ public abstract class AsmPluginTestBase {
List<String> classes = new ArrayList<>();
List<String> resources = new ArrayList<>();
pool = new PoolImpl();
pool = new ModulePoolImpl();
FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
Path root = fs.getPath("/modules");
@ -100,7 +100,7 @@ public abstract class AsmPluginTestBase {
MODULES.get(module).add(toResourceFile(p));
}
resources.add(toPath(p.toString()));
ModuleData res = Pool.newResource(toPath(p.toString()), content);
ModuleEntry res = ModuleEntry.create(toPath(p.toString()), content);
pool.add(res);
} catch (Exception ex) {
throw new RuntimeException(ex);
@ -110,17 +110,17 @@ public abstract class AsmPluginTestBase {
}
}
// There is more than 10 classes in java.base...
if (classes.size() < 10 || pool.getContent().size() < 10) {
if (classes.size() < 10 || pool.getEntryCount() < 10) {
throw new AssertionError("Not expected resource or class number");
}
//Add a fake resource file
String content = "java.lang.Object";
String path = "META-INF/services/com.foo.BarProvider";
ModuleData resFile = Pool.newResource("/" + TEST_MODULE + "/" +
ModuleEntry resFile = ModuleEntry.create("/" + TEST_MODULE + "/" +
path, content.getBytes());
pool.add(resFile);
ModuleData fakeInfoFile = Pool.newResource("/" + TEST_MODULE
ModuleEntry fakeInfoFile = ModuleEntry.create("/" + TEST_MODULE
+ "/module-info.class", moduleInfos.get(0));
pool.add(fakeInfoFile);
MODULES.get(TEST_MODULE).add(path);
@ -144,20 +144,20 @@ public abstract class AsmPluginTestBase {
return resources;
}
public Pool getPool() {
public ModulePool getPool() {
return pool;
}
public abstract void test() throws Exception;
public Collection<ModuleData> extractClasses(Pool pool) {
return pool.getContent().stream()
public Collection<ModuleEntry> extractClasses(ModulePool pool) {
return pool.entries()
.filter(isClass)
.collect(Collectors.toSet());
}
public Collection<ModuleData> extractResources(Pool pool) {
return pool.getContent().stream()
public Collection<ModuleEntry> extractResources(ModulePool pool) {
return pool.entries()
.filter(isClass.negate())
.collect(Collectors.toSet());
}
@ -209,9 +209,9 @@ public abstract class AsmPluginTestBase {
return pools != null;
}
public Pool visit(Pool inResources) throws IOException {
public ModulePool visit(ModulePool inResources) throws IOException {
try {
Pool outResources = new PoolImpl(inResources.getByteOrder(), new StringTable() {
ModulePool outResources = new ModulePoolImpl(inResources.getByteOrder(), new StringTable() {
@Override
public int addString(String str) {
return -1;
@ -239,7 +239,7 @@ public abstract class AsmPluginTestBase {
}
public abstract void visit();
public abstract void test(Pool inResources, Pool outResources) throws Exception;
public abstract void test(ModulePool inResources, ModulePool outResources) throws Exception;
@Override
public String getName() {

View File

@ -45,8 +45,8 @@ import java.util.logging.Logger;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.tools.jlink.internal.plugins.asm.AsmModulePool;
import jdk.tools.jlink.internal.plugins.asm.AsmPool;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
public class BasicTest extends AsmPluginTestBase {
@ -61,7 +61,7 @@ public class BasicTest extends AsmPluginTestBase {
@Override
public void test() throws Exception {
BasicPlugin basicPlugin = new BasicPlugin(getClasses());
Pool res = basicPlugin.visit(getPool());
ModulePool res = basicPlugin.visit(getPool());
basicPlugin.test(getPool(), res);
}
@ -107,13 +107,13 @@ public class BasicTest extends AsmPluginTestBase {
}
@Override
public void test(Pool inResources, Pool outResources) throws Exception {
public void test(ModulePool inResources, ModulePool outResources) throws Exception {
if (!isVisitCalled()) {
throw new AssertionError("Resources not visited");
}
if (inResources.getContent().size() != outResources.getContent().size()) {
throw new AssertionError("Input size " + inResources.getContent().size() +
" != to " + outResources.getContent().size());
if (inResources.getEntryCount() != outResources.getEntryCount()) {
throw new AssertionError("Input size " + inResources.getEntryCount() +
" != to " + outResources.getEntryCount());
}
}
@ -142,7 +142,7 @@ public class BasicTest extends AsmPluginTestBase {
private void testPools() throws IOException {
Set<String> remain = new HashSet<>(classes);
for (ModuleData res : getPools().getGlobalPool().getClasses()) {
for (ModuleEntry res : getPools().getGlobalPool().getClasses()) {
ClassReader reader = getPools().getGlobalPool().getClassReader(res);
String className = reader.getClassName();
// Wrong naming of module-info.class in ASM

View File

@ -35,14 +35,15 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.tools.jlink.internal.plugins.asm.AsmPool.WritableClassPool;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
public class IdentityPluginTest extends AsmPluginTestBase {
@ -56,7 +57,7 @@ public class IdentityPluginTest extends AsmPluginTestBase {
public void test() throws Exception {
IdentityPlugin asm = new IdentityPlugin();
Pool resourcePool = asm.visit(getPool());
ModulePool resourcePool = asm.visit(getPool());
asm.test(getPool(), resourcePool);
}
@ -64,7 +65,7 @@ public class IdentityPluginTest extends AsmPluginTestBase {
@Override
public void visit() {
for (ModuleData res : getPools().getGlobalPool().getClasses()) {
for (ModuleEntry res : getPools().getGlobalPool().getClasses()) {
if (res.getPath().endsWith("module-info.class")) {
continue;
}
@ -77,7 +78,7 @@ public class IdentityPluginTest extends AsmPluginTestBase {
}
@Override
public void test(Pool inResources, Pool outResources) throws IOException {
public void test(ModulePool inResources, ModulePool outResources) throws IOException {
if (outResources.isEmpty()) {
throw new AssertionError("Empty result");
}
@ -93,13 +94,17 @@ public class IdentityPluginTest extends AsmPluginTestBase {
throw new AssertionError("Class not transformed " + className);
}
}
for (ModuleData r : outResources.getContent()) {
outResources.entries().forEach(r -> {
if (r.getPath().endsWith(".class") && !r.getPath().endsWith("module-info.class")) {
ClassReader reader = new ClassReader(new ByteArrayInputStream(r.getBytes()));
ClassWriter w = new ClassWriter(reader, ClassWriter.COMPUTE_FRAMES);
reader.accept(w, ClassReader.EXPAND_FRAMES);
try {
ClassReader reader = new ClassReader(new ByteArrayInputStream(r.getBytes()));
ClassWriter w = new ClassWriter(reader, ClassWriter.COMPUTE_FRAMES);
reader.accept(w, ClassReader.EXPAND_FRAMES);
} catch (IOException exp) {
throw new UncheckedIOException(exp);
}
}
}
});
}
@Override

View File

@ -43,7 +43,7 @@ import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.StringTable;
import jdk.tools.jlink.internal.plugins.asm.AsmGlobalPool;
import jdk.tools.jlink.internal.plugins.asm.AsmModulePool;
@ -51,7 +51,7 @@ import jdk.tools.jlink.internal.plugins.asm.AsmPlugin;
import jdk.tools.jlink.internal.plugins.asm.AsmPool.ResourceFile;
import jdk.tools.jlink.internal.plugins.asm.AsmPools;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModulePool;
public class NegativeTest extends AsmPluginTestBase {
public static void main(String[] args) throws Exception {
@ -102,7 +102,7 @@ public class NegativeTest extends AsmPluginTestBase {
}
}
};
Pool resources = new PoolImpl(ByteOrder.BIG_ENDIAN, new StringTable() {
ModulePool resources = new ModulePoolImpl(ByteOrder.BIG_ENDIAN, new StringTable() {
@Override
public int addString(String str) {
return -1;
@ -136,7 +136,7 @@ public class NegativeTest extends AsmPluginTestBase {
action(() -> pools.fillOutputResources(null), "Output resource is null", NullPointerException.class);
}
};
Pool resources = new PoolImpl(ByteOrder.BIG_ENDIAN, new StringTable() {
ModulePool resources = new ModulePoolImpl(ByteOrder.BIG_ENDIAN, new StringTable() {
@Override
public int addString(String str) {
return -1;

View File

@ -48,8 +48,8 @@ import jdk.tools.jlink.internal.plugins.asm.AsmModulePool;
import jdk.tools.jlink.internal.plugins.asm.AsmPool.ResourceFile;
import jdk.tools.jlink.internal.plugins.asm.AsmPool.WritableResourcePool;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
public class PackageMappingTest extends AsmPluginTestBase {
@ -72,7 +72,7 @@ public class PackageMappingTest extends AsmPluginTestBase {
new PackageMappingPlugin(newFiles, true)
};
for (TestPlugin p : plugins) {
Pool pool = p.visit(getPool());
ModulePool pool = p.visit(getPool());
p.test(getPool(), pool);
}
}
@ -105,12 +105,12 @@ public class PackageMappingTest extends AsmPluginTestBase {
}
@Override
public void test(Pool inResources, Pool outResources) {
public void test(ModulePool inResources, ModulePool outResources) {
Set<String> in = getPools().getGlobalPool().getResourceFiles().stream()
.map(ModuleData::getPath)
.map(ModuleEntry::getPath)
.collect(Collectors.toSet());
Set<String> out = extractResources(outResources).stream()
.map(ModuleData::getPath)
.map(ModuleEntry::getPath)
.collect(Collectors.toSet());
in.addAll(PackageMappingTest.this.newFiles);
if (!Objects.equals(in, out)) {

View File

@ -35,12 +35,13 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import jdk.tools.jlink.internal.plugins.asm.AsmModulePool;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
public class SortingTest extends AsmPluginTestBase {
@ -66,7 +67,7 @@ public class SortingTest extends AsmPluginTestBase {
List<String> sorted = new ArrayList<>(getResources());
sorted.sort(null);
ClassSorterPlugin sorterPlugin = new ClassSorterPlugin(sorted);
Pool resourcePool = sorterPlugin.visit(getPool());
ModulePool resourcePool = sorterPlugin.visit(getPool());
sorterPlugin.test(getPool(), resourcePool);
}
@ -78,7 +79,7 @@ public class SortingTest extends AsmPluginTestBase {
List<String> sorted = new ArrayList<>(getResources());
sorted.sort((s1, s2) -> -getModuleName(s1).compareTo(getModuleName(s2)));
ModuleSorterPlugin sorterPlugin = new ModuleSorterPlugin();
Pool resourcePool = sorterPlugin.visit(getPool());
ModulePool resourcePool = sorterPlugin.visit(getPool());
sorterPlugin.test(getPool(), resourcePool);
}
@ -88,8 +89,8 @@ public class SortingTest extends AsmPluginTestBase {
public void visit() {
for (AsmModulePool modulePool : getPools().getModulePools()) {
modulePool.setSorter(resources -> {
List<String> sort = resources.getContent().stream()
.map(ModuleData::getPath)
List<String> sort = resources.entries()
.map(ModuleEntry::getPath)
.collect(Collectors.toList());
sort.sort(null);
return sort;
@ -102,21 +103,21 @@ public class SortingTest extends AsmPluginTestBase {
}
@Override
public void test(Pool inResources, Pool outResources) throws Exception {
public void test(ModulePool inResources, ModulePool outResources) throws Exception {
if (!isVisitCalled()) {
throw new AssertionError("Resources not visited");
}
List<String> sortedResourcePaths = outResources.getContent().stream()
.map(ModuleData::getPath)
List<String> sortedResourcePaths = outResources.entries()
.map(ModuleEntry::getPath)
.collect(Collectors.toList());
List<String> defaultResourceOrder = new ArrayList<>();
for (ModuleData r : inResources.getContent()) {
if (!inResources.getContent().contains(r)) {
inResources.entries().forEach(r -> {
if (!inResources.contains(r)) {
throw new AssertionError("Resource " + r.getPath() + " not in result pool");
}
defaultResourceOrder.add(r.getPath());
}
});
// Check that default sorting is not equal to sorted one
if (defaultResourceOrder.equals(sortedResourcePaths)) {
throw new AssertionError("Sorting not applied, default ordering");
@ -147,27 +148,28 @@ public class SortingTest extends AsmPluginTestBase {
public void visit() {
getPools().getGlobalPool().setSorter(
(resources) -> expectedClassesOrder.stream()
.map(resources::get)
.map(ModuleData::getPath)
.map(resources::findEntry)
.map(Optional::get)
.map(ModuleEntry::getPath)
.collect(Collectors.toList()));
}
@Override
public void test(Pool inResources, Pool outResources) throws Exception {
public void test(ModulePool inResources, ModulePool outResources) throws Exception {
if (!isVisitCalled()) {
throw new AssertionError("Resources not visited");
}
List<String> sortedResourcePaths = outResources.getContent().stream()
.map(ModuleData::getPath)
List<String> sortedResourcePaths = outResources.entries()
.map(ModuleEntry::getPath)
.collect(Collectors.toList());
List<String> defaultResourceOrder = new ArrayList<>();
for (ModuleData r : getPool().getContent()) {
if (!getPool().getContent().contains(r)) {
getPool().entries().forEach(r -> {
if (!getPool().contains(r)) {
throw new AssertionError("Resource " + r.getPath() + " not in result pool");
}
defaultResourceOrder.add(r.getPath());
}
});
// Check that default sorting is not equal to sorted one
if (defaultResourceOrder.equals(sortedResourcePaths)) {
throw new AssertionError("Sorting not applied, default ordering");

View File

@ -46,8 +46,8 @@ import jdk.tools.jlink.internal.plugins.asm.AsmPool.ClassReaderVisitor;
import jdk.tools.jlink.internal.plugins.asm.AsmPool.ResourceFile;
import jdk.tools.jlink.internal.plugins.asm.AsmPool.ResourceFileVisitor;
import jdk.tools.jlink.internal.plugins.asm.AsmPools;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
public class VisitorTest extends AsmPluginTestBase {
@ -69,7 +69,7 @@ public class VisitorTest extends AsmPluginTestBase {
};
for (TestPlugin p : plugins) {
System.err.println("Testing: " + p.getName());
Pool out = p.visit(getPool());
ModulePool out = p.visit(getPool());
p.test(getPool(), out);
}
}
@ -149,15 +149,15 @@ public class VisitorTest extends AsmPluginTestBase {
}
@Override
public void test(Pool in, Pool out) throws Exception {
Collection<ModuleData> inClasses = getPool.apply(getPools()).getClasses();
public void test(ModulePool in, ModulePool out) throws Exception {
Collection<ModuleEntry> inClasses = getPool.apply(getPools()).getClasses();
if (inClasses.size() != classReaderVisitor.getAmount()) {
throw new AssertionError("Testing " + name + ". Number of visited classes. Expected: " +
inClasses.size() + ", got: " + classReaderVisitor.getAmount());
}
Collection<ModuleData> outClasses = extractClasses(out);
Collection<ModuleEntry> outClasses = extractClasses(out);
int changedClasses = 0;
for (ModuleData r : outClasses) {
for (ModuleEntry r : outClasses) {
if (r.getPath().endsWith("Changed.class")) {
++changedClasses;
}
@ -192,15 +192,15 @@ public class VisitorTest extends AsmPluginTestBase {
}
@Override
public void test(Pool in, Pool out) throws Exception {
Collection<ModuleData> inResources = getPool.apply(getPools()).getResourceFiles();
public void test(ModulePool in, ModulePool out) throws Exception {
Collection<ModuleEntry> inResources = getPool.apply(getPools()).getResourceFiles();
if (inResources.size() != resourceFileVisitor.getAmount()) {
throw new AssertionError("Testing " + name + ". Number of visited resources. Expected: " +
inResources.size() + ", got: " + resourceFileVisitor.getAmount());
}
Collection<ModuleData> outResources = extractResources(out);
Collection<ModuleEntry> outResources = extractResources(out);
int changedClasses = 0;
for (ModuleData r : outResources) {
for (ModuleEntry r : outResources) {
if (r.getPath().endsWith("Changed")) {
++changedClasses;
}

View File

@ -26,7 +26,9 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import jdk.tools.jlink.plugin.Pool;
import java.util.function.Function;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
public class CustomPlugin implements TransformerPlugin {
@ -37,13 +39,8 @@ public class CustomPlugin implements TransformerPlugin {
}
@Override
public void visit(Pool in, Pool out) {
in.visit(new Pool.Visitor() {
@Override
public Pool.ModuleData visit(Pool.ModuleData content) {
return content;
}
}, out);
public void visit(ModulePool in, ModulePool out) {
in.transformAndCopy(Function.identity(), out);
}
@Override
@ -61,9 +58,9 @@ public class CustomPlugin implements TransformerPlugin {
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.PROCESSOR);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.PROCESSOR);
return Collections.unmodifiableSet(set);
}
}

View File

@ -29,8 +29,8 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
/**
@ -49,23 +49,23 @@ public final class HelloPlugin implements TransformerPlugin {
}
@Override
public void visit(Pool inResources, Pool outResources) {
public void visit(ModulePool inResources, ModulePool outResources) {
try {
System.out.println("Hello!!!!!!!!!!");
File f = new File(OUTPUT_FILE);
f.createNewFile();
for (ModuleData res : inResources.getContent()) {
inResources.entries().forEach(res -> {
outResources.add(res);
}
});
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.TRANSFORMER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.TRANSFORMER);
return Collections.unmodifiableSet(set);
}

View File

@ -53,14 +53,14 @@ import jdk.internal.jimage.decompressor.ResourceDecompressor;
import jdk.internal.jimage.decompressor.ResourceDecompressorFactory;
import jdk.internal.jimage.decompressor.StringSharingDecompressorFactory;
import jdk.internal.jimage.decompressor.ZipDecompressorFactory;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.StringTable;
import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin;
import jdk.tools.jlink.internal.plugins.StringSharingPlugin;
import jdk.tools.jlink.internal.plugins.ZipPlugin;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
public class CompressorPluginTest {
@ -86,7 +86,7 @@ public class CompressorPluginTest {
new ZipDecompressorFactory()
});
Pool classes = gatherClasses(javabase);
ModulePool classes = gatherClasses(javabase);
// compress = String sharing
checkCompress(classes, new StringSharingPlugin(), null,
new ResourceDecompressorFactory[]{
@ -173,8 +173,8 @@ public class CompressorPluginTest {
Collections.singletonList(".*IOException.class"));
}
private Pool gatherResources(Path module) throws Exception {
Pool pool = new PoolImpl(ByteOrder.nativeOrder(), new StringTable() {
private ModulePool gatherResources(Path module) throws Exception {
ModulePool pool = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
@Override
public int addString(String str) {
@ -191,15 +191,15 @@ public class CompressorPluginTest {
Path p = iterator.next();
if (Files.isRegularFile(p)) {
byte[] content = Files.readAllBytes(p);
pool.add(Pool.newResource(p.toString(), content));
pool.add(ModuleEntry.create(p.toString(), content));
}
}
}
return pool;
}
private Pool gatherClasses(Path module) throws Exception {
Pool pool = new PoolImpl(ByteOrder.nativeOrder(), new StringTable() {
private ModulePool gatherClasses(Path module) throws Exception {
ModulePool pool = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
@Override
public int addString(String str) {
@ -216,27 +216,27 @@ public class CompressorPluginTest {
Path p = iterator.next();
if (Files.isRegularFile(p) && p.toString().endsWith(".class")) {
byte[] content = Files.readAllBytes(p);
pool.add(Pool.newResource(p.toString(), content));
pool.add(ModuleEntry.create(p.toString(), content));
}
}
}
return pool;
}
private void checkCompress(Pool resources, Plugin prov,
private void checkCompress(ModulePool resources, Plugin prov,
Properties config,
ResourceDecompressorFactory[] factories) throws Exception {
checkCompress(resources, prov, config, factories, Collections.emptyList(), Collections.emptyList());
}
private void checkCompress(Pool resources, Plugin prov,
private void checkCompress(ModulePool resources, Plugin prov,
Properties config,
ResourceDecompressorFactory[] factories,
List<String> includes,
List<String> excludes) throws Exception {
long original = 0;
long compressed = 0;
for (ModuleData resource : resources.getContent()) {
long[] original = new long[1];
long[] compressed = new long[1];
resources.entries().forEach(resource -> {
List<Pattern> includesPatterns = includes.stream()
.map(Pattern::compile)
.collect(Collectors.toList());
@ -252,7 +252,7 @@ public class CompressorPluginTest {
}
prov.configure(props);
final Map<Integer, String> strings = new HashMap<>();
PoolImpl inputResources = new PoolImpl(ByteOrder.nativeOrder(), new StringTable() {
ModulePoolImpl inputResources = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
@Override
public int addString(String str) {
int id = strID;
@ -267,32 +267,32 @@ public class CompressorPluginTest {
}
});
inputResources.add(resource);
Pool compressedResources = applyCompressor(prov, inputResources, resource, includesPatterns, excludesPatterns);
original += resource.getLength();
compressed += compressedResources.get(resource.getPath()).getLength();
ModulePool compressedResources = applyCompressor(prov, inputResources, resource, includesPatterns, excludesPatterns);
original[0] += resource.getLength();
compressed[0] += compressedResources.findEntry(resource.getPath()).get().getLength();
applyDecompressors(factories, inputResources, compressedResources, strings, includesPatterns, excludesPatterns);
}
});
String compressors = Stream.of(factories)
.map(Object::getClass)
.map(Class::getSimpleName)
.collect(Collectors.joining(", "));
String size = "Compressed size: " + compressed + ", original size: " + original;
String size = "Compressed size: " + compressed[0] + ", original size: " + original[0];
System.out.println("Used " + compressors + ". " + size);
if (original <= compressed) {
if (original[0] <= compressed[0]) {
throw new AssertionError("java.base not compressed.");
}
}
private Pool applyCompressor(Plugin plugin,
PoolImpl inputResources,
ModuleData res,
private ModulePool applyCompressor(Plugin plugin,
ModulePoolImpl inputResources,
ModuleEntry res,
List<Pattern> includesPatterns,
List<Pattern> excludesPatterns) throws Exception {
List<Pattern> excludesPatterns) {
TransformerPlugin compressor = (TransformerPlugin) plugin;
Pool compressedPool = new PoolImpl(ByteOrder.nativeOrder(), inputResources.getStringTable());
compressor.visit(inputResources, compressedPool);
ModulePool compressedModulePool = new ModulePoolImpl(ByteOrder.nativeOrder(), inputResources.getStringTable());
compressor.visit(inputResources, compressedModulePool);
String path = res.getPath();
ModuleData compressed = compressedPool.get(path);
ModuleEntry compressed = compressedModulePool.findEntry(path).get();
CompressedResourceHeader header
= CompressedResourceHeader.readFromResource(ByteOrder.nativeOrder(), compressed.getBytes());
if (isIncluded(includesPatterns, excludesPatterns, path)) {
@ -310,29 +310,33 @@ public class CompressorPluginTest {
} else if (header != null) {
throw new AssertionError("Path should not be compressed: " + path);
}
return compressedPool;
return compressedModulePool;
}
private void applyDecompressors(ResourceDecompressorFactory[] decompressors,
Pool inputResources,
Pool compressedResources,
ModulePool inputResources,
ModulePool compressedResources,
Map<Integer, String> strings,
List<Pattern> includesPatterns,
List<Pattern> excludesPatterns) throws Exception {
for (ModuleData compressed : compressedResources.getContent()) {
List<Pattern> excludesPatterns) {
compressedResources.entries().forEach(compressed -> {
CompressedResourceHeader header = CompressedResourceHeader.readFromResource(
ByteOrder.nativeOrder(), compressed.getBytes());
String path = compressed.getPath();
ModuleData orig = inputResources.get(path);
ModuleEntry orig = inputResources.findEntry(path).get();
if (!isIncluded(includesPatterns, excludesPatterns, path)) {
continue;
return;
}
byte[] decompressed = compressed.getBytes();
for (ResourceDecompressorFactory factory : decompressors) {
ResourceDecompressor decompressor = factory.newDecompressor(new Properties());
decompressed = decompressor.decompress(
try {
ResourceDecompressor decompressor = factory.newDecompressor(new Properties());
decompressed = decompressor.decompress(
strings::get, decompressed,
CompressedResourceHeader.getSize(), header.getUncompressedSize());
} catch (Exception exp) {
throw new RuntimeException(exp);
}
}
if (decompressed.length != orig.getLength()) {
@ -345,7 +349,7 @@ public class CompressorPluginTest {
throw new AssertionError("Decompressed and original differ at index " + i);
}
}
}
});
}
private boolean isIncluded(List<Pattern> includesPatterns, List<Pattern> excludesPatterns, String path) {

View File

@ -35,12 +35,11 @@ import java.io.File;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
public class ExcludeFilesPluginTest {
@ -73,20 +72,20 @@ public class ExcludeFilesPluginTest {
prop.put(ExcludeFilesPlugin.NAME, s);
ExcludeFilesPlugin fplug = new ExcludeFilesPlugin();
fplug.configure(prop);
PoolImpl files = new PoolImpl();
PoolImpl fresult = new PoolImpl();
ModuleData f = Pool.newImageFile(module, "/" + module + "/" + sample,
ModuleDataType.CONFIG, new ByteArrayInputStream(new byte[0]), 0);
ModulePoolImpl files = new ModulePoolImpl();
ModulePoolImpl fresult = new ModulePoolImpl();
ModuleEntry f = ModuleEntry.create(module, "/" + module + "/" + sample,
ModuleEntry.Type.CONFIG, new ByteArrayInputStream(new byte[0]), 0);
files.add(f);
fplug.visit(files, fresult);
if (exclude) {
if (fresult.getContent().contains(f)) {
if (fresult.contains(f)) {
throw new Exception(sample + " should be excluded by " + s);
}
} else {
if (!fresult.getContent().contains(f)) {
if (!fresult.contains(f)) {
throw new Exception(sample + " shouldn't be excluded by " + s);
}
}

View File

@ -34,11 +34,11 @@ import java.io.File;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.plugins.ExcludePlugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
public class ExcludePluginTest {
@ -75,17 +75,17 @@ public class ExcludePluginTest {
prop.put(ExcludePlugin.NAME, s);
ExcludePlugin excludePlugin = new ExcludePlugin();
excludePlugin.configure(prop);
Pool resources = new PoolImpl();
ModuleData resource = Pool.newResource(sample, new byte[0]);
ModulePool resources = new ModulePoolImpl();
ModuleEntry resource = ModuleEntry.create(sample, new byte[0]);
resources.add(resource);
Pool result = new PoolImpl();
ModulePool result = new ModulePoolImpl();
excludePlugin.visit(resources, result);
if (exclude) {
if (result.getContent().contains(resource)) {
if (result.contains(resource)) {
throw new AssertionError(sample + " should be excluded by " + s);
}
} else {
if (!result.getContent().contains(resource)) {
if (!result.contains(resource)) {
throw new AssertionError(sample + " shouldn't be excluded by " + s);
}
}

View File

@ -32,13 +32,12 @@
import java.io.ByteArrayInputStream;
import java.util.HashMap;
import java.util.Map;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.plugins.ExcludeVMPlugin;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.TransformerPlugin;
public class ExcludeVMPluginTest {
@ -165,14 +164,14 @@ public class ExcludeVMPluginTest {
private void doCheckVM(String vm, String[] input, String jvmcfg, String[] expectedOutput, String expectdJvmCfg) throws Exception {
// Create a pool with jvm.cfg and the input paths.
byte[] jvmcfgContent = jvmcfg.getBytes();
Pool pool = new PoolImpl();
pool.add(Pool.newImageFile("java.base", "/java.base/native/jvm.cfg",
ModuleDataType.NATIVE_LIB, new ByteArrayInputStream(jvmcfgContent), jvmcfgContent.length));
ModulePool pool = new ModulePoolImpl();
pool.add(ModuleEntry.create("java.base", "/java.base/native/jvm.cfg",
ModuleEntry.Type.NATIVE_LIB, new ByteArrayInputStream(jvmcfgContent), jvmcfgContent.length));
for (String in : input) {
pool.add(Pool.newImageFile("java.base", in,
ModuleDataType.NATIVE_LIB, new ByteArrayInputStream(new byte[0]), 0));
pool.add(ModuleEntry.create("java.base", in,
ModuleEntry.Type.NATIVE_LIB, new ByteArrayInputStream(new byte[0]), 0));
}
Pool out = new PoolImpl();
ModulePool out = new ModulePoolImpl();
TransformerPlugin p = new ExcludeVMPlugin();
Map<String, String> config = new HashMap<>();
@ -182,22 +181,22 @@ public class ExcludeVMPluginTest {
p.configure(config);
p.visit(pool, out);
String newContent = new String(out.get("/java.base/native/jvm.cfg").stream().readAllBytes());
String newContent = new String(out.findEntry("/java.base/native/jvm.cfg").get().stream().readAllBytes());
if (!expectdJvmCfg.equals(newContent)) {
throw new Exception("Got content " + newContent + " expected " + expectdJvmCfg);
}
if (out.getContent().size() != (expectedOutput.length + 1)) {
for (ModuleData m : out.getContent()) {
if (out.getEntryCount() != (expectedOutput.length + 1)) {
out.entries().forEach(m -> {
System.err.println(m.getPath());
}
throw new Exception("Invalid output size " + out.getContent().size() + " expected " + (expectedOutput.length + 1));
});
throw new Exception("Invalid output size " + out.getEntryCount() + " expected " + (expectedOutput.length + 1));
}
for (ModuleData md : out.getContent()) {
out.entries().forEach(md -> {
if (md.getPath().equals("/java.base/native/jvm.cfg")) {
continue;
return;
}
boolean contained = false;
for (String o : expectedOutput) {
@ -207,9 +206,9 @@ public class ExcludeVMPluginTest {
}
}
if (!contained) {
throw new Exception(md.getPath() + " not expected");
throw new RuntimeException(md.getPath() + " not expected");
}
}
});
}

View File

@ -26,6 +26,7 @@
* @summary Test files copy plugin
* @author Jean-Francois Denise
* @modules jdk.jlink/jdk.tools.jlink.internal
* jdk.jlink/jdk.tools.jlink.builder
* jdk.jlink/jdk.tools.jlink.internal.plugins
* @run main FileCopierPluginTest
*/
@ -36,13 +37,12 @@ import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.Pool.ModuleDataType;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
public class FileCopierPluginTest {
@ -85,21 +85,20 @@ public class FileCopierPluginTest {
Map<String, String> conf = new HashMap<>();
conf.put(FileCopierPlugin.NAME, builder.toString());
plug.configure(conf);
Pool pool = new PoolImpl();
plug.visit(new PoolImpl(), pool);
if (pool.getContent().size() != expected) {
ModulePool pool = new ModulePoolImpl();
plug.visit(new ModulePoolImpl(), pool);
if (pool.getEntryCount() != expected) {
throw new AssertionError("Wrong number of added files");
}
for (ModuleData f : pool.getContent()) {
if (!f.getType().equals(ModuleDataType.OTHER)) {
pool.entries().forEach(f -> {
if (!f.getType().equals(ModuleEntry.Type.OTHER)) {
throw new AssertionError("Invalid type " + f.getType()
+ " for file " + f.getPath());
}
if (f.stream() == null) {
throw new AssertionError("Null stream for file " + f.getPath());
}
}
});
Path root = new File(".").toPath();
DefaultImageBuilder imgbuilder = new DefaultImageBuilder(root);
imgbuilder.storeFiles(pool);

View File

@ -26,6 +26,7 @@
* @summary Test last sorter property
* @author Jean-Francois Denise
* @modules jdk.jlink/jdk.tools.jlink.internal
* jdk.jlink/jdk.tools.jlink
* @run main/othervm LastSorterTest
*/
@ -40,12 +41,12 @@ import java.util.Set;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
public class LastSorterTest {
@ -80,7 +81,7 @@ public class LastSorterTest {
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config);
// check order
PoolImpl res = fillOutResourcePool();
ModulePoolImpl res = fillOutResourceModulePool();
try {
stack.visitResources(res);
@ -91,18 +92,18 @@ public class LastSorterTest {
}
}
private PoolImpl fillOutResourcePool() throws Exception {
PoolImpl res = new PoolImpl();
res.add(Pool.newResource("/eee/bbb/res1.class", new byte[90]));
res.add(Pool.newResource("/aaaa/bbb/res2.class", new byte[90]));
res.add(Pool.newResource("/bbb/aa/res1.class", new byte[90]));
res.add(Pool.newResource("/aaaa/bbb/res3.class", new byte[90]));
res.add(Pool.newResource("/bbb/aa/res2.class", new byte[90]));
res.add(Pool.newResource("/fff/bbb/res1.class", new byte[90]));
res.add(Pool.newResource("/aaaa/bbb/res1.class", new byte[90]));
res.add(Pool.newResource("/bbb/aa/res3.class", new byte[90]));
res.add(Pool.newResource("/ccc/bbb/res1.class", new byte[90]));
res.add(Pool.newResource("/ddd/bbb/res1.class", new byte[90]));
private ModulePoolImpl fillOutResourceModulePool() throws Exception {
ModulePoolImpl res = new ModulePoolImpl();
res.add(ModuleEntry.create("/eee/bbb/res1.class", new byte[90]));
res.add(ModuleEntry.create("/aaaa/bbb/res2.class", new byte[90]));
res.add(ModuleEntry.create("/bbb/aa/res1.class", new byte[90]));
res.add(ModuleEntry.create("/aaaa/bbb/res3.class", new byte[90]));
res.add(ModuleEntry.create("/bbb/aa/res2.class", new byte[90]));
res.add(ModuleEntry.create("/fff/bbb/res1.class", new byte[90]));
res.add(ModuleEntry.create("/aaaa/bbb/res1.class", new byte[90]));
res.add(ModuleEntry.create("/bbb/aa/res3.class", new byte[90]));
res.add(ModuleEntry.create("/ccc/bbb/res1.class", new byte[90]));
res.add(ModuleEntry.create("/ddd/bbb/res1.class", new byte[90]));
return res;
}
@ -124,7 +125,7 @@ public class LastSorterTest {
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config);
// check order
PoolImpl res = fillOutResourcePool();
ModulePoolImpl res = fillOutResourceModulePool();
stack.visitResources(res);
}
@ -159,7 +160,7 @@ public class LastSorterTest {
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config);
// check order
PoolImpl res = fillOutResourcePool();
ModulePoolImpl res = fillOutResourceModulePool();
try {
stack.visitResources(res);
throw new AssertionError("Order was changed after the last sorter, but no exception occurred");
@ -178,17 +179,17 @@ public class LastSorterTest {
}
@Override
public void visit(Pool resources, Pool output) {
List<ModuleData> paths = new ArrayList<>();
for (ModuleData res : resources.getContent()) {
public void visit(ModulePool resources, ModulePool output) {
List<ModuleEntry> paths = new ArrayList<>();
resources.entries().forEach(res -> {
if (res.getPath().startsWith(starts)) {
paths.add(0, res);
} else {
paths.add(res);
}
}
});
for (ModuleData r : paths) {
for (ModuleEntry r : paths) {
output.add(r);
}
}
@ -199,9 +200,9 @@ public class LastSorterTest {
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.TRANSFORMER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.TRANSFORMER);
return Collections.unmodifiableSet(set);
}

View File

@ -36,11 +36,12 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import jdk.tools.jlink.internal.PoolImpl;
import java.util.stream.Collectors;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.plugins.OrderResourcesPlugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
public class OrderResourcesPluginTest {
@ -50,52 +51,52 @@ public class OrderResourcesPluginTest {
}
public void test() throws Exception {
ModuleData[] array = {
Pool.newResource("/module1/toto1.class", new byte[0]),
Pool.newResource("/module2/toto2.class", new byte[0]),
Pool.newResource("/module3/toto3.class", new byte[0]),
Pool.newResource("/module3/toto3/module-info.class", new byte[0]),
Pool.newResource("/zazou/toto.class", new byte[0]),
Pool.newResource("/module4/zazou.class", new byte[0]),
Pool.newResource("/module5/toto5.class", new byte[0]),
Pool.newResource("/module6/toto6/module-info.class", new byte[0])
ModuleEntry[] array = {
ModuleEntry.create("/module1/toto1.class", new byte[0]),
ModuleEntry.create("/module2/toto2.class", new byte[0]),
ModuleEntry.create("/module3/toto3.class", new byte[0]),
ModuleEntry.create("/module3/toto3/module-info.class", new byte[0]),
ModuleEntry.create("/zazou/toto.class", new byte[0]),
ModuleEntry.create("/module4/zazou.class", new byte[0]),
ModuleEntry.create("/module5/toto5.class", new byte[0]),
ModuleEntry.create("/module6/toto6/module-info.class", new byte[0])
};
ModuleData[] sorted = {
Pool.newResource("/zazou/toto.class", new byte[0]),
Pool.newResource("/module3/toto3/module-info.class", new byte[0]),
Pool.newResource("/module6/toto6/module-info.class", new byte[0]),
Pool.newResource("/module1/toto1.class", new byte[0]),
Pool.newResource("/module2/toto2.class", new byte[0]),
Pool.newResource("/module3/toto3.class", new byte[0]),
Pool.newResource("/module4/zazou.class", new byte[0]),
Pool.newResource("/module5/toto5.class", new byte[0])
ModuleEntry[] sorted = {
ModuleEntry.create("/zazou/toto.class", new byte[0]),
ModuleEntry.create("/module3/toto3/module-info.class", new byte[0]),
ModuleEntry.create("/module6/toto6/module-info.class", new byte[0]),
ModuleEntry.create("/module1/toto1.class", new byte[0]),
ModuleEntry.create("/module2/toto2.class", new byte[0]),
ModuleEntry.create("/module3/toto3.class", new byte[0]),
ModuleEntry.create("/module4/zazou.class", new byte[0]),
ModuleEntry.create("/module5/toto5.class", new byte[0])
};
ModuleData[] sorted2 = {
Pool.newResource("/module5/toto5.class", new byte[0]),
Pool.newResource("/module6/toto6/module-info.class", new byte[0]),
Pool.newResource("/module4/zazou.class", new byte[0]),
Pool.newResource("/module3/toto3.class", new byte[0]),
Pool.newResource("/module3/toto3/module-info.class", new byte[0]),
Pool.newResource("/module1/toto1.class", new byte[0]),
Pool.newResource("/module2/toto2.class", new byte[0]),
Pool.newResource("/zazou/toto.class", new byte[0])
ModuleEntry[] sorted2 = {
ModuleEntry.create("/module5/toto5.class", new byte[0]),
ModuleEntry.create("/module6/toto6/module-info.class", new byte[0]),
ModuleEntry.create("/module4/zazou.class", new byte[0]),
ModuleEntry.create("/module3/toto3.class", new byte[0]),
ModuleEntry.create("/module3/toto3/module-info.class", new byte[0]),
ModuleEntry.create("/module1/toto1.class", new byte[0]),
ModuleEntry.create("/module2/toto2.class", new byte[0]),
ModuleEntry.create("/zazou/toto.class", new byte[0])
};
Pool resources = new PoolImpl();
for (ModuleData r : array) {
ModulePool resources = new ModulePoolImpl();
for (ModuleEntry r : array) {
resources.add(r);
}
{
Pool out = new PoolImpl();
ModulePool out = new ModulePoolImpl();
Map<String, String> config = new HashMap<>();
config.put(OrderResourcesPlugin.NAME, "/zazou/*,*/module-info.class");
TransformerPlugin p = new OrderResourcesPlugin();
p.configure(config);
p.visit(resources, out);
check(out.getContent(), sorted);
check(out.entries().collect(Collectors.toList()), sorted);
}
{
@ -112,26 +113,26 @@ public class OrderResourcesPluginTest {
}
Files.write(order.toPath(), builder.toString().getBytes());
Pool out = new PoolImpl();
ModulePool out = new ModulePoolImpl();
Map<String, String> config = new HashMap<>();
config.put(OrderResourcesPlugin.NAME, "@" + order.getAbsolutePath());
TransformerPlugin p = new OrderResourcesPlugin();
p.configure(config);
p.visit(resources, out);
check(out.getContent(), sorted2);
check(out.entries().collect(Collectors.toList()), sorted2);
}
}
private void check(Collection<ModuleData> outResources,
ModuleData[] sorted) {
private void check(Collection<ModuleEntry> outResources,
ModuleEntry[] sorted) {
if (outResources.size() != sorted.length) {
throw new AssertionError("Wrong number of resources:\n"
+ "expected: " + Arrays.toString(sorted) + ",\n"
+ " got: " + outResources);
}
int i = 0;
for (ModuleData r : outResources) {
for (ModuleEntry r : outResources) {
System.err.println("Resource: " + r);
if (!sorted[i].getPath().equals(r.getPath())) {
throw new AssertionError("Resource not properly sorted, difference at: " + i + "\n"

View File

@ -44,8 +44,8 @@ import java.util.Set;
import jdk.tools.jlink.internal.PluginOrderingGraph;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.Plugin.CATEGORY;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Plugin.Category;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
public class PluginOrderTest {
@ -96,8 +96,8 @@ public class PluginOrderTest {
set.add("plug2");
List<Plugin> plugins = new ArrayList<>();
plugins.add(new Plug("plug2", Collections.emptySet(), Collections.emptySet(),
CATEGORY.TRANSFORMER));
plugins.add(new Plug("plug1", set, Collections.emptySet(), CATEGORY.TRANSFORMER));
Category.TRANSFORMER));
plugins.add(new Plug("plug1", set, Collections.emptySet(), Category.TRANSFORMER));
List<Plugin> ordered = PluginOrderingGraph.sort(plugins);
if (ordered.get(0) != plugins.get(1) || ordered.get(1) != plugins.get(0)) {
throw new Exception("Invalid sorting");
@ -108,32 +108,32 @@ public class PluginOrderTest {
Set<String> lst1 = new HashSet<>();
lst1.add("plug2");
lst1.add("plug3");
Plugin p1 = new Plug("plug1", lst1, Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p1 = new Plug("plug1", lst1, Collections.emptySet(), Category.TRANSFORMER);
Plugin p2 = new Plug("plug2", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p2 = new Plug("plug2", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER);
Set<String> lst3 = new HashSet<>();
lst3.add("plug4");
lst3.add("plug6");
Plugin p3 = new Plug("plug3", lst3, Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p3 = new Plug("plug3", lst3, Collections.emptySet(), Category.TRANSFORMER);
Plugin p4 = new Plug("plug4", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p4 = new Plug("plug4", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER);
Set<String> lst5 = new HashSet<>();
lst5.add("plug3");
lst5.add("plug1");
lst5.add("plug2");
lst5.add("plug6");
Plugin p5 = new Plug("plug5", lst5, Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p5 = new Plug("plug5", lst5, Collections.emptySet(), Category.TRANSFORMER);
Set<String> lst6 = new HashSet<>();
lst6.add("plug4");
lst6.add("plug2");
Plugin p6 = new Plug("plug6", lst6, Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p6 = new Plug("plug6", lst6, Collections.emptySet(), Category.TRANSFORMER);
Plugin p7 = new Plug("plug7", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p7 = new Plug("plug7", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER);
Plugin p8 = new Plug("plug8", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p8 = new Plug("plug8", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER);
List<Plugin> plugins = new ArrayList<>();
plugins.add(p1);
@ -153,11 +153,11 @@ public class PluginOrderTest {
set2.add("plug1");
List<Plugin> plugins = new ArrayList<>();
plugins.add(new Plug("plug2", set2, Collections.emptySet(),
CATEGORY.TRANSFORMER));
Category.TRANSFORMER));
Set<String> set1 = new HashSet<>();
set1.add("plug2");
plugins.add(new Plug("plug1", set1, Collections.emptySet(), CATEGORY.TRANSFORMER));
plugins.add(new Plug("plug1", set1, Collections.emptySet(), Category.TRANSFORMER));
PluginOrderingGraph.sort(plugins);
}
@ -166,31 +166,31 @@ public class PluginOrderTest {
Set<String> lst1 = new HashSet<>();
lst1.add("plug2");
lst1.add("plug3");
Plugin p1 = new Plug("plug1", lst1, Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p1 = new Plug("plug1", lst1, Collections.emptySet(), Category.TRANSFORMER);
Plugin p2 = new Plug("plug2", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p2 = new Plug("plug2", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER);
Set<String> lst3 = new HashSet<>();
lst3.add("plug4");
lst3.add("plug6");
Plugin p3 = new Plug("plug3", lst3, Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p3 = new Plug("plug3", lst3, Collections.emptySet(), Category.TRANSFORMER);
Plugin p4 = new Plug("plug4", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p4 = new Plug("plug4", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER);
Set<String> lst5 = new HashSet<>();
lst5.add("plug3");
lst5.add("plug1");
lst5.add("plug2");
Plugin p5 = new Plug("plug5", lst5, Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p5 = new Plug("plug5", lst5, Collections.emptySet(), Category.TRANSFORMER);
Set<String> lst6 = new HashSet<>();
lst6.add("plug4");
lst6.add("plug1");
Plugin p6 = new Plug("plug6", lst6, Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p6 = new Plug("plug6", lst6, Collections.emptySet(), Category.TRANSFORMER);
Plugin p7 = new Plug("plug7", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p7 = new Plug("plug7", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER);
Plugin p8 = new Plug("plug8", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p8 = new Plug("plug8", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER);
List<Plugin> plugins = new ArrayList<>();
plugins.add(p1);
@ -208,8 +208,8 @@ public class PluginOrderTest {
Set<String> lst1 = new HashSet<>();
lst1.add("plug2");
lst1.add("plug3");
Plugin p = new Plug("plug1", lst1, Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p2 = new Plug("plug2", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER);
Plugin p = new Plug("plug1", lst1, Collections.emptySet(), Category.TRANSFORMER);
Plugin p2 = new Plug("plug2", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER);
Set<String> lst3 = new HashSet<>();
lst3.add("plug2");
@ -217,7 +217,7 @@ public class PluginOrderTest {
Set<String> lst4 = new HashSet<>();
lst4.add("plug1");
Plugin p3 = new Plug("plug3", lst4, lst3, CATEGORY.TRANSFORMER);
Plugin p3 = new Plug("plug3", lst4, lst3, Category.TRANSFORMER);
List<Plugin> plugins = new ArrayList<>();
plugins.add(p);
plugins.add(p2);
@ -229,10 +229,10 @@ public class PluginOrderTest {
private final Set<String> isBefore;
private final Set<String> isAfter;
private final CATEGORY category;
private final Category category;
private final String name;
private Plug(String name, Set<String> isBefore, Set<String> isAfter, CATEGORY category) {
private Plug(String name, Set<String> isBefore, Set<String> isAfter, Category category) {
this.name = name;
this.isBefore = isBefore;
this.isAfter = isAfter;
@ -255,12 +255,12 @@ public class PluginOrderTest {
}
@Override
public void visit(Pool in, Pool out) {
public void visit(ModulePool in, ModulePool out) {
}
@Override
public Set<PluginType> getType() {
public Set<Category> getType() {
return Collections.singleton(category);
}

View File

@ -26,6 +26,7 @@
* @summary Negative test for ImagePluginStack.
* @author Andrei Eremeev
* @modules jdk.jlink/jdk.tools.jlink.internal
* jdk.jlink/jdk.tools.jlink
* @run main/othervm PluginsNegativeTest
*/
import java.lang.reflect.Layer;
@ -39,11 +40,12 @@ import java.util.Set;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
public class PluginsNegativeTest {
@ -96,8 +98,8 @@ public class PluginsNegativeTest {
plugins.add(createPlugin("plugin"));
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new PluginsConfiguration(plugins,
null, null));
PoolImpl inResources = new PoolImpl();
inResources.add(Pool.newResource("/aaa/bbb/A", new byte[10]));
ModulePoolImpl inResources = new ModulePoolImpl();
inResources.add(ModuleEntry.create("/aaa/bbb/A", new byte[10]));
try {
stack.visitResources(inResources);
throw new AssertionError("Exception expected when output resource is empty");
@ -110,8 +112,8 @@ public class PluginsNegativeTest {
plugins.add(createPlugin("plugin"));
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new PluginsConfiguration(plugins,
null, null));
PoolImpl inResources = new PoolImpl();
PoolImpl outResources = (PoolImpl) stack.visitResources(inResources);
ModulePoolImpl inResources = new ModulePoolImpl();
ModulePoolImpl outResources = (ModulePoolImpl) stack.visitResources(inResources);
if (!outResources.isEmpty()) {
throw new AssertionError("Output resource is not empty");
}
@ -126,7 +128,7 @@ public class PluginsNegativeTest {
}
@Override
public void visit(Pool inResources, Pool outResources) {
public void visit(ModulePool inResources, ModulePool outResources) {
// do nothing
}
@ -136,9 +138,9 @@ public class PluginsNegativeTest {
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.TRANSFORMER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.TRANSFORMER);
return Collections.unmodifiableSet(set);
}

View File

@ -26,6 +26,7 @@
* @summary Test previsitor
* @author Andrei Eremeev
* @modules jdk.jlink/jdk.tools.jlink.internal
* jdk.jlink/jdk.tools.jlink
* @run main/othervm PrevisitorTest
*/
import java.nio.ByteOrder;
@ -36,19 +37,20 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.ResourcePrevisitor;
import jdk.tools.jlink.internal.StringTable;
import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
public class PrevisitorTest {
@ -68,17 +70,17 @@ public class PrevisitorTest {
plugins.add(createPlugin(CustomPlugin.NAME));
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new Jlink.PluginsConfiguration(plugins,
null, null));
PoolImpl inResources = new PoolImpl(ByteOrder.nativeOrder(), new CustomStringTable());
inResources.add(Pool.newResource("/aaa/bbb/res1.class", new byte[90]));
inResources.add(Pool.newResource("/aaa/bbb/res2.class", new byte[90]));
inResources.add(Pool.newResource("/aaa/bbb/res3.class", new byte[90]));
inResources.add(Pool.newResource("/aaa/ddd/res1.class", new byte[90]));
inResources.add(Pool.newResource("/aaa/res1.class", new byte[90]));
Pool outResources = stack.visitResources(inResources);
Collection<String> input = inResources.getContent().stream()
ModulePoolImpl inResources = new ModulePoolImpl(ByteOrder.nativeOrder(), new CustomStringTable());
inResources.add(ModuleEntry.create("/aaa/bbb/res1.class", new byte[90]));
inResources.add(ModuleEntry.create("/aaa/bbb/res2.class", new byte[90]));
inResources.add(ModuleEntry.create("/aaa/bbb/res3.class", new byte[90]));
inResources.add(ModuleEntry.create("/aaa/ddd/res1.class", new byte[90]));
inResources.add(ModuleEntry.create("/aaa/res1.class", new byte[90]));
ModulePool outResources = stack.visitResources(inResources);
Collection<String> input = inResources.entries()
.map(Object::toString)
.collect(Collectors.toList());
Collection<String> output = outResources.getContent().stream()
Collection<String> output = outResources.entries()
.map(Object::toString)
.collect(Collectors.toList());
if (!input.equals(output)) {
@ -114,19 +116,20 @@ public class PrevisitorTest {
private boolean isPrevisitCalled = false;
@Override
public void visit(Pool inResources, Pool outResources) {
public void visit(ModulePool inResources, ModulePool outResources) {
if (!isPrevisitCalled) {
throw new AssertionError("Previsit was not called");
}
CustomStringTable table = (CustomStringTable)
((PoolImpl) inResources).getStringTable();
((ModulePoolImpl) inResources).getStringTable();
if (table.size() == 0) {
throw new AssertionError("Table is empty");
}
Map<String, Integer> count = new HashMap<>();
for (int i = 0; i < table.size(); ++i) {
String s = table.getString(i);
if (inResources.get(s) != null) {
Optional<ModuleEntry> e = inResources.findEntry(s);
if (e.isPresent()) {
throw new AssertionError();
}
count.compute(s, (k, c) -> 1 + (c == null ? 0 : c));
@ -136,9 +139,9 @@ public class PrevisitorTest {
throw new AssertionError("Expected one entry in the table, got: " + v + " for " + k);
}
});
for (ModuleData r : inResources.getContent()) {
inResources.entries().forEach(r -> {
outResources.add(r);
}
});
}
@Override
@ -147,21 +150,21 @@ public class PrevisitorTest {
}
@Override
public void previsit(Pool resources, StringTable strings) {
public void previsit(ModulePool resources, StringTable strings) {
isPrevisitCalled = true;
for (ModuleData r : resources.getContent()) {
resources.entries().forEach(r -> {
String s = r.getPath();
int lastIndexOf = s.lastIndexOf('/');
if (lastIndexOf >= 0) {
strings.addString(s.substring(0, lastIndexOf));
}
}
});
}
@Override
public Set<PluginType> getType() {
Set<PluginType> set = new HashSet<>();
set.add(CATEGORY.TRANSFORMER);
public Set<Category> getType() {
Set<Category> set = new HashSet<>();
set.add(Category.TRANSFORMER);
return Collections.unmodifiableSet(set);
}
}

View File

@ -38,6 +38,8 @@
* @run main StringSharingPluginTest
*/
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.file.Files;
@ -50,11 +52,11 @@ import java.util.function.Consumer;
import jdk.internal.jimage.decompressor.CompressedResourceHeader;
import jdk.internal.jimage.decompressor.StringSharingDecompressor;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.StringTable;
import jdk.tools.jlink.internal.plugins.StringSharingPlugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
import tests.Helper;
import tests.JImageValidator;
@ -78,7 +80,7 @@ public class StringSharingPluginTest {
Map<String, Integer> map = new HashMap<>();
Map<Integer, String> reversedMap = new HashMap<>();
PoolImpl resources = new PoolImpl(ByteOrder.nativeOrder(), new StringTable() {
ModulePoolImpl resources = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
@Override
public int addString(String str) {
Integer id = map.get(str);
@ -104,7 +106,7 @@ public class StringSharingPluginTest {
byte[] content = Files.readAllBytes(p);
String path = p.toString().replace('\\', '/');
path = path.substring("/modules".length());
ModuleData res = Pool.newResource(path, content);
ModuleEntry res = ModuleEntry.create(path, content);
resources.add(res);
} catch (Exception ex) {
throw new RuntimeException(ex);
@ -115,19 +117,23 @@ public class StringSharingPluginTest {
stream.forEach(c);
}
TransformerPlugin plugin = new StringSharingPlugin();
PoolImpl result = new PoolImpl(resources.getByteOrder(), resources.getStringTable());
ModulePoolImpl result = new ModulePoolImpl(resources.getByteOrder(), resources.getStringTable());
plugin.visit(resources, result);
if (result.isEmpty()) {
throw new AssertionError("No result");
}
for (ModuleData res : result.getContent()) {
result.entries().forEach(res -> {
if (res.getPath().endsWith(".class")) {
byte[] uncompacted = StringSharingDecompressor.normalize(reversedMap::get, res.getBytes(),
try {
byte[] uncompacted = StringSharingDecompressor.normalize(reversedMap::get, res.getBytes(),
CompressedResourceHeader.getSize());
JImageValidator.readClass(uncompacted);
JImageValidator.readClass(uncompacted);
} catch (IOException exp) {
throw new UncheckedIOException(exp);
}
}
}
});
}
}

View File

@ -54,10 +54,10 @@ import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Method;
import java.util.HashMap;
import java.util.Map;
import jdk.tools.jlink.internal.PoolImpl;
import jdk.tools.jlink.internal.ModulePoolImpl;
import jdk.tools.jlink.internal.plugins.StripDebugPlugin;
import jdk.tools.jlink.plugin.Pool;
import jdk.tools.jlink.plugin.Pool.ModuleData;
import jdk.tools.jlink.plugin.ModuleEntry;
import jdk.tools.jlink.plugin.ModulePool;
import jdk.tools.jlink.plugin.TransformerPlugin;
import tests.Helper;
@ -106,7 +106,7 @@ public class StripDebugPluginTest {
path = path.replace('\\', '/');
StripDebugPlugin debug = new StripDebugPlugin();
debug.configure(new HashMap<>());
ModuleData result1 = stripDebug(debug, Pool.newResource(path,content), path, infoPath, moduleInfo);
ModuleEntry result1 = stripDebug(debug, ModuleEntry.create(path,content), path, infoPath, moduleInfo);
if (!path.endsWith("module-info.class")) {
if (result1.getLength() >= content.length) {
@ -116,7 +116,7 @@ public class StripDebugPluginTest {
checkDebugAttributes(result1.getBytes());
}
ModuleData result2 = stripDebug(debug, result1, path, infoPath, moduleInfo);
ModuleEntry result2 = stripDebug(debug, result1, path, infoPath, moduleInfo);
if (result1.getLength() != result2.getLength()) {
throw new AssertionError("removing debug info twice reduces class size of "
+ path);
@ -124,18 +124,18 @@ public class StripDebugPluginTest {
checkDebugAttributes(result1.getBytes());
}
private ModuleData stripDebug(TransformerPlugin debug, ModuleData classResource,
private ModuleEntry stripDebug(TransformerPlugin debug, ModuleEntry classResource,
String path, String infoPath, byte[] moduleInfo) throws Exception {
Pool resources = new PoolImpl();
ModulePool resources = new ModulePoolImpl();
resources.add(classResource);
if (!path.endsWith("module-info.class")) {
ModuleData res2 = Pool.newResource(infoPath, moduleInfo);
ModuleEntry res2 = ModuleEntry.create(infoPath, moduleInfo);
resources.add(res2);
}
Pool results = new PoolImpl();
ModulePool results = new ModulePoolImpl();
debug.visit(resources, results);
System.out.println(classResource.getPath());
return results.get(classResource.getPath());
return results.findEntry(classResource.getPath()).get();
}
private void checkDebugAttributes(byte[] strippedClassFile) throws IOException, ConstantPoolException {