8162538: plugin API should avoid read only pool, have module view separated from resource view and have pool builder to modify
Reviewed-by: jlaskey, psandoz
This commit is contained in:
parent
f06b866cdd
commit
2ebc9d3c1f
@ -58,8 +58,8 @@ 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.internal.ExecutableImage;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
|
||||
/**
|
||||
@ -170,10 +170,10 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeFiles(ModulePool files) {
|
||||
public void storeFiles(ResourcePool files) {
|
||||
try {
|
||||
files.entries().forEach(f -> {
|
||||
if (!f.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
try {
|
||||
accept(f);
|
||||
} catch (IOException ioExp) {
|
||||
@ -181,17 +181,17 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
}
|
||||
}
|
||||
});
|
||||
files.modules().forEach(m -> {
|
||||
files.moduleView().modules().forEach(m -> {
|
||||
// Only add modules that contain packages
|
||||
if (!m.getAllPackages().isEmpty()) {
|
||||
if (!m.packages().isEmpty()) {
|
||||
// Skip the fake module used by FileCopierPlugin when copying files.
|
||||
if (m.getName().equals(FileCopierPlugin.FAKE_MODULE)) {
|
||||
if (m.name().equals(FileCopierPlugin.FAKE_MODULE)) {
|
||||
return;
|
||||
}
|
||||
modules.add(m.getName());
|
||||
modules.add(m.name());
|
||||
}
|
||||
});
|
||||
storeFiles(modules, files.getReleaseProperties());
|
||||
storeFiles(modules, files.releaseProperties());
|
||||
|
||||
if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) {
|
||||
// launchers in the bin directory need execute permission
|
||||
@ -226,16 +226,16 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
* @param modules The set of modules that the runtime image contains.
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void prepareApplicationFiles(ModulePool imageContent, Set<String> modules) throws IOException {
|
||||
protected void prepareApplicationFiles(ResourcePool 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";
|
||||
Optional<ModuleEntry> res = imageContent.findEntry(path);
|
||||
Optional<ResourcePoolEntry> 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.get().getBytes());
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(res.get().contentBytes());
|
||||
mainClass = ModuleDescriptor.read(stream).mainClass();
|
||||
if (mainClass.isPresent()) {
|
||||
Path cmd = root.resolve("bin").resolve(module);
|
||||
@ -298,14 +298,14 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private void accept(ModuleEntry file) throws IOException {
|
||||
String fullPath = file.getPath();
|
||||
String module = "/" + file.getModule() + "/";
|
||||
private void accept(ResourcePoolEntry file) throws IOException {
|
||||
String fullPath = file.path();
|
||||
String module = "/" + file.moduleName() + "/";
|
||||
String filename = fullPath.substring(module.length());
|
||||
// Remove radical native|config|...
|
||||
filename = filename.substring(filename.indexOf('/') + 1);
|
||||
try (InputStream in = file.stream()) {
|
||||
switch (file.getType()) {
|
||||
try (InputStream in = file.content()) {
|
||||
switch (file.type()) {
|
||||
case NATIVE_LIB:
|
||||
writeEntry(in, destFile(nativeDir(filename), filename));
|
||||
break;
|
||||
|
@ -29,7 +29,7 @@ import java.util.Properties;
|
||||
|
||||
import jdk.tools.jlink.internal.ExecutableImage;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
|
||||
/**
|
||||
* 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(ModulePool content, Properties release) {
|
||||
public default void storeFiles(ResourcePool content, Properties release) {
|
||||
storeFiles(content);
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ public interface ImageBuilder {
|
||||
* @param content Pool of module content.
|
||||
* @throws PluginException
|
||||
*/
|
||||
public default void storeFiles(ModulePool content) {
|
||||
public default void storeFiles(ResourcePool content) {
|
||||
throw new UnsupportedOperationException("storeFiles");
|
||||
}
|
||||
|
||||
|
@ -26,14 +26,14 @@
|
||||
package jdk.tools.jlink.internal;
|
||||
|
||||
import java.util.Objects;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
/**
|
||||
* A LinkModuleEntry is the elementary unit of data inside an image. It is
|
||||
* A LinkResourcePoolEntry 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:
|
||||
* A LinkResourcePoolEntry is identified by a path of the form:
|
||||
* <ul>
|
||||
* <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
|
||||
* name}</li>
|
||||
@ -41,36 +41,36 @@ import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
* {@literal bin|conf|native}/{dir1}>/.../{dirN}/{file name}</li>
|
||||
* </ul>
|
||||
*/
|
||||
abstract class AbstractModuleEntry implements ModuleEntry {
|
||||
abstract class AbstractResourcePoolEntry implements ResourcePoolEntry {
|
||||
private final String path;
|
||||
private final String module;
|
||||
private final Type type;
|
||||
|
||||
/**
|
||||
* Create a new AbstractModuleEntry.
|
||||
* Create a new AbstractResourcePoolEntry.
|
||||
*
|
||||
* @param module The module name.
|
||||
* @param path The data path identifier.
|
||||
* @param type The data type.
|
||||
*/
|
||||
AbstractModuleEntry(String module, String path, Type type) {
|
||||
AbstractResourcePoolEntry(String module, String path, Type type) {
|
||||
this.module = Objects.requireNonNull(module);
|
||||
this.path = Objects.requireNonNull(path);
|
||||
this.type = Objects.requireNonNull(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getModule() {
|
||||
public final String moduleName() {
|
||||
return module;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getPath() {
|
||||
public final String path() {
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Type getType() {
|
||||
public final Type type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -81,15 +81,15 @@ abstract class AbstractModuleEntry implements ModuleEntry {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof AbstractModuleEntry)) {
|
||||
if (!(other instanceof AbstractResourcePoolEntry)) {
|
||||
return false;
|
||||
}
|
||||
AbstractModuleEntry f = (AbstractModuleEntry) other;
|
||||
AbstractResourcePoolEntry f = (AbstractResourcePoolEntry) other;
|
||||
return f.path.equals(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getPath();
|
||||
return path();
|
||||
}
|
||||
}
|
@ -29,28 +29,28 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.Objects;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
/**
|
||||
* A ModuleEntry backed by a given Archive Entry.
|
||||
* A ResourcePoolEntry backed by a given Archive Entry.
|
||||
*/
|
||||
final class ArchiveEntryModuleEntry extends AbstractModuleEntry {
|
||||
final class ArchiveEntryResourcePoolEntry extends AbstractResourcePoolEntry {
|
||||
private final Archive.Entry entry;
|
||||
|
||||
/**
|
||||
* Create a new ArchiveModuleEntry.
|
||||
* Create a new ArchiveResourcePoolEntry.
|
||||
*
|
||||
* @param module The module name.
|
||||
* @param path The data path identifier.
|
||||
* @param entry The archive Entry.
|
||||
*/
|
||||
ArchiveEntryModuleEntry(String module, String path, Archive.Entry entry) {
|
||||
ArchiveEntryResourcePoolEntry(String module, String path, Archive.Entry entry) {
|
||||
super(module, path, getImageFileType(Objects.requireNonNull(entry)));
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream stream() {
|
||||
public InputStream content() {
|
||||
try {
|
||||
return entry.stream();
|
||||
} catch (IOException ex) {
|
||||
@ -59,22 +59,22 @@ final class ArchiveEntryModuleEntry extends AbstractModuleEntry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
public long contentLength() {
|
||||
return entry.size();
|
||||
}
|
||||
|
||||
private static ModuleEntry.Type getImageFileType(Archive.Entry entry) {
|
||||
private static ResourcePoolEntry.Type getImageFileType(Archive.Entry entry) {
|
||||
switch(entry.type()) {
|
||||
case CLASS_OR_RESOURCE:
|
||||
return ModuleEntry.Type.CLASS_OR_RESOURCE;
|
||||
return ResourcePoolEntry.Type.CLASS_OR_RESOURCE;
|
||||
case CONFIG:
|
||||
return ModuleEntry.Type.CONFIG;
|
||||
return ResourcePoolEntry.Type.CONFIG;
|
||||
case NATIVE_CMD:
|
||||
return ModuleEntry.Type.NATIVE_CMD;
|
||||
return ResourcePoolEntry.Type.NATIVE_CMD;
|
||||
case NATIVE_LIB:
|
||||
return ModuleEntry.Type.NATIVE_LIB;
|
||||
return ResourcePoolEntry.Type.NATIVE_LIB;
|
||||
default:
|
||||
return ModuleEntry.Type.OTHER;
|
||||
return ResourcePoolEntry.Type.OTHER;
|
||||
}
|
||||
}
|
||||
}
|
@ -33,31 +33,31 @@ import java.io.UncheckedIOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A ModuleEntry backed by a given byte[].
|
||||
* A ResourcePoolEntry backed by a given byte[].
|
||||
*/
|
||||
class ByteArrayModuleEntry extends AbstractModuleEntry {
|
||||
class ByteArrayResourcePoolEntry extends AbstractResourcePoolEntry {
|
||||
private final byte[] buffer;
|
||||
|
||||
/**
|
||||
* Create a new ByteArrayModuleEntry.
|
||||
* Create a new ByteArrayResourcePoolEntry.
|
||||
*
|
||||
* @param module The module name.
|
||||
* @param path The data path identifier.
|
||||
* @param type The data type.
|
||||
* @param buf The byte buffer.
|
||||
*/
|
||||
ByteArrayModuleEntry(String module, String path, Type type, byte[] buffer) {
|
||||
ByteArrayResourcePoolEntry(String module, String path, Type type, byte[] buffer) {
|
||||
super(module, path, type);
|
||||
this.buffer = Objects.requireNonNull(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBytes() {
|
||||
public byte[] contentBytes() {
|
||||
return buffer.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream stream() {
|
||||
public InputStream content() {
|
||||
return new ByteArrayInputStream(buffer);
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ class ByteArrayModuleEntry extends AbstractModuleEntry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLength() {
|
||||
public long contentLength() {
|
||||
return buffer.length;
|
||||
}
|
||||
}
|
@ -42,9 +42,10 @@ 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.ModulePoolImpl.CompressedModuleData;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager.CompressedModuleData;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
/**
|
||||
* An image (native endian.)
|
||||
@ -140,7 +141,7 @@ public final class ImageFileCreator {
|
||||
}));
|
||||
ByteOrder order = ByteOrder.nativeOrder();
|
||||
BasicImageWriter writer = new BasicImageWriter(order);
|
||||
ModulePoolImpl pool = createPools(archives, entriesForModule, order, writer);
|
||||
ResourcePoolManager pool = createPoolManager(archives, entriesForModule, order, writer);
|
||||
try (OutputStream fos = Files.newOutputStream(jimageFile);
|
||||
BufferedOutputStream bos = new BufferedOutputStream(fos);
|
||||
DataOutputStream out = new DataOutputStream(bos)) {
|
||||
@ -158,52 +159,61 @@ public final class ImageFileCreator {
|
||||
ByteOrder byteOrder)
|
||||
throws IOException {
|
||||
BasicImageWriter writer = new BasicImageWriter(byteOrder);
|
||||
ModulePoolImpl allContent = createPools(archives,
|
||||
ResourcePoolManager allContent = createPoolManager(archives,
|
||||
entriesForModule, byteOrder, writer);
|
||||
ModulePoolImpl result = generateJImage(allContent,
|
||||
ResourcePool result = generateJImage(allContent,
|
||||
writer, plugins, plugins.getJImageFileOutputStream());
|
||||
|
||||
//Handle files.
|
||||
try {
|
||||
plugins.storeFiles(allContent, result, writer);
|
||||
plugins.storeFiles(allContent.resourcePool(), result, writer);
|
||||
} catch (Exception ex) {
|
||||
if (JlinkTask.DEBUG) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static ModulePoolImpl generateJImage(ModulePoolImpl allContent,
|
||||
private static ResourcePool generateJImage(ResourcePoolManager allContent,
|
||||
BasicImageWriter writer,
|
||||
ImagePluginStack pluginSupport,
|
||||
DataOutputStream out
|
||||
) throws IOException {
|
||||
ModulePoolImpl resultResources;
|
||||
ResourcePool resultResources;
|
||||
try {
|
||||
resultResources = pluginSupport.visitResources(allContent);
|
||||
} catch (PluginException pe) {
|
||||
if (JlinkTask.DEBUG) {
|
||||
pe.printStackTrace();
|
||||
}
|
||||
throw pe;
|
||||
} catch (Exception ex) {
|
||||
if (JlinkTask.DEBUG) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
throw new IOException(ex);
|
||||
}
|
||||
Set<String> duplicates = new HashSet<>();
|
||||
long[] offset = new long[1];
|
||||
|
||||
List<ModuleEntry> content = new ArrayList<>();
|
||||
List<ResourcePoolEntry> 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
|
||||
resultResources.entries().forEach(res -> {
|
||||
if (res.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
String path = res.getPath();
|
||||
if (res.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
String path = res.path();
|
||||
content.add(res);
|
||||
long uncompressedSize = res.getLength();
|
||||
long uncompressedSize = res.contentLength();
|
||||
long compressedSize = 0;
|
||||
if (res instanceof CompressedModuleData) {
|
||||
CompressedModuleData comp
|
||||
= (CompressedModuleData) res;
|
||||
compressedSize = res.getLength();
|
||||
compressedSize = res.contentLength();
|
||||
uncompressedSize = comp.getUncompressedSize();
|
||||
}
|
||||
long onFileSize = res.getLength();
|
||||
long onFileSize = res.contentLength();
|
||||
|
||||
if (duplicates.contains(path)) {
|
||||
System.err.format("duplicate resource \"%s\", skipping%n",
|
||||
@ -239,11 +249,11 @@ public final class ImageFileCreator {
|
||||
return resultResources;
|
||||
}
|
||||
|
||||
private static ModulePoolImpl createPools(Set<Archive> archives,
|
||||
private static ResourcePoolManager createPoolManager(Set<Archive> archives,
|
||||
Map<String, List<Entry>> entriesForModule,
|
||||
ByteOrder byteOrder,
|
||||
BasicImageWriter writer) throws IOException {
|
||||
ModulePoolImpl resources = new ModulePoolImpl(byteOrder, new StringTable() {
|
||||
ResourcePoolManager resources = new ResourcePoolManager(byteOrder, new StringTable() {
|
||||
|
||||
@Override
|
||||
public int addString(String str) {
|
||||
@ -273,7 +283,7 @@ public final class ImageFileCreator {
|
||||
path = "/" + mn + "/" + entry.path();
|
||||
}
|
||||
|
||||
resources.add(new ArchiveEntryModuleEntry(mn, path, entry));
|
||||
resources.add(new ArchiveEntryResourcePoolEntry(mn, path, entry));
|
||||
}
|
||||
}
|
||||
return resources;
|
||||
|
@ -37,7 +37,7 @@ import jdk.tools.jlink.Jlink;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.plugin.Plugin.Category;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
|
||||
/**
|
||||
* Plugins configuration.
|
||||
@ -122,7 +122,7 @@ public final class ImagePluginConfiguration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeFiles(ModulePool files) {
|
||||
public void storeFiles(ResourcePool files) {
|
||||
throw new PluginException("No directory setup to store files");
|
||||
}
|
||||
};
|
||||
|
@ -46,9 +46,10 @@ import jdk.internal.jimage.decompressor.Decompressor;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.builder.ImageBuilder;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.LinkModule;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolModule;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
|
||||
|
||||
/**
|
||||
* Plugins Stack. Plugins entry point to apply transformations onto resources
|
||||
@ -61,36 +62,47 @@ public final class ImagePluginStack {
|
||||
ExecutableImage retrieve(ImagePluginStack stack) throws IOException;
|
||||
}
|
||||
|
||||
public static final class OrderedResourcePool extends ModulePoolImpl {
|
||||
public static final class OrderedResourcePoolManager extends ResourcePoolManager {
|
||||
class OrderedResourcePool extends ResourcePoolImpl {
|
||||
List<ResourcePoolEntry> getOrderedList() {
|
||||
return OrderedResourcePoolManager.this.getOrderedList();
|
||||
}
|
||||
}
|
||||
|
||||
private final List<ModuleEntry> orderedList = new ArrayList<>();
|
||||
private final List<ResourcePoolEntry> orderedList = new ArrayList<>();
|
||||
private final ResourcePoolImpl poolImpl = new OrderedResourcePool();
|
||||
|
||||
public OrderedResourcePool(ByteOrder order, StringTable table) {
|
||||
public OrderedResourcePoolManager(ByteOrder order, StringTable table) {
|
||||
super(order, table);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourcePool resourcePool() {
|
||||
return poolImpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a resource.
|
||||
*
|
||||
* @param resource The Resource to add.
|
||||
*/
|
||||
@Override
|
||||
public void add(ModuleEntry resource) {
|
||||
public void add(ResourcePoolEntry resource) {
|
||||
super.add(resource);
|
||||
orderedList.add(resource);
|
||||
}
|
||||
|
||||
List<ModuleEntry> getOrderedList() {
|
||||
List<ResourcePoolEntry> getOrderedList() {
|
||||
return Collections.unmodifiableList(orderedList);
|
||||
}
|
||||
}
|
||||
|
||||
private final static class CheckOrderResourcePool extends ModulePoolImpl {
|
||||
private final static class CheckOrderResourcePoolManager extends ResourcePoolManager {
|
||||
|
||||
private final List<ModuleEntry> orderedList;
|
||||
private final List<ResourcePoolEntry> orderedList;
|
||||
private int currentIndex;
|
||||
|
||||
public CheckOrderResourcePool(ByteOrder order, List<ModuleEntry> orderedList, StringTable table) {
|
||||
public CheckOrderResourcePoolManager(ByteOrder order, List<ResourcePoolEntry> orderedList, StringTable table) {
|
||||
super(order, table);
|
||||
this.orderedList = Objects.requireNonNull(orderedList);
|
||||
}
|
||||
@ -101,10 +113,10 @@ public final class ImagePluginStack {
|
||||
* @param resource The Resource to add.
|
||||
*/
|
||||
@Override
|
||||
public void add(ModuleEntry resource) {
|
||||
ModuleEntry ordered = orderedList.get(currentIndex);
|
||||
public void add(ResourcePoolEntry resource) {
|
||||
ResourcePoolEntry ordered = orderedList.get(currentIndex);
|
||||
if (!resource.equals(ordered)) {
|
||||
throw new PluginException("Resource " + resource.getPath() + " not in the right order");
|
||||
throw new PluginException("Resource " + resource.path() + " not in the right order");
|
||||
}
|
||||
super.add(resource);
|
||||
currentIndex += 1;
|
||||
@ -209,17 +221,16 @@ public final class ImagePluginStack {
|
||||
* @return The result of the visit.
|
||||
* @throws IOException
|
||||
*/
|
||||
public ModulePoolImpl visitResources(ModulePoolImpl resources)
|
||||
public ResourcePool visitResources(ResourcePoolManager resources)
|
||||
throws Exception {
|
||||
Objects.requireNonNull(resources);
|
||||
resources.setReadOnly();
|
||||
if (resources.isEmpty()) {
|
||||
return new ModulePoolImpl(resources.getByteOrder(),
|
||||
resources.getStringTable());
|
||||
return new ResourcePoolManager(resources.byteOrder(),
|
||||
resources.getStringTable()).resourcePool();
|
||||
}
|
||||
PreVisitStrings previsit = new PreVisitStrings();
|
||||
resourcePrevisitors.stream().forEach((p) -> {
|
||||
p.previsit(resources, previsit);
|
||||
p.previsit(resources.resourcePool(), previsit);
|
||||
});
|
||||
|
||||
// Store the strings resulting from the previsit.
|
||||
@ -228,89 +239,80 @@ public final class ImagePluginStack {
|
||||
resources.getStringTable().addString(s);
|
||||
});
|
||||
|
||||
ModulePoolImpl current = resources;
|
||||
List<ModuleEntry> frozenOrder = null;
|
||||
ResourcePool resPool = resources.resourcePool();
|
||||
List<ResourcePoolEntry> frozenOrder = null;
|
||||
for (Plugin p : plugins) {
|
||||
current.setReadOnly();
|
||||
ModulePoolImpl output = null;
|
||||
ResourcePoolManager resMgr = null;
|
||||
if (p == lastSorter) {
|
||||
if (frozenOrder != null) {
|
||||
throw new Exception("Order of resources is already frozen. Plugin "
|
||||
+ p.getName() + " is badly located");
|
||||
}
|
||||
// Create a special Resource pool to compute the indexes.
|
||||
output = new OrderedResourcePool(current.getByteOrder(),
|
||||
resMgr = new OrderedResourcePoolManager(resPool.byteOrder(),
|
||||
resources.getStringTable());
|
||||
} else {// If we have an order, inject it
|
||||
if (frozenOrder != null) {
|
||||
output = new CheckOrderResourcePool(current.getByteOrder(),
|
||||
resMgr = new CheckOrderResourcePoolManager(resPool.byteOrder(),
|
||||
frozenOrder, resources.getStringTable());
|
||||
} else {
|
||||
output = new ModulePoolImpl(current.getByteOrder(),
|
||||
resMgr = new ResourcePoolManager(resPool.byteOrder(),
|
||||
resources.getStringTable());
|
||||
}
|
||||
}
|
||||
p.visit(current, output);
|
||||
if (output.isEmpty()) {
|
||||
resPool = p.transform(resPool, resMgr.resourcePoolBuilder());
|
||||
if (resPool.isEmpty()) {
|
||||
throw new Exception("Invalid resource pool for plugin " + p);
|
||||
}
|
||||
if (output instanceof OrderedResourcePool) {
|
||||
frozenOrder = ((OrderedResourcePool) output).getOrderedList();
|
||||
if (resPool instanceof OrderedResourcePoolManager.OrderedResourcePool) {
|
||||
frozenOrder = ((OrderedResourcePoolManager.OrderedResourcePool)resPool).getOrderedList();
|
||||
}
|
||||
|
||||
current = output;
|
||||
}
|
||||
current.setReadOnly();
|
||||
return current;
|
||||
return resPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* This pool wrap the original pool and automatically uncompress ModuleEntry
|
||||
* This pool wrap the original pool and automatically uncompress ResourcePoolEntry
|
||||
* if needed.
|
||||
*/
|
||||
private class LastPool implements ModulePool {
|
||||
private class LastModule implements LinkModule {
|
||||
private class LastPoolManager extends ResourcePoolManager {
|
||||
private class LastModule implements ResourcePoolModule {
|
||||
|
||||
final LinkModule module;
|
||||
final ResourcePoolModule module;
|
||||
|
||||
LastModule(LinkModule module) {
|
||||
LastModule(ResourcePoolModule module) {
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return module.getName();
|
||||
public String name() {
|
||||
return module.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ModuleEntry> findEntry(String path) {
|
||||
Optional<ModuleEntry> d = module.findEntry(path);
|
||||
public Optional<ResourcePoolEntry> findEntry(String path) {
|
||||
Optional<ResourcePoolEntry> d = module.findEntry(path);
|
||||
return d.isPresent()? Optional.of(getUncompressed(d.get())) : Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleDescriptor getDescriptor() {
|
||||
return module.getDescriptor();
|
||||
public ModuleDescriptor descriptor() {
|
||||
return module.descriptor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(ModuleEntry data) {
|
||||
throw new PluginException("pool is readonly");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAllPackages() {
|
||||
return module.getAllPackages();
|
||||
public Set<String> packages() {
|
||||
return module.packages();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
return name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<ModuleEntry> entries() {
|
||||
List<ModuleEntry> lst = new ArrayList<>();
|
||||
public Stream<ResourcePoolEntry> entries() {
|
||||
List<ResourcePoolEntry> lst = new ArrayList<>();
|
||||
module.entries().forEach(md -> {
|
||||
lst.add(getUncompressed(md));
|
||||
});
|
||||
@ -318,31 +320,27 @@ public final class ImagePluginStack {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEntryCount() {
|
||||
return module.getEntryCount();
|
||||
public int entryCount() {
|
||||
return module.entryCount();
|
||||
}
|
||||
}
|
||||
private final ModulePoolImpl pool;
|
||||
Decompressor decompressor = new Decompressor();
|
||||
Collection<ModuleEntry> content;
|
||||
|
||||
LastPool(ModulePoolImpl pool) {
|
||||
private final ResourcePool pool;
|
||||
Decompressor decompressor = new Decompressor();
|
||||
Collection<ResourcePoolEntry> content;
|
||||
|
||||
LastPoolManager(ResourcePool pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(ModuleEntry resource) {
|
||||
public void add(ResourcePoolEntry resource) {
|
||||
throw new PluginException("pool is readonly");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<LinkModule> findModule(String name) {
|
||||
Optional<LinkModule> module = pool.findModule(name);
|
||||
public Optional<ResourcePoolModule> findModule(String name) {
|
||||
Optional<ResourcePoolModule> module = pool.moduleView().findModule(name);
|
||||
return module.isPresent()? Optional.of(new LastModule(module.get())) : Optional.empty();
|
||||
}
|
||||
|
||||
@ -352,17 +350,17 @@ public final class ImagePluginStack {
|
||||
* @return The collection of modules.
|
||||
*/
|
||||
@Override
|
||||
public Stream<? extends LinkModule> modules() {
|
||||
List<LinkModule> modules = new ArrayList<>();
|
||||
pool.modules().forEach(m -> {
|
||||
public Stream<ResourcePoolModule> modules() {
|
||||
List<ResourcePoolModule> modules = new ArrayList<>();
|
||||
pool.moduleView().modules().forEach(m -> {
|
||||
modules.add(new LastModule(m));
|
||||
});
|
||||
return modules.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getModuleCount() {
|
||||
return pool.getModuleCount();
|
||||
public int moduleCount() {
|
||||
return pool.moduleView().moduleCount();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -371,7 +369,7 @@ public final class ImagePluginStack {
|
||||
* @return The stream of resources;
|
||||
*/
|
||||
@Override
|
||||
public Stream<? extends ModuleEntry> entries() {
|
||||
public Stream<ResourcePoolEntry> entries() {
|
||||
if (content == null) {
|
||||
content = new ArrayList<>();
|
||||
pool.entries().forEach(md -> {
|
||||
@ -382,8 +380,8 @@ public final class ImagePluginStack {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEntryCount() {
|
||||
return pool.getEntryCount();
|
||||
public int entryCount() {
|
||||
return pool.entryCount();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -393,22 +391,22 @@ public final class ImagePluginStack {
|
||||
* @return A Resource instance if the resource is found
|
||||
*/
|
||||
@Override
|
||||
public Optional<ModuleEntry> findEntry(String path) {
|
||||
public Optional<ResourcePoolEntry> findEntry(String path) {
|
||||
Objects.requireNonNull(path);
|
||||
Optional<ModuleEntry> res = pool.findEntry(path);
|
||||
Optional<ResourcePoolEntry> res = pool.findEntry(path);
|
||||
return res.isPresent()? Optional.of(getUncompressed(res.get())) : Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ModuleEntry> findEntryInContext(String path, ModuleEntry context) {
|
||||
public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context) {
|
||||
Objects.requireNonNull(path);
|
||||
Objects.requireNonNull(context);
|
||||
Optional<ModuleEntry> res = pool.findEntryInContext(path, context);
|
||||
Optional<ResourcePoolEntry> res = pool.findEntryInContext(path, context);
|
||||
return res.map(this::getUncompressed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(ModuleEntry res) {
|
||||
public boolean contains(ResourcePoolEntry res) {
|
||||
return pool.contains(res);
|
||||
}
|
||||
|
||||
@ -418,29 +416,27 @@ public final class ImagePluginStack {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transformAndCopy(Function<ModuleEntry, ModuleEntry> visitor, ModulePool output) {
|
||||
pool.transformAndCopy(visitor, output);
|
||||
public ByteOrder byteOrder() {
|
||||
return pool.byteOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteOrder getByteOrder() {
|
||||
return pool.getByteOrder();
|
||||
public Map<String, String> releaseProperties() {
|
||||
return pool.releaseProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getReleaseProperties() {
|
||||
return Collections.unmodifiableMap(pool.getReleaseProperties());
|
||||
}
|
||||
|
||||
private ModuleEntry getUncompressed(ModuleEntry res) {
|
||||
private ResourcePoolEntry getUncompressed(ResourcePoolEntry res) {
|
||||
if (res != null) {
|
||||
if (res instanceof ModulePoolImpl.CompressedModuleData) {
|
||||
if (res instanceof ResourcePoolManager.CompressedModuleData) {
|
||||
try {
|
||||
byte[] bytes = decompressor.decompressResource(getByteOrder(),
|
||||
(int offset) -> pool.getStringTable().getString(offset),
|
||||
res.getBytes());
|
||||
res = res.create(bytes);
|
||||
byte[] bytes = decompressor.decompressResource(byteOrder(),
|
||||
(int offset) -> ((ResourcePoolImpl)pool).getStringTable().getString(offset),
|
||||
res.contentBytes());
|
||||
res = res.copyWithContent(bytes);
|
||||
} catch (IOException ex) {
|
||||
if (JlinkTask.DEBUG) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
throw new PluginException(ex);
|
||||
}
|
||||
}
|
||||
@ -457,24 +453,24 @@ public final class ImagePluginStack {
|
||||
* @param writer
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
public void storeFiles(ModulePoolImpl original, ModulePoolImpl transformed,
|
||||
public void storeFiles(ResourcePool original, ResourcePool transformed,
|
||||
BasicImageWriter writer)
|
||||
throws Exception {
|
||||
Objects.requireNonNull(original);
|
||||
Objects.requireNonNull(transformed);
|
||||
Optional<LinkModule> javaBase = transformed.findModule("java.base");
|
||||
Optional<ResourcePoolModule> javaBase = transformed.moduleView().findModule("java.base");
|
||||
javaBase.ifPresent(mod -> {
|
||||
try {
|
||||
Map<String, String> release = transformed.getReleaseProperties();
|
||||
Map<String, String> release = transformed.releaseProperties();
|
||||
// fill release information available from transformed "java.base" module!
|
||||
ModuleDescriptor desc = mod.getDescriptor();
|
||||
ModuleDescriptor desc = mod.descriptor();
|
||||
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));
|
||||
imageBuilder.storeFiles(new LastPoolManager(transformed).resourcePool());
|
||||
}
|
||||
|
||||
public ExecutableImage getExecutableImage() throws IOException {
|
||||
|
@ -61,7 +61,7 @@ import jdk.tools.jlink.plugin.Plugin;
|
||||
* ## Should use jdk.joptsimple some day.
|
||||
*/
|
||||
public class JlinkTask {
|
||||
private static final boolean DEBUG = Boolean.getBoolean("jlink.debug");
|
||||
static final boolean DEBUG = Boolean.getBoolean("jlink.debug");
|
||||
|
||||
private static <T extends Throwable> void fail(Class<T> type,
|
||||
String format,
|
||||
|
@ -33,20 +33,20 @@ import java.nio.file.Path;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A ModuleEntry backed by a given nio Path.
|
||||
* A ResourcePoolEntry backed by a given nio Path.
|
||||
*/
|
||||
public class PathModuleEntry extends AbstractModuleEntry {
|
||||
public class PathResourcePoolEntry extends AbstractResourcePoolEntry {
|
||||
private final Path file;
|
||||
|
||||
/**
|
||||
* Create a new PathModuleEntry.
|
||||
* Create a new PathResourcePoolEntry.
|
||||
*
|
||||
* @param module The module name.
|
||||
* @param path The path for the resource content.
|
||||
* @param type The data type.
|
||||
* @param file The data file identifier.
|
||||
*/
|
||||
public PathModuleEntry(String module, String path, Type type, Path file) {
|
||||
public PathResourcePoolEntry(String module, String path, Type type, Path file) {
|
||||
super(module, path, type);
|
||||
this.file = Objects.requireNonNull(file);
|
||||
if (!Files.isRegularFile(file)) {
|
||||
@ -55,7 +55,7 @@ public class PathModuleEntry extends AbstractModuleEntry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final InputStream stream() {
|
||||
public final InputStream content() {
|
||||
try {
|
||||
return Files.newInputStream(file);
|
||||
} catch (IOException ex) {
|
||||
@ -64,7 +64,7 @@ public class PathModuleEntry extends AbstractModuleEntry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final long getLength() {
|
||||
public final long contentLength() {
|
||||
try {
|
||||
return Files.size(file);
|
||||
} catch (IOException ex) {
|
@ -26,57 +26,41 @@ package jdk.tools.jlink.internal;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Objects;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
public final class ModuleEntryFactory {
|
||||
private ModuleEntryFactory() {}
|
||||
public final class ResourcePoolEntryFactory {
|
||||
private ResourcePoolEntryFactory() {}
|
||||
|
||||
public static ModuleEntry create(String path,
|
||||
ModuleEntry.Type type, byte[] content) {
|
||||
return new ByteArrayModuleEntry(moduleFrom(path), path, type, content);
|
||||
public static ResourcePoolEntry create(String path,
|
||||
ResourcePoolEntry.Type type, byte[] content) {
|
||||
return new ByteArrayResourcePoolEntry(moduleFrom(path), path, type, content);
|
||||
}
|
||||
|
||||
public static ModuleEntry create(String path,
|
||||
ModuleEntry.Type type, Path file) {
|
||||
return new PathModuleEntry(moduleFrom(path), path, type, file);
|
||||
public static ResourcePoolEntry create(String path,
|
||||
ResourcePoolEntry.Type type, Path file) {
|
||||
return new PathResourcePoolEntry(moduleFrom(path), path, type, file);
|
||||
}
|
||||
|
||||
public static ModuleEntry create(ModuleEntry original, byte[] content) {
|
||||
return new ByteArrayModuleEntry(original.getModule(),
|
||||
original.getPath(), original.getType(), content);
|
||||
public static ResourcePoolEntry create(ResourcePoolEntry original, byte[] content) {
|
||||
return new ByteArrayResourcePoolEntry(original.moduleName(),
|
||||
original.path(), original.type(), content);
|
||||
}
|
||||
|
||||
public static ModuleEntry create(ModuleEntry original, Path file) {
|
||||
return new PathModuleEntry(original.getModule(),
|
||||
original.getPath(), original.getType(), file);
|
||||
public static ResourcePoolEntry create(ResourcePoolEntry original, Path file) {
|
||||
return new PathResourcePoolEntry(original.moduleName(),
|
||||
original.path(), original.type(), file);
|
||||
}
|
||||
|
||||
static String moduleFrom(String path) {
|
||||
private static String moduleFrom(String path) {
|
||||
Objects.requireNonNull(path);
|
||||
if (path.isEmpty() || path.charAt(0) != '/') {
|
||||
throw new IllegalArgumentException(path + " must start with /");
|
||||
}
|
||||
int idx = path.indexOf('/', 1);
|
||||
String noRoot = path.substring(1);
|
||||
int idx = noRoot.indexOf('/');
|
||||
if (idx == -1) {
|
||||
throw new IllegalArgumentException("/ missing after module: " + path);
|
||||
}
|
||||
return path.substring(1, idx);
|
||||
}
|
||||
|
||||
static String packageFrom(String path) {
|
||||
Objects.requireNonNull(path);
|
||||
int idx = path.lastIndexOf('/');
|
||||
if (idx == -1) {
|
||||
throw new IllegalArgumentException("/ missing from path: " + path);
|
||||
}
|
||||
if (path.startsWith("/")) {
|
||||
int jdx = path.indexOf('/', 1);
|
||||
if (jdx == -1) {
|
||||
throw new IllegalArgumentException("/ missing after module: " + path);
|
||||
}
|
||||
return path.substring(jdx + 1, idx);
|
||||
} else {
|
||||
return path.substring(0, idx);
|
||||
}
|
||||
return noRoot.substring(0, idx);
|
||||
}
|
||||
}
|
@ -38,34 +38,36 @@ 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.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolModule;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolModuleView;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
|
||||
|
||||
/**
|
||||
* Pool of module data.
|
||||
* A manager for pool of resources.
|
||||
*/
|
||||
public class ModulePoolImpl implements ModulePool {
|
||||
public class ResourcePoolManager {
|
||||
|
||||
private class ModuleImpl implements LinkModule {
|
||||
class ResourcePoolModuleImpl implements ResourcePoolModule {
|
||||
|
||||
final Map<String, ModuleEntry> moduleContent = new LinkedHashMap<>();
|
||||
final Map<String, ResourcePoolEntry> moduleContent = new LinkedHashMap<>();
|
||||
private ModuleDescriptor descriptor;
|
||||
final String name;
|
||||
|
||||
private ModuleImpl(String name) {
|
||||
private ResourcePoolModuleImpl(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ModuleEntry> findEntry(String path) {
|
||||
public Optional<ResourcePoolEntry> findEntry(String path) {
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
@ -76,41 +78,28 @@ public class ModulePoolImpl implements ModulePool {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleDescriptor getDescriptor() {
|
||||
public ModuleDescriptor descriptor() {
|
||||
if (descriptor == null) {
|
||||
String p = "/" + name + "/module-info.class";
|
||||
Optional<ModuleEntry> content = findEntry(p);
|
||||
Optional<ResourcePoolEntry> content = findEntry(p);
|
||||
if (!content.isPresent()) {
|
||||
throw new PluginException("No module-info for " + name
|
||||
+ " module");
|
||||
}
|
||||
ByteBuffer bb = ByteBuffer.wrap(content.get().getBytes());
|
||||
ByteBuffer bb = ByteBuffer.wrap(content.get().contentBytes());
|
||||
descriptor = ModuleDescriptor.read(bb);
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(ModuleEntry data) {
|
||||
if (isReadOnly()) {
|
||||
throw new PluginException("ModulePool 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() {
|
||||
public Set<String> packages() {
|
||||
Set<String> pkgs = new HashSet<>();
|
||||
moduleContent.values().stream().filter(m -> m.getType().
|
||||
equals(ModuleEntry.Type.CLASS_OR_RESOURCE)).forEach(res -> {
|
||||
moduleContent.values().stream().filter(m -> m.type().
|
||||
equals(ResourcePoolEntry.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());
|
||||
if (ImageFileCreator.isClassPackage(res.path())) {
|
||||
String[] split = ImageFileCreator.splitPath(res.path());
|
||||
String pkg = split[1];
|
||||
if (pkg != null && !pkg.isEmpty()) {
|
||||
pkgs.add(pkg);
|
||||
@ -122,35 +111,121 @@ public class ModulePoolImpl implements ModulePool {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
return name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<? extends ModuleEntry> entries() {
|
||||
public Stream<ResourcePoolEntry> entries() {
|
||||
return moduleContent.values().stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEntryCount() {
|
||||
public int entryCount() {
|
||||
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);
|
||||
public class ResourcePoolImpl implements ResourcePool {
|
||||
@Override
|
||||
public ResourcePoolModuleView moduleView() {
|
||||
return ResourcePoolManager.this.moduleView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<ResourcePoolEntry> entries() {
|
||||
return ResourcePoolManager.this.entries();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int entryCount() {
|
||||
return ResourcePoolManager.this.entryCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ResourcePoolEntry> findEntry(String path) {
|
||||
return ResourcePoolManager.this.findEntry(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context) {
|
||||
return ResourcePoolManager.this.findEntryInContext(path, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(ResourcePoolEntry data) {
|
||||
return ResourcePoolManager.this.contains(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return ResourcePoolManager.this.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteOrder byteOrder() {
|
||||
return ResourcePoolManager.this.byteOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> releaseProperties() {
|
||||
return ResourcePoolManager.this.releaseProperties();
|
||||
}
|
||||
|
||||
public StringTable getStringTable() {
|
||||
return ResourcePoolManager.this.getStringTable();
|
||||
}
|
||||
}
|
||||
|
||||
class ResourcePoolBuilderImpl implements ResourcePoolBuilder {
|
||||
private boolean built;
|
||||
|
||||
@Override
|
||||
public void add(ResourcePoolEntry data) {
|
||||
if (built) {
|
||||
throw new IllegalStateException("resource pool already built!");
|
||||
}
|
||||
ResourcePoolManager.this.add(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourcePool build() {
|
||||
built = true;
|
||||
return ResourcePoolManager.this.resourcePool();
|
||||
}
|
||||
}
|
||||
|
||||
class ResourcePoolModuleViewImpl implements ResourcePoolModuleView {
|
||||
@Override
|
||||
public Optional<ResourcePoolModule> findModule(String name) {
|
||||
return ResourcePoolManager.this.findModule(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<ResourcePoolModule> modules() {
|
||||
return ResourcePoolManager.this.modules();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int moduleCount() {
|
||||
return ResourcePoolManager.this.moduleCount();
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<String, ResourcePoolEntry> resources = new LinkedHashMap<>();
|
||||
private final Map<String, ResourcePoolModule> modules = new LinkedHashMap<>();
|
||||
private final ResourcePoolModuleImpl fileCopierModule = new ResourcePoolModuleImpl(FileCopierPlugin.FAKE_MODULE);
|
||||
private Map<String, String> releaseProps = new HashMap<>();
|
||||
|
||||
private final ByteOrder order;
|
||||
|
||||
private boolean isReadOnly;
|
||||
private final StringTable table;
|
||||
private final ResourcePool poolImpl;
|
||||
private final ResourcePoolBuilder poolBuilderImpl;
|
||||
private final ResourcePoolModuleView moduleViewImpl;
|
||||
|
||||
public ModulePoolImpl() {
|
||||
public ResourcePoolManager() {
|
||||
this(ByteOrder.nativeOrder());
|
||||
}
|
||||
|
||||
public ModulePoolImpl(ByteOrder order) {
|
||||
public ResourcePoolManager(ByteOrder order) {
|
||||
this(order, new StringTable() {
|
||||
|
||||
@Override
|
||||
@ -165,39 +240,50 @@ public class ModulePoolImpl implements ModulePool {
|
||||
});
|
||||
}
|
||||
|
||||
public ModulePoolImpl(ByteOrder order, StringTable table) {
|
||||
public ResourcePoolManager(ByteOrder order, StringTable table) {
|
||||
this.order = Objects.requireNonNull(order);
|
||||
this.table = Objects.requireNonNull(table);
|
||||
this.poolImpl = new ResourcePoolImpl();
|
||||
this.poolBuilderImpl = new ResourcePoolBuilderImpl();
|
||||
this.moduleViewImpl = new ResourcePoolModuleViewImpl();
|
||||
}
|
||||
|
||||
public ResourcePool resourcePool() {
|
||||
return poolImpl;
|
||||
}
|
||||
|
||||
public ResourcePoolBuilder resourcePoolBuilder() {
|
||||
return poolBuilderImpl;
|
||||
}
|
||||
|
||||
public ResourcePoolModuleView moduleView() {
|
||||
return moduleViewImpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a ModuleEntry.
|
||||
* Add a ResourcePoolEntry.
|
||||
*
|
||||
* @param data The ModuleEntry to add.
|
||||
* @param data The ResourcePoolEntry to add.
|
||||
*/
|
||||
@Override
|
||||
public void add(ModuleEntry data) {
|
||||
if (isReadOnly()) {
|
||||
throw new PluginException("ModulePool is readonly");
|
||||
}
|
||||
public void add(ResourcePoolEntry data) {
|
||||
Objects.requireNonNull(data);
|
||||
if (resources.get(data.getPath()) != null) {
|
||||
throw new PluginException("Resource " + data.getPath()
|
||||
if (resources.get(data.path()) != null) {
|
||||
throw new PluginException("Resource " + data.path()
|
||||
+ " already present");
|
||||
}
|
||||
String modulename = data.getModule();
|
||||
ModuleImpl m = modules.get(modulename);
|
||||
String modulename = data.moduleName();
|
||||
ResourcePoolModuleImpl m = (ResourcePoolModuleImpl)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);
|
||||
m = new ResourcePoolModuleImpl(modulename);
|
||||
modules.put(modulename, m);
|
||||
}
|
||||
resources.put(data.getPath(), data);
|
||||
m.moduleContent.put(data.getPath(), data);
|
||||
resources.put(data.path(), data);
|
||||
m.moduleContent.put(data.path(), data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -206,175 +292,123 @@ public class ModulePoolImpl implements ModulePool {
|
||||
* @param name The module name
|
||||
* @return the module of matching name, if found
|
||||
*/
|
||||
@Override
|
||||
public Optional<LinkModule> findModule(String name) {
|
||||
public Optional<ResourcePoolModule> findModule(String name) {
|
||||
Objects.requireNonNull(name);
|
||||
return Optional.ofNullable(modules.get(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* The stream of modules contained in this ModulePool.
|
||||
* The stream of modules contained in this ResourcePool.
|
||||
*
|
||||
* @return The stream of modules.
|
||||
*/
|
||||
@Override
|
||||
public Stream<? extends LinkModule> modules() {
|
||||
public Stream<ResourcePoolModule> modules() {
|
||||
return modules.values().stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of LinkModule count in this ModulePool.
|
||||
* Return the number of ResourcePoolModule count in this ResourcePool.
|
||||
*
|
||||
* @return the module count.
|
||||
*/
|
||||
@Override
|
||||
public int getModuleCount() {
|
||||
public int moduleCount() {
|
||||
return modules.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all ModuleEntry contained in this ModulePool instance.
|
||||
* Get all ResourcePoolEntry contained in this ResourcePool instance.
|
||||
*
|
||||
* @return The stream of LinkModuleEntries.
|
||||
* @return The stream of ResourcePoolModuleEntries.
|
||||
*/
|
||||
@Override
|
||||
public Stream<? extends ModuleEntry> entries() {
|
||||
public Stream<ResourcePoolEntry> entries() {
|
||||
return resources.values().stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of ModuleEntry count in this ModulePool.
|
||||
* Return the number of ResourcePoolEntry count in this ResourcePool.
|
||||
*
|
||||
* @return the entry count.
|
||||
*/
|
||||
@Override
|
||||
public int getEntryCount() {
|
||||
public int entryCount() {
|
||||
return resources.values().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ModuleEntry for the passed path.
|
||||
* Get the ResourcePoolEntry for the passed path.
|
||||
*
|
||||
* @param path A data path
|
||||
* @return A ModuleEntry instance or null if the data is not found
|
||||
* @return A ResourcePoolEntry instance or null if the data is not found
|
||||
*/
|
||||
@Override
|
||||
public Optional<ModuleEntry> findEntry(String path) {
|
||||
public Optional<ResourcePoolEntry> findEntry(String path) {
|
||||
Objects.requireNonNull(path);
|
||||
return Optional.ofNullable(resources.get(path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ModuleEntry for the passed path restricted to supplied context.
|
||||
* Get the ResourcePoolEntry for the passed path restricted to supplied context.
|
||||
*
|
||||
* @param path A data path
|
||||
* @param context A context of the search
|
||||
* @return A ModuleEntry instance or null if the data is not found
|
||||
* @return A ResourcePoolEntry instance or null if the data is not found
|
||||
*/
|
||||
@Override
|
||||
public Optional<ModuleEntry> findEntryInContext(String path, ModuleEntry context) {
|
||||
public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context) {
|
||||
Objects.requireNonNull(path);
|
||||
Objects.requireNonNull(context);
|
||||
LinkModule module = modules.get(context.getModule());
|
||||
ResourcePoolModule module = modules.get(context.moduleName());
|
||||
Objects.requireNonNull(module);
|
||||
Optional<ModuleEntry> entry = module.findEntry(path);
|
||||
Optional<ResourcePoolEntry> entry = module.findEntry(path);
|
||||
// Navigating other modules via requires and exports is problematic
|
||||
// since we cannot construct the runtime model of loaders and layers.
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the ModulePool contains the given ModuleEntry.
|
||||
* Check if the ResourcePool contains the given ResourcePoolEntry.
|
||||
*
|
||||
* @param data The module data to check existence for.
|
||||
* @return The module data or null if not found.
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(ModuleEntry data) {
|
||||
public boolean contains(ResourcePoolEntry data) {
|
||||
Objects.requireNonNull(data);
|
||||
return findEntry(data.getPath()).isPresent();
|
||||
return findEntry(data.path()).isPresent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the ModulePool contains some content at all.
|
||||
* Check if the ResourcePool contains some content at all.
|
||||
*
|
||||
* @return True, no content, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return resources.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.
|
||||
*/
|
||||
@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() {
|
||||
public ByteOrder byteOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getReleaseProperties() {
|
||||
return isReadOnly()? Collections.unmodifiableMap(releaseProps) : releaseProps;
|
||||
public Map<String, String> releaseProperties() {
|
||||
return 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 ByteArrayModuleEntry {
|
||||
public static final class CompressedModuleData extends ByteArrayResourcePoolEntry {
|
||||
|
||||
final long uncompressed_size;
|
||||
|
||||
private CompressedModuleData(String module, String path,
|
||||
byte[] content, long uncompressed_size) {
|
||||
super(module, path, ModuleEntry.Type.CLASS_OR_RESOURCE, content);
|
||||
super(module, path, ResourcePoolEntry.Type.CLASS_OR_RESOURCE, content);
|
||||
this.uncompressed_size = uncompressed_size;
|
||||
}
|
||||
|
||||
@ -388,7 +422,7 @@ public class ModulePoolImpl implements ModulePool {
|
||||
return false;
|
||||
}
|
||||
CompressedModuleData f = (CompressedModuleData) other;
|
||||
return f.getPath().equals(getPath());
|
||||
return f.path().equals(path());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -397,7 +431,7 @@ public class ModulePoolImpl implements ModulePool {
|
||||
}
|
||||
}
|
||||
|
||||
public static CompressedModuleData newCompressedResource(ModuleEntry original,
|
||||
public static CompressedModuleData newCompressedResource(ResourcePoolEntry original,
|
||||
ByteBuffer compressed,
|
||||
String plugin, String pluginConfig, StringTable strings,
|
||||
ByteOrder order) {
|
||||
@ -406,7 +440,7 @@ public class ModulePoolImpl implements ModulePool {
|
||||
Objects.requireNonNull(plugin);
|
||||
|
||||
boolean isTerminal = !(original instanceof CompressedModuleData);
|
||||
long uncompressed_size = original.getLength();
|
||||
long uncompressed_size = original.contentLength();
|
||||
if (original instanceof CompressedModuleData) {
|
||||
CompressedModuleData comp = (CompressedModuleData) original;
|
||||
uncompressed_size = comp.getUncompressedSize();
|
||||
@ -417,7 +451,7 @@ public class ModulePoolImpl implements ModulePool {
|
||||
configOffset = strings.addString(plugin);
|
||||
}
|
||||
CompressedResourceHeader rh
|
||||
= new CompressedResourceHeader(compressed.limit(), original.getLength(),
|
||||
= new CompressedResourceHeader(compressed.limit(), original.contentLength(),
|
||||
nameOffset, configOffset, isTerminal);
|
||||
// Merge header with content;
|
||||
byte[] h = rh.getBytes(order);
|
||||
@ -428,9 +462,8 @@ public class ModulePoolImpl implements ModulePool {
|
||||
byte[] contentWithHeader = bb.array();
|
||||
|
||||
CompressedModuleData compressedResource
|
||||
= new CompressedModuleData(original.getModule(), original.getPath(),
|
||||
= new CompressedModuleData(original.moduleName(), original.path(),
|
||||
contentWithHeader, uncompressed_size);
|
||||
return compressedResource;
|
||||
}
|
||||
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
package jdk.tools.jlink.internal;
|
||||
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
|
||||
/**
|
||||
* Plugin wishing to pre-visit the resources must implement this interface.
|
||||
@ -43,5 +43,5 @@ public interface ResourcePrevisitor {
|
||||
* @param strings StringTable instance. Add string to the StringTable to track string
|
||||
* usage.
|
||||
*/
|
||||
public void previsit(ModulePool resources, StringTable strings);
|
||||
public void previsit(ResourcePool resources, StringTable strings);
|
||||
}
|
||||
|
@ -29,7 +29,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.Plugin.Category;
|
||||
import jdk.internal.org.objectweb.asm.ClassReader;
|
||||
import static jdk.internal.org.objectweb.asm.ClassReader.*;
|
||||
@ -44,7 +45,7 @@ import jdk.internal.org.objectweb.asm.tree.LdcInsnNode;
|
||||
import jdk.internal.org.objectweb.asm.tree.LineNumberNode;
|
||||
import jdk.internal.org.objectweb.asm.tree.MethodInsnNode;
|
||||
import jdk.internal.org.objectweb.asm.tree.MethodNode;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
|
||||
public final class ClassForNamePlugin implements Plugin {
|
||||
@ -55,8 +56,8 @@ public final class ClassForNamePlugin implements Plugin {
|
||||
path.length() - ".class".length());
|
||||
}
|
||||
|
||||
private static int getAccess(ModuleEntry resource) {
|
||||
ClassReader cr = new ClassReader(resource.getBytes());
|
||||
private static int getAccess(ResourcePoolEntry resource) {
|
||||
ClassReader cr = new ClassReader(resource.contentBytes());
|
||||
|
||||
return cr.getAccess();
|
||||
}
|
||||
@ -67,8 +68,8 @@ public final class ClassForNamePlugin implements Plugin {
|
||||
return index == -1 ? "" : binaryName.substring(0, index);
|
||||
}
|
||||
|
||||
private ModuleEntry transform(ModuleEntry resource, ModulePool pool) {
|
||||
byte[] inBytes = resource.getBytes();
|
||||
private ResourcePoolEntry transform(ResourcePoolEntry resource, ResourcePool pool) {
|
||||
byte[] inBytes = resource.contentBytes();
|
||||
ClassReader cr = new ClassReader(inBytes);
|
||||
ClassNode cn = new ClassNode();
|
||||
cr.accept(cn, EXPAND_FRAMES);
|
||||
@ -76,7 +77,7 @@ public final class ClassForNamePlugin implements Plugin {
|
||||
boolean modified = false;
|
||||
LdcInsnNode ldc = null;
|
||||
|
||||
String thisPackage = getPackage(binaryClassName(resource.getPath()));
|
||||
String thisPackage = getPackage(binaryClassName(resource.path()));
|
||||
|
||||
for (MethodNode mn : ms) {
|
||||
InsnList il = mn.instructions;
|
||||
@ -96,7 +97,7 @@ public final class ClassForNamePlugin implements Plugin {
|
||||
min.desc.equals("(Ljava/lang/String;)Ljava/lang/Class;")) {
|
||||
String ldcClassName = ldc.cst.toString();
|
||||
String thatClassName = ldcClassName.replaceAll("\\.", "/");
|
||||
Optional<ModuleEntry> thatClass =
|
||||
Optional<ResourcePoolEntry> thatClass =
|
||||
pool.findEntryInContext(thatClassName + ".class", resource);
|
||||
|
||||
if (thatClass.isPresent()) {
|
||||
@ -128,7 +129,7 @@ public final class ClassForNamePlugin implements Plugin {
|
||||
cn.accept(cw);
|
||||
byte[] outBytes = cw.toByteArray();
|
||||
|
||||
return resource.create(outBytes);
|
||||
return resource.copyWithContent(outBytes);
|
||||
}
|
||||
|
||||
return resource;
|
||||
@ -140,13 +141,13 @@ public final class ClassForNamePlugin implements Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
Objects.requireNonNull(in);
|
||||
Objects.requireNonNull(out);
|
||||
|
||||
in.entries()
|
||||
.forEach(resource -> {
|
||||
String path = resource.getPath();
|
||||
String path = resource.path();
|
||||
|
||||
if (path.endsWith(".class") && !path.endsWith("/module-info.class")) {
|
||||
out.add(transform(resource, in));
|
||||
@ -154,6 +155,7 @@ public final class ClassForNamePlugin implements Plugin {
|
||||
out.add(resource);
|
||||
}
|
||||
});
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -26,10 +26,12 @@ package jdk.tools.jlink.internal.plugins;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import jdk.tools.jlink.internal.ModulePoolImpl;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.internal.ImagePluginStack;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
import jdk.tools.jlink.internal.ResourcePrevisitor;
|
||||
import jdk.tools.jlink.internal.StringTable;
|
||||
|
||||
@ -53,21 +55,22 @@ public final class DefaultCompressPlugin implements Plugin, ResourcePrevisitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
if (ss != null && zip != null) {
|
||||
ModulePool output = new ImagePluginStack.OrderedResourcePool(in.getByteOrder(),
|
||||
((ModulePoolImpl) in).getStringTable());
|
||||
ss.visit(in, output);
|
||||
zip.visit(output, out);
|
||||
ResourcePoolManager resMgr = new ImagePluginStack.OrderedResourcePoolManager(
|
||||
in.byteOrder(), ((ResourcePoolImpl)in).getStringTable());
|
||||
return zip.transform(ss.transform(in, resMgr.resourcePoolBuilder()), out);
|
||||
} else if (ss != null) {
|
||||
ss.visit(in, out);
|
||||
return ss.transform(in, out);
|
||||
} else if (zip != null) {
|
||||
zip.visit(in, out);
|
||||
return zip.transform(in, out);
|
||||
}
|
||||
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void previsit(ModulePool resources, StringTable strings) {
|
||||
public void previsit(ResourcePool resources, StringTable strings) {
|
||||
if (ss != null) {
|
||||
ss.previsit(resources, strings);
|
||||
}
|
||||
|
@ -27,8 +27,9 @@ package jdk.tools.jlink.internal.plugins;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -45,13 +46,14 @@ public final class ExcludeFilesPlugin implements Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
in.transformAndCopy((file) -> {
|
||||
if (!file.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
file = predicate.test(file.getPath()) ? file : null;
|
||||
if (!file.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
file = predicate.test(file.path()) ? file : null;
|
||||
}
|
||||
return file;
|
||||
}, out);
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -27,8 +27,9 @@ package jdk.tools.jlink.internal.plugins;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -45,13 +46,14 @@ public final class ExcludePlugin implements Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
in.transformAndCopy((resource) -> {
|
||||
if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
resource = predicate.test(resource.getPath()) ? resource : null;
|
||||
if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
resource = predicate.test(resource.path()) ? resource : null;
|
||||
}
|
||||
return resource;
|
||||
}, out);
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -36,8 +36,9 @@ import java.util.TreeSet;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
|
||||
/**
|
||||
@ -97,25 +98,25 @@ public final class ExcludeVMPlugin implements Plugin {
|
||||
* e.g.: /java.base/native/amd64/server/libjvm.so
|
||||
* /java.base/native/server/libjvm.dylib
|
||||
*/
|
||||
private List<ModuleEntry> getVMs(ModulePool in) {
|
||||
private List<ResourcePoolEntry> getVMs(ResourcePool in) {
|
||||
String jvmlib = jvmlib();
|
||||
List<ModuleEntry> ret = in.findModule("java.base").get().entries().filter((t) -> {
|
||||
return t.getPath().endsWith("/" + jvmlib);
|
||||
List<ResourcePoolEntry> ret = in.moduleView().findModule("java.base").get().entries().filter((t) -> {
|
||||
return t.path().endsWith("/" + jvmlib);
|
||||
}).collect(Collectors.toList());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder 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<ModuleEntry> jvms = getVMs(in);
|
||||
List<ResourcePoolEntry> jvms = getVMs(in);
|
||||
for (Jvm jvm : Jvm.values()) {
|
||||
for (ModuleEntry md : jvms) {
|
||||
if (md.getPath().endsWith("/" + jvm.getName() + "/" + jvmlib)) {
|
||||
for (ResourcePoolEntry md : jvms) {
|
||||
if (md.path().endsWith("/" + jvm.getName() + "/" + jvmlib)) {
|
||||
existing.add(jvm);
|
||||
if (isRemoved(md)) {
|
||||
removed.add(jvm);
|
||||
@ -134,8 +135,8 @@ public final class ExcludeVMPlugin implements Plugin {
|
||||
// Rewrite the jvm.cfg file.
|
||||
in.transformAndCopy((file) -> {
|
||||
if (!keepAll) {
|
||||
if (file.getType().equals(ModuleEntry.Type.NATIVE_LIB)) {
|
||||
if (file.getPath().endsWith(JVM_CFG)) {
|
||||
if (file.type().equals(ResourcePoolEntry.Type.NATIVE_LIB)) {
|
||||
if (file.path().endsWith(JVM_CFG)) {
|
||||
try {
|
||||
file = handleJvmCfgFile(file, existing, removed);
|
||||
} catch (IOException ex) {
|
||||
@ -148,10 +149,11 @@ public final class ExcludeVMPlugin implements Plugin {
|
||||
return file;
|
||||
}, out);
|
||||
|
||||
return out.build();
|
||||
}
|
||||
|
||||
private boolean isRemoved(ModuleEntry file) {
|
||||
return !predicate.test(file.getPath());
|
||||
private boolean isRemoved(ResourcePoolEntry file) {
|
||||
return !predicate.test(file.path());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -206,7 +208,7 @@ public final class ExcludeVMPlugin implements Plugin {
|
||||
predicate = ResourceFilter.excludeFilter(exclude);
|
||||
}
|
||||
|
||||
private ModuleEntry handleJvmCfgFile(ModuleEntry orig,
|
||||
private ResourcePoolEntry handleJvmCfgFile(ResourcePoolEntry orig,
|
||||
TreeSet<Jvm> existing,
|
||||
TreeSet<Jvm> removed) throws IOException {
|
||||
if (keepAll) {
|
||||
@ -215,7 +217,7 @@ public final class ExcludeVMPlugin implements Plugin {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
// Keep comments
|
||||
try (BufferedReader reader
|
||||
= new BufferedReader(new InputStreamReader(orig.stream(),
|
||||
= new BufferedReader(new InputStreamReader(orig.content(),
|
||||
StandardCharsets.UTF_8))) {
|
||||
reader.lines().forEach((s) -> {
|
||||
if (s.startsWith("#")) {
|
||||
@ -242,7 +244,7 @@ public final class ExcludeVMPlugin implements Plugin {
|
||||
|
||||
byte[] content = builder.toString().getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
return orig.create(content);
|
||||
return orig.copyWithContent(content);
|
||||
}
|
||||
|
||||
private static String jvmlib() {
|
||||
|
@ -37,10 +37,11 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import jdk.tools.jlink.internal.PathModuleEntry;
|
||||
import jdk.tools.jlink.internal.PathResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.internal.Utils;
|
||||
|
||||
@ -64,12 +65,12 @@ public class FileCopierPlugin implements Plugin {
|
||||
/**
|
||||
* Symbolic link to another path.
|
||||
*/
|
||||
public static abstract class SymImageFile extends PathModuleEntry {
|
||||
public static abstract class SymImageFile extends PathResourcePoolEntry {
|
||||
|
||||
private final String targetPath;
|
||||
|
||||
public SymImageFile(String targetPath, String module, String path,
|
||||
ModuleEntry.Type type, Path file) {
|
||||
ResourcePoolEntry.Type type, Path file) {
|
||||
super(module, path, type, file);
|
||||
this.targetPath = targetPath;
|
||||
}
|
||||
@ -82,7 +83,7 @@ public class FileCopierPlugin implements Plugin {
|
||||
private static final class SymImageFileImpl extends SymImageFile {
|
||||
|
||||
public SymImageFileImpl(String targetPath, Path file, String module,
|
||||
String path, ModuleEntry.Type type) {
|
||||
String path, ResourcePoolEntry.Type type) {
|
||||
super(targetPath, module, path, type, file);
|
||||
}
|
||||
}
|
||||
@ -90,11 +91,11 @@ public class FileCopierPlugin implements Plugin {
|
||||
private static final class DirectoryCopy implements FileVisitor<Path> {
|
||||
|
||||
private final Path source;
|
||||
private final ModulePool pool;
|
||||
private final ResourcePoolBuilder pool;
|
||||
private final String targetDir;
|
||||
private final List<SymImageFile> symlinks = new ArrayList<>();
|
||||
|
||||
DirectoryCopy(Path source, ModulePool pool, String targetDir) {
|
||||
DirectoryCopy(Path source, ResourcePoolBuilder pool, String targetDir) {
|
||||
this.source = source;
|
||||
this.pool = pool;
|
||||
this.targetDir = targetDir;
|
||||
@ -128,7 +129,7 @@ public class FileCopierPlugin implements Plugin {
|
||||
}
|
||||
SymImageFileImpl impl = new SymImageFileImpl(symTarget.toString(),
|
||||
file, path, Objects.requireNonNull(file.getFileName()).toString(),
|
||||
ModuleEntry.Type.OTHER);
|
||||
ResourcePoolEntry.Type.OTHER);
|
||||
symlinks.add(impl);
|
||||
} else {
|
||||
addFile(pool, file, path);
|
||||
@ -152,14 +153,14 @@ public class FileCopierPlugin implements Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addFile(ModulePool pool, Path file, String path)
|
||||
private static void addFile(ResourcePoolBuilder pool, Path file, String path)
|
||||
throws IOException {
|
||||
Objects.requireNonNull(pool);
|
||||
Objects.requireNonNull(file);
|
||||
Objects.requireNonNull(path);
|
||||
ModuleEntry impl = ModuleEntry.create(
|
||||
ResourcePoolEntry impl = ResourcePoolEntry.create(
|
||||
"/" + FAKE_MODULE + "/other/" + path,
|
||||
ModuleEntry.Type.OTHER, file);
|
||||
ResourcePoolEntry.Type.OTHER, file);
|
||||
try {
|
||||
pool.add(impl);
|
||||
} catch (Exception ex) {
|
||||
@ -211,7 +212,7 @@ public class FileCopierPlugin implements Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
in.transformAndCopy((file) -> {
|
||||
return file;
|
||||
}, out);
|
||||
@ -238,6 +239,8 @@ public class FileCopierPlugin implements Plugin {
|
||||
} catch (IOException ex) {
|
||||
throw new UncheckedIOException(ex);
|
||||
}
|
||||
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,9 +31,10 @@ 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.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
|
||||
/**
|
||||
@ -145,22 +146,22 @@ public final class GenerateJLIClassesPlugin implements Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
in.entries().forEach(data -> {
|
||||
if (("/java.base/" + BMH + ".class").equals(data.getPath())) {
|
||||
if (("/java.base/" + BMH + ".class").equals(data.path())) {
|
||||
// Add BoundMethodHandle unchanged
|
||||
out.add(data);
|
||||
speciesTypes.forEach(types -> generateConcreteClass(types, data, out));
|
||||
} else {
|
||||
if (!out.contains(data)) {
|
||||
out.add(data);
|
||||
}
|
||||
out.add(data);
|
||||
}
|
||||
});
|
||||
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void generateConcreteClass(String types, ModuleEntry data, ModulePool out) {
|
||||
private void generateConcreteClass(String types, ResourcePoolEntry data, ResourcePoolBuilder out) {
|
||||
try {
|
||||
// Generate class
|
||||
Map.Entry<String, byte[]> result = (Map.Entry<String, byte[]>)
|
||||
@ -169,12 +170,10 @@ public final class GenerateJLIClassesPlugin implements Plugin {
|
||||
byte[] bytes = result.getValue();
|
||||
|
||||
// Add class to pool
|
||||
ModuleEntry ndata = ModuleEntry.create(
|
||||
ResourcePoolEntry ndata = ResourcePoolEntry.create(
|
||||
"/java.base/" + className + ".class",
|
||||
bytes);
|
||||
if (!out.contains(ndata)) {
|
||||
out.add(ndata);
|
||||
}
|
||||
out.add(ndata);
|
||||
} catch (Exception ex) {
|
||||
throw new PluginException(ex);
|
||||
}
|
||||
|
@ -42,10 +42,11 @@ import java.util.stream.Stream;
|
||||
import jdk.internal.org.objectweb.asm.ClassReader;
|
||||
import jdk.tools.jlink.internal.ResourcePrevisitor;
|
||||
import jdk.tools.jlink.internal.StringTable;
|
||||
import jdk.tools.jlink.plugin.LinkModule;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolModule;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import sun.util.cldr.CLDRBaseLocaleDataMetaInfo;
|
||||
import sun.util.locale.provider.LocaleProviderAdapter;
|
||||
@ -151,24 +152,26 @@ public final class IncludeLocalesPlugin implements Plugin, ResourcePrevisitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
in.transformAndCopy((resource) -> {
|
||||
if (resource.getModule().equals(MODULENAME)) {
|
||||
String path = resource.getPath();
|
||||
if (resource.moduleName().equals(MODULENAME)) {
|
||||
String path = resource.path();
|
||||
resource = predicate.test(path) ? resource: null;
|
||||
if (resource != null &&
|
||||
resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
byte[] bytes = resource.getBytes();
|
||||
resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
byte[] bytes = resource.contentBytes();
|
||||
ClassReader cr = new ClassReader(bytes);
|
||||
if (Arrays.stream(cr.getInterfaces())
|
||||
.anyMatch(i -> i.contains(METAINFONAME)) &&
|
||||
stripUnsupportedLocales(bytes, cr)) {
|
||||
resource = resource.create(bytes);
|
||||
resource = resource.copyWithContent(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
return resource;
|
||||
}, out);
|
||||
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -205,14 +208,14 @@ public final class IncludeLocalesPlugin implements Plugin, ResourcePrevisitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void previsit(ModulePool resources, StringTable strings) {
|
||||
public void previsit(ResourcePool resources, StringTable strings) {
|
||||
final Pattern p = Pattern.compile(".*((Data_)|(Names_))(?<tag>.*)\\.class");
|
||||
Optional<LinkModule> optMod = resources.findModule(MODULENAME);
|
||||
Optional<ResourcePoolModule> optMod = resources.moduleView().findModule(MODULENAME);
|
||||
|
||||
// jdk.localedata module validation
|
||||
if (optMod.isPresent()) {
|
||||
LinkModule module = optMod.get();
|
||||
Set<String> packages = module.getAllPackages();
|
||||
ResourcePoolModule module = optMod.get();
|
||||
Set<String> packages = module.packages();
|
||||
if (!packages.containsAll(LOCALEDATA_PACKAGES)) {
|
||||
throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".missingpackages") +
|
||||
LOCALEDATA_PACKAGES.stream()
|
||||
@ -221,7 +224,7 @@ public final class IncludeLocalesPlugin implements Plugin, ResourcePrevisitor {
|
||||
}
|
||||
|
||||
available = Stream.concat(module.entries()
|
||||
.map(md -> p.matcher(md.getPath()))
|
||||
.map(md -> p.matcher(md.path()))
|
||||
.filter(m -> m.matches())
|
||||
.map(m -> m.group("tag").replaceAll("_", "-")),
|
||||
Stream.concat(Stream.of(jaJPJPTag), Stream.of(thTHTHTag)))
|
||||
|
@ -35,8 +35,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.ToIntFunction;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.internal.Utils;
|
||||
|
||||
@ -62,20 +63,20 @@ public final class OrderResourcesPlugin implements Plugin {
|
||||
}
|
||||
|
||||
static class SortWrapper {
|
||||
private final ModuleEntry resource;
|
||||
private final ResourcePoolEntry resource;
|
||||
private final int ordinal;
|
||||
|
||||
SortWrapper(ModuleEntry resource, int ordinal) {
|
||||
SortWrapper(ResourcePoolEntry resource, int ordinal) {
|
||||
this.resource = resource;
|
||||
this.ordinal = ordinal;
|
||||
}
|
||||
|
||||
ModuleEntry getResource() {
|
||||
ResourcePoolEntry getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
String getPath() {
|
||||
return resource.getPath();
|
||||
return resource.path();
|
||||
}
|
||||
|
||||
int getOrdinal() {
|
||||
@ -95,8 +96,8 @@ public final class OrderResourcesPlugin implements Plugin {
|
||||
return path;
|
||||
}
|
||||
|
||||
private int getOrdinal(ModuleEntry resource) {
|
||||
String path = resource.getPath();
|
||||
private int getOrdinal(ResourcePoolEntry resource) {
|
||||
String path = resource.path();
|
||||
|
||||
Integer value = orderedPaths.get(stripModule(path));
|
||||
|
||||
@ -126,17 +127,19 @@ public final class OrderResourcesPlugin implements Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
in.entries()
|
||||
.filter(resource -> resource.getType()
|
||||
.equals(ModuleEntry.Type.CLASS_OR_RESOURCE))
|
||||
.filter(resource -> resource.type()
|
||||
.equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE))
|
||||
.map((resource) -> new SortWrapper(resource, getOrdinal(resource)))
|
||||
.sorted(OrderResourcesPlugin::compare)
|
||||
.forEach((wrapper) -> out.add(wrapper.getResource()));
|
||||
in.entries()
|
||||
.filter(other -> !other.getType()
|
||||
.equals(ModuleEntry.Type.CLASS_OR_RESOURCE))
|
||||
.filter(other -> !other.type()
|
||||
.equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE))
|
||||
.forEach((other) -> out.add(other));
|
||||
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -33,7 +33,8 @@ import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import jdk.tools.jlink.internal.Utils;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.Plugin.Category;
|
||||
import jdk.tools.jlink.plugin.Plugin.State;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
@ -117,9 +118,8 @@ public final class ReleaseInfoPlugin implements Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
in.transformAndCopy(Function.identity(), out);
|
||||
out.getReleaseProperties().putAll(in.getReleaseProperties());
|
||||
out.getReleaseProperties().putAll(release);
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
in.releaseProperties().putAll(release);
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
@ -55,11 +55,13 @@ 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.ModulePoolImpl;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
import jdk.tools.jlink.internal.ResourcePrevisitor;
|
||||
import jdk.tools.jlink.internal.StringTable;
|
||||
|
||||
@ -226,22 +228,22 @@ public class StringSharingPlugin implements Plugin, ResourcePrevisitor {
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] transform(ModuleEntry resource, ModulePool out,
|
||||
public byte[] transform(ResourcePoolEntry resource, ResourcePoolBuilder out,
|
||||
StringTable strings) throws IOException, Exception {
|
||||
byte[] content = resource.getBytes();
|
||||
byte[] content = resource.contentBytes();
|
||||
ClassFile cf;
|
||||
try (InputStream stream = new ByteArrayInputStream(content)) {
|
||||
cf = ClassFile.read(stream);
|
||||
} catch (ConstantPoolException ex) {
|
||||
throw new IOException("Compressor EX " + ex + " for "
|
||||
+ resource.getPath() + " content.length " + content.length, ex);
|
||||
+ resource.path() + " content.length " + content.length, ex);
|
||||
}
|
||||
DescriptorsScanner scanner = new DescriptorsScanner(cf);
|
||||
return optimize(resource, out, strings, scanner.scan(), content);
|
||||
}
|
||||
|
||||
@SuppressWarnings("fallthrough")
|
||||
private byte[] optimize(ModuleEntry resource, ModulePool resources,
|
||||
private byte[] optimize(ResourcePoolEntry resource, ResourcePoolBuilder resources,
|
||||
StringTable strings,
|
||||
Set<Integer> descriptorIndexes, byte[] content) throws Exception {
|
||||
DataInputStream stream = new DataInputStream(new ByteArrayInputStream(content));
|
||||
@ -347,23 +349,25 @@ public class StringSharingPlugin implements Plugin, ResourcePrevisitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool result) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder result) {
|
||||
CompactCPHelper visit = new CompactCPHelper();
|
||||
in.transformAndCopy((resource) -> {
|
||||
ModuleEntry res = resource;
|
||||
if (predicate.test(resource.getPath()) && resource.getPath().endsWith(".class")) {
|
||||
ResourcePoolEntry res = resource;
|
||||
if (predicate.test(resource.path()) && resource.path().endsWith(".class")) {
|
||||
byte[] compressed = null;
|
||||
try {
|
||||
compressed = visit.transform(resource, result, ((ModulePoolImpl) in).getStringTable());
|
||||
compressed = visit.transform(resource, result, ((ResourcePoolImpl)in).getStringTable());
|
||||
} catch (Exception ex) {
|
||||
throw new PluginException(ex);
|
||||
}
|
||||
res = ModulePoolImpl.newCompressedResource(resource,
|
||||
res = ResourcePoolManager.newCompressedResource(resource,
|
||||
ByteBuffer.wrap(compressed), getName(), null,
|
||||
((ModulePoolImpl) in).getStringTable(), in.getByteOrder());
|
||||
((ResourcePoolImpl)in).getStringTable(), in.byteOrder());
|
||||
}
|
||||
return res;
|
||||
}, result);
|
||||
|
||||
return result.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -392,11 +396,11 @@ public class StringSharingPlugin implements Plugin, ResourcePrevisitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void previsit(ModulePool resources, StringTable strings) {
|
||||
public void previsit(ResourcePool resources, StringTable strings) {
|
||||
CompactCPHelper preVisit = new CompactCPHelper();
|
||||
resources.entries().forEach(resource -> {
|
||||
if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)
|
||||
&& resource.getPath().endsWith(".class") && predicate.test(resource.getPath())) {
|
||||
if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
|
||||
&& resource.path().endsWith(".class") && predicate.test(resource.path())) {
|
||||
try {
|
||||
preVisit.transform(resource, null, strings);
|
||||
} catch (Exception ex) {
|
||||
|
@ -27,8 +27,9 @@ package jdk.tools.jlink.internal.plugins;
|
||||
import java.util.function.Predicate;
|
||||
import jdk.internal.org.objectweb.asm.ClassReader;
|
||||
import jdk.internal.org.objectweb.asm.ClassWriter;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
|
||||
/**
|
||||
@ -58,27 +59,29 @@ public final class StripDebugPlugin implements Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
//remove *.diz files as well as debug attributes.
|
||||
in.transformAndCopy((resource) -> {
|
||||
ModuleEntry res = resource;
|
||||
if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
String path = resource.getPath();
|
||||
ResourcePoolEntry res = resource;
|
||||
if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
String path = resource.path();
|
||||
if (path.endsWith(".class")) {
|
||||
if (path.endsWith("module-info.class")) {
|
||||
// XXX. Do we have debug info? Is Asm ready for module-info?
|
||||
} else {
|
||||
ClassReader reader = new ClassReader(resource.getBytes());
|
||||
ClassReader reader = new ClassReader(resource.contentBytes());
|
||||
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
reader.accept(writer, ClassReader.SKIP_DEBUG);
|
||||
byte[] content = writer.toByteArray();
|
||||
res = resource.create(content);
|
||||
res = resource.copyWithContent(content);
|
||||
}
|
||||
}
|
||||
} else if (predicate.test(res.getPath())) {
|
||||
} else if (predicate.test(res.path())) {
|
||||
res = null;
|
||||
}
|
||||
return res;
|
||||
}, out);
|
||||
|
||||
return out.build();
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,9 @@
|
||||
*/
|
||||
package jdk.tools.jlink.internal.plugins;
|
||||
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
|
||||
/**
|
||||
@ -47,10 +48,12 @@ public final class StripNativeCommandsPlugin implements Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
in.transformAndCopy((file) -> {
|
||||
return file.getType() == ModuleEntry.Type.NATIVE_CMD ? null : file;
|
||||
return file.type() == ResourcePoolEntry.Type.NATIVE_CMD ? null : file;
|
||||
}, out);
|
||||
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -51,10 +51,11 @@ 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.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.internal.plugins.SystemModuleDescriptorPlugin.Builder.*;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
/**
|
||||
* Jlink plugin to reconstitute module descriptors for installed modules.
|
||||
@ -107,7 +108,7 @@ public final class SystemModuleDescriptorPlugin implements Plugin {
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
if (!enabled) {
|
||||
throw new PluginException(NAME + " was set");
|
||||
}
|
||||
@ -116,30 +117,30 @@ public final class SystemModuleDescriptorPlugin implements Plugin {
|
||||
|
||||
// generate the byte code to create ModuleDescriptors
|
||||
// skip parsing module-info.class and skip name check
|
||||
in.modules().forEach(module -> {
|
||||
Optional<ModuleEntry> optData = module.findEntry("module-info.class");
|
||||
in.moduleView().modules().forEach(module -> {
|
||||
Optional<ResourcePoolEntry> 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");
|
||||
module.name() + " module");
|
||||
}
|
||||
ModuleEntry data = optData.get();
|
||||
assert module.getName().equals(data.getModule());
|
||||
ResourcePoolEntry data = optData.get();
|
||||
assert module.name().equals(data.moduleName());
|
||||
try {
|
||||
ByteArrayInputStream bain = new ByteArrayInputStream(data.getBytes());
|
||||
ByteArrayInputStream bain = new ByteArrayInputStream(data.contentBytes());
|
||||
ModuleDescriptor md = ModuleDescriptor.read(bain);
|
||||
validateNames(md);
|
||||
|
||||
ModuleDescriptorBuilder mbuilder = builder.module(md, module.getAllPackages());
|
||||
ModuleDescriptorBuilder mbuilder = builder.module(md, module.packages());
|
||||
int packages = md.exports().size() + md.conceals().size();
|
||||
if (md.conceals().isEmpty() &&
|
||||
packages != module.getAllPackages().size()) {
|
||||
packages != module.packages().size()) {
|
||||
// add ConcealedPackages attribute if not exist
|
||||
bain.reset();
|
||||
ModuleInfoRewriter minfoWriter =
|
||||
new ModuleInfoRewriter(bain, mbuilder.conceals());
|
||||
// replace with the overridden version
|
||||
data = data.create(minfoWriter.getBytes());
|
||||
data = data.copyWithContent(minfoWriter.getBytes());
|
||||
}
|
||||
out.add(data);
|
||||
} catch (IOException e) {
|
||||
@ -150,16 +151,18 @@ public final class SystemModuleDescriptorPlugin implements Plugin {
|
||||
// Generate the new class
|
||||
ClassWriter cwriter = builder.build();
|
||||
in.entries().forEach(data -> {
|
||||
if (data.getPath().endsWith("module-info.class"))
|
||||
if (data.path().endsWith("module-info.class"))
|
||||
return;
|
||||
if (builder.isOverriddenClass(data.getPath())) {
|
||||
if (builder.isOverriddenClass(data.path())) {
|
||||
byte[] bytes = cwriter.toByteArray();
|
||||
ModuleEntry ndata = data.create(bytes);
|
||||
ResourcePoolEntry ndata = data.copyWithContent(bytes);
|
||||
out.add(ndata);
|
||||
} else {
|
||||
out.add(data);
|
||||
}
|
||||
});
|
||||
|
||||
return out.build();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -31,9 +31,11 @@ import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.zip.Deflater;
|
||||
import jdk.tools.jlink.internal.ModulePoolImpl;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
|
||||
/**
|
||||
@ -112,18 +114,20 @@ public final class ZipPlugin implements Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
in.transformAndCopy((resource) -> {
|
||||
ModuleEntry res = resource;
|
||||
if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)
|
||||
&& predicate.test(resource.getPath())) {
|
||||
ResourcePoolEntry res = resource;
|
||||
if (resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
|
||||
&& predicate.test(resource.path())) {
|
||||
byte[] compressed;
|
||||
compressed = compress(resource.getBytes());
|
||||
res = ModulePoolImpl.newCompressedResource(resource,
|
||||
compressed = compress(resource.contentBytes());
|
||||
res = ResourcePoolManager.newCompressedResource(resource,
|
||||
ByteBuffer.wrap(compressed), getName(), null,
|
||||
((ModulePoolImpl) in).getStringTable(), in.getByteOrder());
|
||||
((ResourcePoolImpl)in).getStringTable(), in.byteOrder());
|
||||
}
|
||||
return res;
|
||||
}, out);
|
||||
|
||||
return out.build();
|
||||
}
|
||||
}
|
||||
|
@ -191,5 +191,5 @@ public interface Plugin {
|
||||
*
|
||||
* @throws PluginException
|
||||
*/
|
||||
public void visit(ModulePool in, ModulePool out);
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out);
|
||||
}
|
||||
|
@ -31,65 +31,37 @@ import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Pool of module data.
|
||||
* A Pool of Java resources.
|
||||
*/
|
||||
public interface ModulePool {
|
||||
/**
|
||||
* Is this a read-only ModulePool?
|
||||
public interface ResourcePool {
|
||||
/**
|
||||
* Return the module view of this resource pool.
|
||||
*
|
||||
* @return true if this is a read-only configuration.
|
||||
* @return a module based view of this resource pool.
|
||||
*/
|
||||
public boolean isReadOnly();
|
||||
public ResourcePoolModuleView moduleView();
|
||||
|
||||
/**
|
||||
* Add a ModuleEntry.
|
||||
* Get all ResourcePoolEntry contained in this ResourcePool instance.
|
||||
*
|
||||
* @param data The ModuleEntry to add.
|
||||
* @return The stream of ResourcePoolEntries.
|
||||
*/
|
||||
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);
|
||||
public Stream<ResourcePoolEntry> entries();
|
||||
|
||||
/**
|
||||
* 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 number of ResourcePoolEntry count in this ResourcePool.
|
||||
*
|
||||
* @return the entry count.
|
||||
*/
|
||||
public int getEntryCount();
|
||||
public int entryCount();
|
||||
|
||||
/**
|
||||
* Get the ModuleEntry for the passed path.
|
||||
* Get the ResourcePoolEntry for the passed path.
|
||||
*
|
||||
* @param path A data path
|
||||
* @return A ModuleEntry instance or null if the data is not found
|
||||
* @return A ResourcePoolEntry instance or null if the data is not found
|
||||
*/
|
||||
public Optional<ModuleEntry> findEntry(String path);
|
||||
public Optional<ResourcePoolEntry> findEntry(String path);
|
||||
|
||||
/**
|
||||
* Get the ModuleEntry for the passed path restricted to supplied context.
|
||||
@ -98,48 +70,57 @@ public interface ModulePool {
|
||||
* @param context A context of the search
|
||||
* @return A ModuleEntry instance or null if the data is not found
|
||||
*/
|
||||
public Optional<ModuleEntry> findEntryInContext(String path, ModuleEntry context);
|
||||
public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context);
|
||||
|
||||
/**
|
||||
* Check if the ModulePool contains the given ModuleEntry.
|
||||
* Check if the ResourcePool contains the given ResourcePoolEntry.
|
||||
*
|
||||
* @param data The module data to check existence for.
|
||||
* @return The module data or null if not found.
|
||||
*/
|
||||
public boolean contains(ModuleEntry data);
|
||||
public boolean contains(ResourcePoolEntry data);
|
||||
|
||||
/**
|
||||
* Check if the ModulePool contains some content at all.
|
||||
* Check if the ResourcePool 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();
|
||||
public ByteOrder byteOrder();
|
||||
|
||||
/**
|
||||
* Release properties such as OS, CPU name, version etc.
|
||||
*
|
||||
* @return the release properties
|
||||
*/
|
||||
public Map<String, String> getReleaseProperties();
|
||||
public Map<String, String> releaseProperties();
|
||||
|
||||
/**
|
||||
* Visit each ResourcePoolEntry in this ResourcePool to transform it and copy
|
||||
* the transformed ResourcePoolEntry to the output ResourcePoolBuilder.
|
||||
*
|
||||
* @param transform The function called for each ResourcePoolEntry found in the
|
||||
* ResourcePool. The transform function should return a ResourcePoolEntry
|
||||
* instance which will be added to the output or it should return null if
|
||||
* the passed ResourcePoolEntry is to be ignored for the output.
|
||||
*
|
||||
* @param outBuilder The ResourcePoolBuilder to be filled with Visitor returned
|
||||
* ResourcePoolEntries.
|
||||
*/
|
||||
public default void transformAndCopy(
|
||||
Function<ResourcePoolEntry, ResourcePoolEntry> transform,
|
||||
ResourcePoolBuilder outBuilder) {
|
||||
entries().forEach(resource -> {
|
||||
ResourcePoolEntry res = transform.apply(resource);
|
||||
if (res != null) {
|
||||
outBuilder.add(res);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Resource pool builder to build a resource pool by incrementally
|
||||
* adding a set of resources one at a time.
|
||||
*/
|
||||
public interface ResourcePoolBuilder {
|
||||
/**
|
||||
* Add a ResourcePoolEntry.
|
||||
*
|
||||
* @param data The ResourcePoolEntry to add.
|
||||
*/
|
||||
public void add(ResourcePoolEntry data);
|
||||
|
||||
/**
|
||||
* Done with adding resource entries. Construct
|
||||
* a ResourcePool with the added resource entries.
|
||||
*
|
||||
* @return a new ResourcePool filled with entries added.
|
||||
*/
|
||||
public ResourcePool build();
|
||||
}
|
@ -31,13 +31,13 @@ import java.io.OutputStream;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import jdk.tools.jlink.internal.ModuleEntryFactory;
|
||||
import jdk.tools.jlink.internal.ResourcePoolEntryFactory;
|
||||
|
||||
/**
|
||||
* A ModuleEntry is the elementary unit of data inside an image. It is
|
||||
* A ResourcePoolEntry 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 ModuleEntry is identified by a path of the form:
|
||||
* A ResourcePoolEntry is identified by a path of the form:
|
||||
* <ul>
|
||||
* <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file
|
||||
* name}</li>
|
||||
@ -45,7 +45,7 @@ import jdk.tools.jlink.internal.ModuleEntryFactory;
|
||||
* {@literal bin|conf|native}/{dir1}/.../{dirN}/{file name}</li>
|
||||
* </ul>
|
||||
*/
|
||||
public interface ModuleEntry {
|
||||
public interface ResourcePoolEntry {
|
||||
|
||||
/**
|
||||
* Type of module data.
|
||||
@ -64,34 +64,49 @@ public interface ModuleEntry {
|
||||
NATIVE_LIB,
|
||||
OTHER
|
||||
}
|
||||
|
||||
/**
|
||||
* The ModuleEntry module name.
|
||||
* The module name of this ResourcePoolEntry.
|
||||
*
|
||||
* @return The module name.
|
||||
*/
|
||||
public String getModule();
|
||||
public String moduleName();
|
||||
|
||||
/**
|
||||
* The ModuleEntry path.
|
||||
* The path of this ResourcePoolEntry.
|
||||
*
|
||||
* @return The module path.
|
||||
*/
|
||||
public String getPath();
|
||||
public String path();
|
||||
|
||||
/**
|
||||
* The ModuleEntry's type.
|
||||
* The ResourcePoolEntry's type.
|
||||
*
|
||||
* @return The data type.
|
||||
*/
|
||||
public Type getType();
|
||||
public Type type();
|
||||
|
||||
/**
|
||||
* The ModuleEntry content as an array of bytes.
|
||||
* The ResourcePoolEntry content length.
|
||||
*
|
||||
* @return The content length.
|
||||
*/
|
||||
public long contentLength();
|
||||
|
||||
/**
|
||||
* The ResourcePoolEntry content as an InputStream.
|
||||
*
|
||||
* @return The resource content as an InputStream.
|
||||
*/
|
||||
public InputStream content();
|
||||
|
||||
/**
|
||||
* The ResourcePoolEntry content as an array of bytes.
|
||||
*
|
||||
* @return An Array of bytes.
|
||||
*/
|
||||
public default byte[] getBytes() {
|
||||
try (InputStream is = stream()) {
|
||||
public default byte[] contentBytes() {
|
||||
try (InputStream is = content()) {
|
||||
return is.readAllBytes();
|
||||
} catch (IOException ex) {
|
||||
throw new UncheckedIOException(ex);
|
||||
@ -99,99 +114,85 @@ public interface ModuleEntry {
|
||||
}
|
||||
|
||||
/**
|
||||
* The ModuleEntry content length.
|
||||
*
|
||||
* @return The length.
|
||||
*/
|
||||
public long getLength();
|
||||
|
||||
/**
|
||||
* The ModuleEntry stream.
|
||||
*
|
||||
* @return The module data stream.
|
||||
*/
|
||||
public InputStream stream();
|
||||
|
||||
/**
|
||||
* Write the content of this ModuleEntry to stream.
|
||||
* Write the content of this ResourcePoolEntry to an OutputStream.
|
||||
*
|
||||
* @param out the output stream
|
||||
*/
|
||||
public default void write(OutputStream out) {
|
||||
try {
|
||||
out.write(getBytes());
|
||||
out.write(contentBytes());
|
||||
} catch (IOException ex) {
|
||||
throw new UncheckedIOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ModuleEntry with new content but other information
|
||||
* copied from this ModuleEntry.
|
||||
* Create a ResourcePoolEntry with new content but other information
|
||||
* copied from this ResourcePoolEntry.
|
||||
*
|
||||
* @param content The new resource content.
|
||||
* @return A new ModuleEntry.
|
||||
* @return A new ResourcePoolEntry.
|
||||
*/
|
||||
public default ModuleEntry create(byte[] content) {
|
||||
return ModuleEntryFactory.create(this, content);
|
||||
public default ResourcePoolEntry copyWithContent(byte[] content) {
|
||||
return ResourcePoolEntryFactory.create(this, content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ModuleEntry with new content but other information
|
||||
* copied from this ModuleEntry.
|
||||
* Create a ResourcePoolEntry with new content but other information
|
||||
* copied from this ResourcePoolEntry.
|
||||
*
|
||||
* @param file The new resource content.
|
||||
* @return A new ModuleEntry.
|
||||
* @return A new ResourcePoolEntry.
|
||||
*/
|
||||
public default ModuleEntry create(Path file) {
|
||||
return ModuleEntryFactory.create(this, file);
|
||||
public default ResourcePoolEntry copyWithContent(Path file) {
|
||||
return ResourcePoolEntryFactory.create(this, file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ModuleEntry for a resource of the given type.
|
||||
* Create a ResourcePoolEntry for a resource of the given type.
|
||||
*
|
||||
* @param path The resource path.
|
||||
* @param type The ModuleEntry type.
|
||||
* @param type The ResourcePoolEntry type.
|
||||
* @param content The resource content.
|
||||
* @return A new ModuleEntry.
|
||||
* @return A new ResourcePoolEntry.
|
||||
*/
|
||||
public static ModuleEntry create(String path,
|
||||
ModuleEntry.Type type, byte[] content) {
|
||||
return ModuleEntryFactory.create(path, type, content);
|
||||
public static ResourcePoolEntry create(String path,
|
||||
ResourcePoolEntry.Type type, byte[] content) {
|
||||
return ResourcePoolEntryFactory.create(path, type, content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ModuleEntry for a resource of type {@link Type#CLASS_OR_RESOURCE}.
|
||||
* Create a ResourcePoolEntry for a resource of type {@link Type#CLASS_OR_RESOURCE}.
|
||||
*
|
||||
* @param path The resource path.
|
||||
* @param content The resource content.
|
||||
* @return A new ModuleEntry.
|
||||
* @return A new ResourcePoolEntry.
|
||||
*/
|
||||
public static ModuleEntry create(String path, byte[] content) {
|
||||
public static ResourcePoolEntry create(String path, byte[] content) {
|
||||
return create(path, Type.CLASS_OR_RESOURCE, content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ModuleEntry for a resource of the given type.
|
||||
* Create a ResourcePoolEntry for a resource of the given type.
|
||||
*
|
||||
* @param path The resource path.
|
||||
* @param type The ModuleEntry type.
|
||||
* @param type The ResourcePoolEntry type.
|
||||
* @param file The resource file.
|
||||
* @return A new ModuleEntry.
|
||||
* @return A new ResourcePoolEntry.
|
||||
*/
|
||||
public static ModuleEntry create(String path,
|
||||
ModuleEntry.Type type, Path file) {
|
||||
return ModuleEntryFactory.create(path, type, file);
|
||||
public static ResourcePoolEntry create(String path,
|
||||
ResourcePoolEntry.Type type, Path file) {
|
||||
return ResourcePoolEntryFactory.create(path, type, file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ModuleEntry for a resource of type {@link Type#CLASS_OR_RESOURCE}.
|
||||
* Create a ResourcePoolEntry for a resource of type {@link Type#CLASS_OR_RESOURCE}.
|
||||
*
|
||||
* @param path The resource path.
|
||||
* @param file The resource file.
|
||||
* @return A new ModuleEntry.
|
||||
* @return A new ResourcePoolEntry.
|
||||
*/
|
||||
public static ModuleEntry create(String path, Path file) {
|
||||
public static ResourcePoolEntry create(String path, Path file) {
|
||||
return create(path, Type.CLASS_OR_RESOURCE, file);
|
||||
}
|
||||
}
|
@ -30,58 +30,50 @@ import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Link-time representation of a Java module.
|
||||
* Link-time representation of a module.
|
||||
*/
|
||||
public interface LinkModule {
|
||||
|
||||
public interface ResourcePoolModule {
|
||||
/**
|
||||
* The module name.
|
||||
*
|
||||
* @return The name.
|
||||
* @return The module name.
|
||||
*/
|
||||
public String getName();
|
||||
public String name();
|
||||
|
||||
/**
|
||||
* Retrieves a LinkModuleEntry from the given path (e.g:
|
||||
* Retrieves a ResourcePoolEntry 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.
|
||||
* @return A ResourcePoolEntry of the given path, if found.
|
||||
*/
|
||||
public Optional<ModuleEntry> findEntry(String path);
|
||||
public Optional<ResourcePoolEntry> 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);
|
||||
public ModuleDescriptor descriptor();
|
||||
|
||||
/**
|
||||
* Retrieves all the packages located in this module.
|
||||
*
|
||||
* @return The set of packages.
|
||||
*/
|
||||
public Set<String> getAllPackages();
|
||||
public Set<String> packages();
|
||||
|
||||
/**
|
||||
* Retrieves the stream of LinkModuleEntry.
|
||||
* Retrieves the stream of ResourcePoolEntry.
|
||||
*
|
||||
* @return The LinkModuleEntry stream.
|
||||
* @return The ResourcePoolEntry stream.
|
||||
*/
|
||||
public Stream<? extends ModuleEntry> entries();
|
||||
public Stream<ResourcePoolEntry> entries();
|
||||
|
||||
/**
|
||||
* Return the number of LinkModuleEntry count in this LinkModule.
|
||||
* Return the number of ResourcePoolEntry count in this ResourcePoolModule.
|
||||
*
|
||||
* @return the entry count.
|
||||
*/
|
||||
public int getEntryCount();
|
||||
public int entryCount();
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* The module view of a ResourcePool.
|
||||
*/
|
||||
public interface ResourcePoolModuleView {
|
||||
/**
|
||||
* Find the module, if any, of the given name.
|
||||
*
|
||||
* @param name name of the module
|
||||
* @return Optional containing the module of the given name.
|
||||
*/
|
||||
public Optional<ResourcePoolModule> findModule(String name);
|
||||
|
||||
/**
|
||||
* Find the module, if any, of the given ResourcePoolEntry
|
||||
*
|
||||
* @param entry The ResourcePoolEntry whose module is looked up.
|
||||
* @return Optional containing the module of the given ResourcePoolEntry
|
||||
*/
|
||||
public default Optional<ResourcePoolModule> findModule(ResourcePoolEntry entry) {
|
||||
String name = Objects.requireNonNull(entry).moduleName();
|
||||
return name != null? findModule(name) : Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* The stream of modules contained in this ResourcePool.
|
||||
*
|
||||
* @return The stream of modules.
|
||||
*/
|
||||
public Stream<ResourcePoolModule> modules();
|
||||
|
||||
/**
|
||||
* Return the number of ResourcePoolModule count in this ResourcePool.
|
||||
*
|
||||
* @return the module count.
|
||||
*/
|
||||
public int moduleCount();
|
||||
}
|
@ -32,7 +32,8 @@ 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.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import tests.Helper;
|
||||
|
||||
/*
|
||||
@ -69,7 +70,7 @@ public class DefaultProviderTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
if (!enabled) {
|
||||
throw new PluginException(NAME + " was set");
|
||||
}
|
||||
@ -78,6 +79,8 @@ public class DefaultProviderTest {
|
||||
in.transformAndCopy(content -> {
|
||||
return content;
|
||||
}, out);
|
||||
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,7 +39,7 @@ import jdk.tools.jlink.internal.ImageFileCreator;
|
||||
import jdk.tools.jlink.internal.ImagePluginStack;
|
||||
import jdk.tools.jlink.internal.ExecutableImage;
|
||||
import jdk.tools.jlink.builder.ImageBuilder;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
|
||||
|
||||
/*
|
||||
@ -215,7 +215,7 @@ public class ImageFileCreatorTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeFiles(ModulePool content) {
|
||||
public void storeFiles(ResourcePool content) {
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -33,10 +33,10 @@
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import jdk.tools.jlink.internal.ModuleEntryFactory;
|
||||
import jdk.tools.jlink.internal.ModulePoolImpl;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.internal.ResourcePoolEntryFactory;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
|
||||
public class ImageFilePoolTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -51,55 +51,55 @@ public class ImageFilePoolTest {
|
||||
private static final String SUFFIX = "END";
|
||||
|
||||
private void checkVisitor() throws Exception {
|
||||
ModulePool input = new ModulePoolImpl();
|
||||
ResourcePoolManager input = new ResourcePoolManager();
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
String module = "module" + (i / 100);
|
||||
input.add(newInMemoryImageFile("/" + module + "/java/class" + i,
|
||||
ModuleEntry.Type.CONFIG, "class" + i));
|
||||
ResourcePoolEntry.Type.CONFIG, "class" + i));
|
||||
}
|
||||
if (input.getEntryCount() != 1000) {
|
||||
if (input.entryCount() != 1000) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
ModulePool output = new ModulePoolImpl();
|
||||
ResourcePoolManager output = new ResourcePoolManager();
|
||||
ResourceVisitor visitor = new ResourceVisitor();
|
||||
input.transformAndCopy(visitor, output);
|
||||
input.resourcePool().transformAndCopy(visitor, output.resourcePoolBuilder());
|
||||
if (visitor.getAmountBefore() == 0) {
|
||||
throw new AssertionError("Resources not found");
|
||||
}
|
||||
if (visitor.getAmountBefore() != input.getEntryCount()) {
|
||||
if (visitor.getAmountBefore() != input.entryCount()) {
|
||||
throw new AssertionError("Number of visited resources. Expected: " +
|
||||
visitor.getAmountBefore() + ", got: " + input.getEntryCount());
|
||||
visitor.getAmountBefore() + ", got: " + input.entryCount());
|
||||
}
|
||||
if (visitor.getAmountAfter() != output.getEntryCount()) {
|
||||
if (visitor.getAmountAfter() != output.entryCount()) {
|
||||
throw new AssertionError("Number of added resources. Expected: " +
|
||||
visitor.getAmountAfter() + ", got: " + output.getEntryCount());
|
||||
visitor.getAmountAfter() + ", got: " + output.entryCount());
|
||||
}
|
||||
output.entries().forEach(outFile -> {
|
||||
String path = outFile.getPath().replaceAll(SUFFIX + "$", "");
|
||||
Optional<ModuleEntry> inFile = input.findEntry(path);
|
||||
String path = outFile.path().replaceAll(SUFFIX + "$", "");
|
||||
Optional<ResourcePoolEntry> inFile = input.findEntry(path);
|
||||
if (!inFile.isPresent()) {
|
||||
throw new AssertionError("Unknown resource: " + path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class ResourceVisitor implements Function<ModuleEntry, ModuleEntry> {
|
||||
private static class ResourceVisitor implements Function<ResourcePoolEntry, ResourcePoolEntry> {
|
||||
|
||||
private int amountBefore;
|
||||
private int amountAfter;
|
||||
|
||||
@Override
|
||||
public ModuleEntry apply(ModuleEntry file) {
|
||||
public ResourcePoolEntry apply(ResourcePoolEntry file) {
|
||||
int index = ++amountBefore % 3;
|
||||
switch (index) {
|
||||
case 0:
|
||||
++amountAfter;
|
||||
return newInMemoryImageFile(file.getPath() + SUFFIX,
|
||||
file.getType(), file.getPath());
|
||||
return newInMemoryImageFile(file.path() + SUFFIX,
|
||||
file.type(), file.path());
|
||||
case 1:
|
||||
++amountAfter;
|
||||
return newInMemoryImageFile(file.getPath(),
|
||||
file.getType(), file.getPath());
|
||||
return newInMemoryImageFile(file.path(),
|
||||
file.type(), file.path());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -114,7 +114,7 @@ public class ImageFilePoolTest {
|
||||
}
|
||||
|
||||
private void checkNegative() throws Exception {
|
||||
ModulePoolImpl input = new ModulePoolImpl();
|
||||
ResourcePoolManager input = new ResourcePoolManager();
|
||||
try {
|
||||
input.add(null);
|
||||
throw new AssertionError("NullPointerException is not thrown");
|
||||
@ -128,29 +128,22 @@ public class ImageFilePoolTest {
|
||||
// expected
|
||||
}
|
||||
if (input.findEntry("unknown").isPresent()) {
|
||||
throw new AssertionError("ImageFileModulePool does not return null for unknown file");
|
||||
throw new AssertionError("ImageFileResourcePool does not return null for unknown file");
|
||||
}
|
||||
if (input.contains(newInMemoryImageFile("/unknown/foo", ModuleEntry.Type.CONFIG, "unknown"))) {
|
||||
if (input.contains(newInMemoryImageFile("/unknown/foo", ResourcePoolEntry.Type.CONFIG, "unknown"))) {
|
||||
throw new AssertionError("'contain' returns true for /unknown/foo file");
|
||||
}
|
||||
input.add(newInMemoryImageFile("/aaa/bbb", ModuleEntry.Type.CONFIG, ""));
|
||||
input.add(newInMemoryImageFile("/aaa/bbb", ResourcePoolEntry.Type.CONFIG, ""));
|
||||
try {
|
||||
input.add(newInMemoryImageFile("/aaa/bbb", ModuleEntry.Type.CONFIG, ""));
|
||||
throw new AssertionError("Exception expected");
|
||||
} catch (Exception e) {
|
||||
// expected
|
||||
}
|
||||
input.setReadOnly();
|
||||
try {
|
||||
input.add(newInMemoryImageFile("/aaa/ccc", ModuleEntry.Type.CONFIG, ""));
|
||||
input.add(newInMemoryImageFile("/aaa/bbb", ResourcePoolEntry.Type.CONFIG, ""));
|
||||
throw new AssertionError("Exception expected");
|
||||
} catch (Exception e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static ModuleEntry newInMemoryImageFile(String path,
|
||||
ModuleEntry.Type type, String content) {
|
||||
return ModuleEntryFactory.create(path, type, content.getBytes());
|
||||
private static ResourcePoolEntry newInMemoryImageFile(String path,
|
||||
ResourcePoolEntry.Type type, String content) {
|
||||
return ResourcePoolEntryFactory.create(path, type, content.getBytes());
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,8 @@ import jdk.tools.jlink.Jlink;
|
||||
import jdk.tools.jlink.Jlink.JlinkConfiguration;
|
||||
import jdk.tools.jlink.Jlink.PluginsConfiguration;
|
||||
import jdk.tools.jlink.builder.DefaultImageBuilder;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.internal.ExecutableImage;
|
||||
import jdk.tools.jlink.internal.PostProcessor;
|
||||
@ -100,8 +101,9 @@ public class IntegrationTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
in.transformAndCopy(Function.identity(), out);
|
||||
return out.build();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.internal.PluginRepository;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
|
||||
@ -62,8 +63,8 @@ public class JLinkOptionsTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,7 +31,8 @@ import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.internal.PluginRepository;
|
||||
import jdk.tools.jlink.internal.PostProcessor;
|
||||
import jdk.tools.jlink.internal.ExecutableImage;
|
||||
@ -71,8 +72,9 @@ public class JLinkPostProcessingTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
in.transformAndCopy(Function.identity(), out);
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -40,11 +40,11 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
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;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolModule;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
public class ResourcePoolTest {
|
||||
|
||||
@ -61,51 +61,51 @@ public class ResourcePoolTest {
|
||||
private static final String SUFFIX = "END";
|
||||
|
||||
private void checkResourceVisitor() throws Exception {
|
||||
ModulePool input = new ModulePoolImpl();
|
||||
ResourcePoolManager input = new ResourcePoolManager();
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
String module = "/module" + (i / 10);
|
||||
String resourcePath = module + "/java/package" + i;
|
||||
byte[] bytes = resourcePath.getBytes();
|
||||
input.add(ModuleEntry.create(resourcePath, bytes));
|
||||
input.add(ResourcePoolEntry.create(resourcePath, bytes));
|
||||
}
|
||||
ModulePool output = new ModulePoolImpl();
|
||||
ResourcePoolManager output = new ResourcePoolManager();
|
||||
ResourceVisitor visitor = new ResourceVisitor();
|
||||
input.transformAndCopy(visitor, output);
|
||||
input.resourcePool().transformAndCopy(visitor, output.resourcePoolBuilder());
|
||||
if (visitor.getAmountBefore() == 0) {
|
||||
throw new AssertionError("Resources not found");
|
||||
}
|
||||
if (visitor.getAmountBefore() != input.getEntryCount()) {
|
||||
if (visitor.getAmountBefore() != input.entryCount()) {
|
||||
throw new AssertionError("Number of visited resources. Expected: " +
|
||||
visitor.getAmountBefore() + ", got: " + input.getEntryCount());
|
||||
visitor.getAmountBefore() + ", got: " + input.entryCount());
|
||||
}
|
||||
if (visitor.getAmountAfter() != output.getEntryCount()) {
|
||||
if (visitor.getAmountAfter() != output.entryCount()) {
|
||||
throw new AssertionError("Number of added resources. Expected: " +
|
||||
visitor.getAmountAfter() + ", got: " + output.getEntryCount());
|
||||
visitor.getAmountAfter() + ", got: " + output.entryCount());
|
||||
}
|
||||
output.entries().forEach(outResource -> {
|
||||
String path = outResource.getPath().replaceAll(SUFFIX + "$", "");
|
||||
String path = outResource.path().replaceAll(SUFFIX + "$", "");
|
||||
if (!input.findEntry(path).isPresent()) {
|
||||
throw new AssertionError("Unknown resource: " + path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class ResourceVisitor implements Function<ModuleEntry, ModuleEntry> {
|
||||
private static class ResourceVisitor implements Function<ResourcePoolEntry, ResourcePoolEntry> {
|
||||
|
||||
private int amountBefore;
|
||||
private int amountAfter;
|
||||
|
||||
@Override
|
||||
public ModuleEntry apply(ModuleEntry resource) {
|
||||
public ResourcePoolEntry apply(ResourcePoolEntry resource) {
|
||||
int index = ++amountBefore % 3;
|
||||
switch (index) {
|
||||
case 0:
|
||||
++amountAfter;
|
||||
return ModuleEntry.create(resource.getPath() + SUFFIX,
|
||||
resource.getType(), resource.getBytes());
|
||||
return ResourcePoolEntry.create(resource.path() + SUFFIX,
|
||||
resource.type(), resource.contentBytes());
|
||||
case 1:
|
||||
++amountAfter;
|
||||
return resource.create(resource.getBytes());
|
||||
return resource.copyWithContent(resource.contentBytes());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -129,17 +129,17 @@ public class ResourcePoolTest {
|
||||
samples.add("javax/management/ObjectName");
|
||||
test(samples, (resources, module, path) -> {
|
||||
try {
|
||||
resources.add(ModuleEntry.create(path, new byte[0]));
|
||||
resources.add(ResourcePoolEntry.create(path, new byte[0]));
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
});
|
||||
test(samples, (resources, module, path) -> {
|
||||
try {
|
||||
resources.add(ModulePoolImpl.
|
||||
newCompressedResource(ModuleEntry.create(path, new byte[0]),
|
||||
resources.add(ResourcePoolManager.
|
||||
newCompressedResource(ResourcePoolEntry.create(path, new byte[0]),
|
||||
ByteBuffer.allocate(99), "bitcruncher", null,
|
||||
((ModulePoolImpl)resources).getStringTable(), ByteOrder.nativeOrder()));
|
||||
((ResourcePoolManager)resources).getStringTable(), ByteOrder.nativeOrder()));
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
@ -150,7 +150,7 @@ public class ResourcePoolTest {
|
||||
if (samples.isEmpty()) {
|
||||
throw new AssertionError("No sample to test");
|
||||
}
|
||||
ModulePool resources = new ModulePoolImpl();
|
||||
ResourcePoolManager resources = new ResourcePoolManager();
|
||||
Set<String> modules = new HashSet<>();
|
||||
for (int i = 0; i < samples.size(); i++) {
|
||||
String module = samples.get(i);
|
||||
@ -165,68 +165,68 @@ public class ResourcePoolTest {
|
||||
i++;
|
||||
String clazz = samples.get(i);
|
||||
String path = "/" + module + "/" + clazz + ".class";
|
||||
Optional<ModuleEntry> res = resources.findEntry(path);
|
||||
Optional<ResourcePoolEntry> res = resources.findEntry(path);
|
||||
if (!res.isPresent()) {
|
||||
throw new AssertionError("Resource not found " + path);
|
||||
}
|
||||
checkModule(resources, res.get());
|
||||
checkModule(resources.resourcePool(), res.get());
|
||||
if (resources.findEntry(clazz).isPresent()) {
|
||||
throw new AssertionError("Resource found " + clazz);
|
||||
}
|
||||
}
|
||||
if (resources.getEntryCount() != samples.size() / 2) {
|
||||
if (resources.entryCount() != samples.size() / 2) {
|
||||
throw new AssertionError("Invalid number of resources");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkModule(ModulePool resources, ModuleEntry res) {
|
||||
Optional<LinkModule> optMod = resources.findModule(res.getModule());
|
||||
private void checkModule(ResourcePool resources, ResourcePoolEntry res) {
|
||||
Optional<ResourcePoolModule> optMod = resources.moduleView().findModule(res.moduleName());
|
||||
if (!optMod.isPresent()) {
|
||||
throw new AssertionError("No module " + res.getModule());
|
||||
throw new AssertionError("No module " + res.moduleName());
|
||||
}
|
||||
LinkModule m = optMod.get();
|
||||
if (!m.getName().equals(res.getModule())) {
|
||||
throw new AssertionError("Not right module name " + res.getModule());
|
||||
ResourcePoolModule m = optMod.get();
|
||||
if (!m.name().equals(res.moduleName())) {
|
||||
throw new AssertionError("Not right module name " + res.moduleName());
|
||||
}
|
||||
if (!m.findEntry(res.getPath()).isPresent()) {
|
||||
throw new AssertionError("resource " + res.getPath()
|
||||
+ " not in module " + m.getName());
|
||||
if (!m.findEntry(res.path()).isPresent()) {
|
||||
throw new AssertionError("resource " + res.path()
|
||||
+ " not in module " + m.name());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkResourcesAfterCompression() throws Exception {
|
||||
ModulePoolImpl resources1 = new ModulePoolImpl();
|
||||
ModuleEntry res1 = ModuleEntry.create("/module1/toto1", new byte[0]);
|
||||
ModuleEntry res2 = ModuleEntry.create("/module2/toto1", new byte[0]);
|
||||
ResourcePoolManager resources1 = new ResourcePoolManager();
|
||||
ResourcePoolEntry res1 = ResourcePoolEntry.create("/module1/toto1", new byte[0]);
|
||||
ResourcePoolEntry res2 = ResourcePoolEntry.create("/module2/toto1", new byte[0]);
|
||||
resources1.add(res1);
|
||||
resources1.add(res2);
|
||||
|
||||
checkResources(resources1, res1, res2);
|
||||
ModulePool resources2 = new ModulePoolImpl();
|
||||
ModuleEntry res3 = ModuleEntry.create("/module2/toto1", new byte[7]);
|
||||
ResourcePoolManager resources2 = new ResourcePoolManager();
|
||||
ResourcePoolEntry res3 = ResourcePoolEntry.create("/module2/toto1", new byte[7]);
|
||||
resources2.add(res3);
|
||||
resources2.add(ModulePoolImpl.newCompressedResource(res1,
|
||||
resources2.add(ResourcePoolManager.newCompressedResource(res1,
|
||||
ByteBuffer.allocate(7), "zip", null, resources1.getStringTable(),
|
||||
ByteOrder.nativeOrder()));
|
||||
checkResources(resources2, res1, res2);
|
||||
}
|
||||
|
||||
private void checkResources(ModulePool resources, ModuleEntry... expected) {
|
||||
private void checkResources(ResourcePoolManager resources, ResourcePoolEntry... expected) {
|
||||
List<String> modules = new ArrayList();
|
||||
resources.modules().forEach(m -> {
|
||||
modules.add(m.getName());
|
||||
modules.add(m.name());
|
||||
});
|
||||
for (ModuleEntry res : expected) {
|
||||
for (ResourcePoolEntry res : expected) {
|
||||
if (!resources.contains(res)) {
|
||||
throw new AssertionError("Resource not found: " + res);
|
||||
}
|
||||
|
||||
if (!resources.findEntry(res.getPath()).isPresent()) {
|
||||
if (!resources.findEntry(res.path()).isPresent()) {
|
||||
throw new AssertionError("Resource not found: " + res);
|
||||
}
|
||||
|
||||
if (!modules.contains(res.getModule())) {
|
||||
throw new AssertionError("Module not found: " + res.getModule());
|
||||
if (!modules.contains(res.moduleName())) {
|
||||
throw new AssertionError("Module not found: " + res.moduleName());
|
||||
}
|
||||
|
||||
if (!resources.contains(res)) {
|
||||
@ -241,20 +241,15 @@ public class ResourcePoolTest {
|
||||
}
|
||||
}
|
||||
|
||||
if (resources.isReadOnly()) {
|
||||
throw new AssertionError("ReadOnly resources");
|
||||
}
|
||||
|
||||
((ModulePoolImpl) resources).setReadOnly();
|
||||
try {
|
||||
resources.add(ModuleEntry.create("/module2/toto1", new byte[0]));
|
||||
throw new AssertionError("ModulePool is read-only, but an exception is not thrown");
|
||||
resources.add(ResourcePoolEntry.create("/module2/toto1", new byte[0]));
|
||||
throw new AssertionError("ResourcePool is read-only, but an exception is not thrown");
|
||||
} catch (Exception ex) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
interface ResourceAdder {
|
||||
void add(ModulePool resources, String module, String path);
|
||||
void add(ResourcePoolManager resources, String module, String path);
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,9 @@ package plugin;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
|
||||
public class CustomPlugin implements Plugin {
|
||||
@ -37,8 +38,9 @@ public class CustomPlugin implements Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool in, ModulePool out) {
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
in.transformAndCopy(Function.identity(), out);
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -27,8 +27,9 @@ import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
|
||||
/**
|
||||
@ -47,7 +48,7 @@ public final class HelloPlugin implements Plugin {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool inResources, ModulePool outResources) {
|
||||
public ResourcePool transform(ResourcePool inResources, ResourcePoolBuilder outResources) {
|
||||
try {
|
||||
System.out.println("Hello!!!!!!!!!!");
|
||||
File f = new File(OUTPUT_FILE);
|
||||
@ -58,6 +59,7 @@ public final class HelloPlugin implements Plugin {
|
||||
} catch (IOException ex) {
|
||||
throw new UncheckedIOException(ex);
|
||||
}
|
||||
return outResources.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,14 +53,15 @@ 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.ModulePoolImpl;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
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.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
public class CompressorPluginTest {
|
||||
|
||||
@ -85,7 +86,7 @@ public class CompressorPluginTest {
|
||||
new ZipDecompressorFactory()
|
||||
});
|
||||
|
||||
ModulePool classes = gatherClasses(javabase);
|
||||
ResourcePool classes = gatherClasses(javabase);
|
||||
// compress = String sharing
|
||||
checkCompress(classes, new StringSharingPlugin(), null,
|
||||
new ResourceDecompressorFactory[]{
|
||||
@ -168,8 +169,8 @@ public class CompressorPluginTest {
|
||||
}, Collections.singletonList(".*Exception.class"));
|
||||
}
|
||||
|
||||
private ModulePool gatherResources(Path module) throws Exception {
|
||||
ModulePool pool = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
|
||||
private ResourcePool gatherResources(Path module) throws Exception {
|
||||
ResourcePoolManager poolMgr = new ResourcePoolManager(ByteOrder.nativeOrder(), new StringTable() {
|
||||
|
||||
@Override
|
||||
public int addString(String str) {
|
||||
@ -181,20 +182,22 @@ public class CompressorPluginTest {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
ResourcePoolBuilder poolBuilder = poolMgr.resourcePoolBuilder();
|
||||
try (Stream<Path> stream = Files.walk(module)) {
|
||||
for (Iterator<Path> iterator = stream.iterator(); iterator.hasNext();) {
|
||||
Path p = iterator.next();
|
||||
if (Files.isRegularFile(p)) {
|
||||
byte[] content = Files.readAllBytes(p);
|
||||
pool.add(ModuleEntry.create(p.toString(), content));
|
||||
poolBuilder.add(ResourcePoolEntry.create(p.toString(), content));
|
||||
}
|
||||
}
|
||||
}
|
||||
return pool;
|
||||
return poolBuilder.build();
|
||||
}
|
||||
|
||||
private ModulePool gatherClasses(Path module) throws Exception {
|
||||
ModulePool pool = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
|
||||
private ResourcePool gatherClasses(Path module) throws Exception {
|
||||
ResourcePoolManager poolMgr = new ResourcePoolManager(ByteOrder.nativeOrder(), new StringTable() {
|
||||
|
||||
@Override
|
||||
public int addString(String str) {
|
||||
@ -206,25 +209,27 @@ public class CompressorPluginTest {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
ResourcePoolBuilder poolBuilder = poolMgr.resourcePoolBuilder();
|
||||
try (Stream<Path> stream = Files.walk(module)) {
|
||||
for (Iterator<Path> iterator = stream.iterator(); iterator.hasNext();) {
|
||||
Path p = iterator.next();
|
||||
if (Files.isRegularFile(p) && p.toString().endsWith(".class")) {
|
||||
byte[] content = Files.readAllBytes(p);
|
||||
pool.add(ModuleEntry.create(p.toString(), content));
|
||||
poolBuilder.add(ResourcePoolEntry.create(p.toString(), content));
|
||||
}
|
||||
}
|
||||
}
|
||||
return pool;
|
||||
return poolBuilder.build();
|
||||
}
|
||||
|
||||
private void checkCompress(ModulePool resources, Plugin prov,
|
||||
private void checkCompress(ResourcePool resources, Plugin prov,
|
||||
Properties config,
|
||||
ResourceDecompressorFactory[] factories) throws Exception {
|
||||
checkCompress(resources, prov, config, factories, Collections.emptyList());
|
||||
}
|
||||
|
||||
private void checkCompress(ModulePool resources, Plugin prov,
|
||||
private void checkCompress(ResourcePool resources, Plugin prov,
|
||||
Properties config,
|
||||
ResourceDecompressorFactory[] factories,
|
||||
List<String> includes) throws Exception {
|
||||
@ -243,7 +248,7 @@ public class CompressorPluginTest {
|
||||
}
|
||||
prov.configure(props);
|
||||
final Map<Integer, String> strings = new HashMap<>();
|
||||
ModulePoolImpl inputResources = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
|
||||
ResourcePoolManager inputResourcesMgr = new ResourcePoolManager(ByteOrder.nativeOrder(), new StringTable() {
|
||||
@Override
|
||||
public int addString(String str) {
|
||||
int id = strID;
|
||||
@ -257,11 +262,11 @@ public class CompressorPluginTest {
|
||||
return strings.get(id);
|
||||
}
|
||||
});
|
||||
inputResources.add(resource);
|
||||
ModulePool compressedResources = applyCompressor(prov, inputResources, resource, includesPatterns);
|
||||
original[0] += resource.getLength();
|
||||
compressed[0] += compressedResources.findEntry(resource.getPath()).get().getLength();
|
||||
applyDecompressors(factories, inputResources, compressedResources, strings, includesPatterns);
|
||||
inputResourcesMgr.add(resource);
|
||||
ResourcePool compressedResources = applyCompressor(prov, inputResourcesMgr, resource, includesPatterns);
|
||||
original[0] += resource.contentLength();
|
||||
compressed[0] += compressedResources.findEntry(resource.path()).get().contentLength();
|
||||
applyDecompressors(factories, inputResourcesMgr.resourcePool(), compressedResources, strings, includesPatterns);
|
||||
});
|
||||
String compressors = Stream.of(factories)
|
||||
.map(Object::getClass)
|
||||
@ -274,16 +279,18 @@ public class CompressorPluginTest {
|
||||
}
|
||||
}
|
||||
|
||||
private ModulePool applyCompressor(Plugin plugin,
|
||||
ModulePoolImpl inputResources,
|
||||
ModuleEntry res,
|
||||
private ResourcePool applyCompressor(Plugin plugin,
|
||||
ResourcePoolManager inputResources,
|
||||
ResourcePoolEntry res,
|
||||
List<Pattern> includesPatterns) {
|
||||
ModulePool compressedModulePool = new ModulePoolImpl(ByteOrder.nativeOrder(), inputResources.getStringTable());
|
||||
plugin.visit(inputResources, compressedModulePool);
|
||||
String path = res.getPath();
|
||||
ModuleEntry compressed = compressedModulePool.findEntry(path).get();
|
||||
ResourcePoolManager resMgr = new ResourcePoolManager(ByteOrder.nativeOrder(),
|
||||
inputResources.getStringTable());
|
||||
ResourcePool compressedResourcePool = plugin.transform(inputResources.resourcePool(),
|
||||
resMgr.resourcePoolBuilder());
|
||||
String path = res.path();
|
||||
ResourcePoolEntry compressed = compressedResourcePool.findEntry(path).get();
|
||||
CompressedResourceHeader header
|
||||
= CompressedResourceHeader.readFromResource(ByteOrder.nativeOrder(), compressed.getBytes());
|
||||
= CompressedResourceHeader.readFromResource(ByteOrder.nativeOrder(), compressed.contentBytes());
|
||||
if (isIncluded(includesPatterns, path)) {
|
||||
if (header == null) {
|
||||
throw new AssertionError("Path should be compressed: " + path);
|
||||
@ -299,23 +306,23 @@ public class CompressorPluginTest {
|
||||
} else if (header != null) {
|
||||
throw new AssertionError("Path should not be compressed: " + path);
|
||||
}
|
||||
return compressedModulePool;
|
||||
return compressedResourcePool;
|
||||
}
|
||||
|
||||
private void applyDecompressors(ResourceDecompressorFactory[] decompressors,
|
||||
ModulePool inputResources,
|
||||
ModulePool compressedResources,
|
||||
ResourcePool inputResources,
|
||||
ResourcePool compressedResources,
|
||||
Map<Integer, String> strings,
|
||||
List<Pattern> includesPatterns) {
|
||||
compressedResources.entries().forEach(compressed -> {
|
||||
CompressedResourceHeader header = CompressedResourceHeader.readFromResource(
|
||||
ByteOrder.nativeOrder(), compressed.getBytes());
|
||||
String path = compressed.getPath();
|
||||
ModuleEntry orig = inputResources.findEntry(path).get();
|
||||
ByteOrder.nativeOrder(), compressed.contentBytes());
|
||||
String path = compressed.path();
|
||||
ResourcePoolEntry orig = inputResources.findEntry(path).get();
|
||||
if (!isIncluded(includesPatterns, path)) {
|
||||
return;
|
||||
}
|
||||
byte[] decompressed = compressed.getBytes();
|
||||
byte[] decompressed = compressed.contentBytes();
|
||||
for (ResourceDecompressorFactory factory : decompressors) {
|
||||
try {
|
||||
ResourceDecompressor decompressor = factory.newDecompressor(new Properties());
|
||||
@ -327,11 +334,11 @@ public class CompressorPluginTest {
|
||||
}
|
||||
}
|
||||
|
||||
if (decompressed.length != orig.getLength()) {
|
||||
if (decompressed.length != orig.contentLength()) {
|
||||
throw new AssertionError("Invalid uncompressed size "
|
||||
+ header.getUncompressedSize());
|
||||
}
|
||||
byte[] origContent = orig.getBytes();
|
||||
byte[] origContent = orig.contentBytes();
|
||||
for (int i = 0; i < decompressed.length; i++) {
|
||||
if (decompressed[i] != origContent[i]) {
|
||||
throw new AssertionError("Decompressed and original differ at index " + i);
|
||||
|
@ -35,11 +35,11 @@ import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import jdk.tools.jlink.internal.ModulePoolImpl;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
|
||||
import jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
public class ExcludeFilesPluginTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -71,20 +71,20 @@ public class ExcludeFilesPluginTest {
|
||||
prop.put(ExcludeFilesPlugin.NAME, s);
|
||||
ExcludeFilesPlugin fplug = new ExcludeFilesPlugin();
|
||||
fplug.configure(prop);
|
||||
ModulePoolImpl files = new ModulePoolImpl();
|
||||
ModulePoolImpl fresult = new ModulePoolImpl();
|
||||
ModuleEntry f = ModuleEntry.create("/" + module + "/" + sample,
|
||||
ModuleEntry.Type.CONFIG, new byte[0]);
|
||||
ResourcePoolManager files = new ResourcePoolManager();
|
||||
ResourcePoolManager fresult = new ResourcePoolManager();
|
||||
ResourcePoolEntry f = ResourcePoolEntry.create("/" + module + "/" + sample,
|
||||
ResourcePoolEntry.Type.CONFIG, new byte[0]);
|
||||
files.add(f);
|
||||
|
||||
fplug.visit(files, fresult);
|
||||
ResourcePool resPool = fplug.transform(files.resourcePool(), fresult.resourcePoolBuilder());
|
||||
|
||||
if (exclude) {
|
||||
if (fresult.contains(f)) {
|
||||
if (resPool.contains(f)) {
|
||||
throw new Exception(sample + " should be excluded by " + s);
|
||||
}
|
||||
} else {
|
||||
if (!fresult.contains(f)) {
|
||||
if (!resPool.contains(f)) {
|
||||
throw new Exception(sample + " shouldn't be excluded by " + s);
|
||||
}
|
||||
}
|
||||
|
@ -34,11 +34,12 @@ import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import jdk.tools.jlink.internal.ModulePoolImpl;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
|
||||
import jdk.tools.jlink.internal.plugins.ExcludePlugin;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
public class ExcludePluginTest {
|
||||
|
||||
@ -75,17 +76,18 @@ public class ExcludePluginTest {
|
||||
prop.put(ExcludePlugin.NAME, s);
|
||||
ExcludePlugin excludePlugin = new ExcludePlugin();
|
||||
excludePlugin.configure(prop);
|
||||
ModulePool resources = new ModulePoolImpl();
|
||||
ModuleEntry resource = ModuleEntry.create(sample, new byte[0]);
|
||||
resources.add(resource);
|
||||
ModulePool result = new ModulePoolImpl();
|
||||
excludePlugin.visit(resources, result);
|
||||
ResourcePoolManager resourcesMgr = new ResourcePoolManager();
|
||||
ResourcePoolEntry resource = ResourcePoolEntry.create(sample, new byte[0]);
|
||||
resourcesMgr.add(resource);
|
||||
ResourcePoolManager resultMgr = new ResourcePoolManager();
|
||||
ResourcePool resPool = excludePlugin.transform(resourcesMgr.resourcePool(),
|
||||
resultMgr.resourcePoolBuilder());
|
||||
if (exclude) {
|
||||
if (result.contains(resource)) {
|
||||
if (resPool.contains(resource)) {
|
||||
throw new AssertionError(sample + " should be excluded by " + s);
|
||||
}
|
||||
} else {
|
||||
if (!result.contains(resource)) {
|
||||
if (!resPool.contains(resource)) {
|
||||
throw new AssertionError(sample + " shouldn't be excluded by " + s);
|
||||
}
|
||||
}
|
||||
|
@ -32,12 +32,12 @@
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import jdk.tools.jlink.internal.ModulePoolImpl;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
|
||||
import jdk.tools.jlink.internal.plugins.ExcludeVMPlugin;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
public class ExcludeVMPluginTest {
|
||||
|
||||
@ -163,14 +163,15 @@ 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();
|
||||
ModulePool pool = new ModulePoolImpl();
|
||||
pool.add(ModuleEntry.create("/java.base/native/jvm.cfg",
|
||||
ModuleEntry.Type.NATIVE_LIB, jvmcfgContent));
|
||||
ResourcePoolManager poolMgr = new ResourcePoolManager();
|
||||
poolMgr.add(
|
||||
ResourcePoolEntry.create("/java.base/native/jvm.cfg",
|
||||
ResourcePoolEntry.Type.NATIVE_LIB, jvmcfgContent));
|
||||
for (String in : input) {
|
||||
pool.add(ModuleEntry.create(in,
|
||||
ModuleEntry.Type.NATIVE_LIB, new byte[0]));
|
||||
poolMgr.add(ResourcePoolEntry.create(in,
|
||||
ResourcePoolEntry.Type.NATIVE_LIB, new byte[0]));
|
||||
}
|
||||
ModulePool out = new ModulePoolImpl();
|
||||
ResourcePoolManager outMgr = new ResourcePoolManager();
|
||||
|
||||
Plugin p = new ExcludeVMPlugin();
|
||||
Map<String, String> config = new HashMap<>();
|
||||
@ -178,34 +179,34 @@ public class ExcludeVMPluginTest {
|
||||
config.put(ExcludeVMPlugin.NAME, vm);
|
||||
}
|
||||
p.configure(config);
|
||||
p.visit(pool, out);
|
||||
ResourcePool out = p.transform(poolMgr.resourcePool(), outMgr.resourcePoolBuilder());
|
||||
|
||||
String newContent = new String(out.findEntry("/java.base/native/jvm.cfg").get().stream().readAllBytes());
|
||||
String newContent = new String(out.findEntry("/java.base/native/jvm.cfg").get().contentBytes());
|
||||
|
||||
if (!expectdJvmCfg.equals(newContent)) {
|
||||
throw new Exception("Got content " + newContent + " expected " + expectdJvmCfg);
|
||||
}
|
||||
|
||||
if (out.getEntryCount() != (expectedOutput.length + 1)) {
|
||||
if (out.entryCount() != (expectedOutput.length + 1)) {
|
||||
out.entries().forEach(m -> {
|
||||
System.err.println(m.getPath());
|
||||
System.err.println(m.path());
|
||||
});
|
||||
throw new Exception("Invalid output size " + out.getEntryCount() + " expected " + (expectedOutput.length + 1));
|
||||
throw new Exception("Invalid output size " + out.entryCount() + " expected " + (expectedOutput.length + 1));
|
||||
}
|
||||
|
||||
out.entries().forEach(md -> {
|
||||
if (md.getPath().equals("/java.base/native/jvm.cfg")) {
|
||||
if (md.path().equals("/java.base/native/jvm.cfg")) {
|
||||
return;
|
||||
}
|
||||
boolean contained = false;
|
||||
for (String o : expectedOutput) {
|
||||
if (md.getPath().equals(o)) {
|
||||
if (md.path().equals(o)) {
|
||||
contained = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!contained) {
|
||||
throw new RuntimeException(md.getPath() + " not expected");
|
||||
throw new RuntimeException(md.path() + " not expected");
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -37,12 +37,12 @@ import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import jdk.tools.jlink.internal.ModulePoolImpl;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
import jdk.tools.jlink.builder.DefaultImageBuilder;
|
||||
|
||||
import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
|
||||
public class FileCopierPluginTest {
|
||||
|
||||
@ -85,18 +85,20 @@ public class FileCopierPluginTest {
|
||||
Map<String, String> conf = new HashMap<>();
|
||||
conf.put(FileCopierPlugin.NAME, builder.toString());
|
||||
plug.configure(conf);
|
||||
ModulePool pool = new ModulePoolImpl();
|
||||
plug.visit(new ModulePoolImpl(), pool);
|
||||
if (pool.getEntryCount() != expected) {
|
||||
ResourcePoolManager poolMgr = new ResourcePoolManager();
|
||||
ResourcePool pool = plug.transform(
|
||||
new ResourcePoolManager().resourcePool(),
|
||||
poolMgr.resourcePoolBuilder());
|
||||
if (pool.entryCount() != expected) {
|
||||
throw new AssertionError("Wrong number of added files");
|
||||
}
|
||||
pool.entries().forEach(f -> {
|
||||
if (!f.getType().equals(ModuleEntry.Type.OTHER)) {
|
||||
throw new AssertionError("Invalid type " + f.getType()
|
||||
+ " for file " + f.getPath());
|
||||
if (!f.type().equals(ResourcePoolEntry.Type.OTHER)) {
|
||||
throw new AssertionError("Invalid type " + f.type()
|
||||
+ " for file " + f.path());
|
||||
}
|
||||
if (f.stream() == null) {
|
||||
throw new AssertionError("Null stream for file " + f.getPath());
|
||||
if (f.content() == null) {
|
||||
throw new AssertionError("Null stream for file " + f.path());
|
||||
}
|
||||
});
|
||||
Path root = new File(".").toPath();
|
||||
|
@ -39,12 +39,13 @@ import java.util.Map;
|
||||
import jdk.tools.jlink.internal.ImagePluginConfiguration;
|
||||
import jdk.tools.jlink.internal.PluginRepository;
|
||||
import jdk.tools.jlink.internal.ImagePluginStack;
|
||||
import jdk.tools.jlink.internal.ModulePoolImpl;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
import jdk.tools.jlink.Jlink;
|
||||
import jdk.tools.jlink.Jlink.PluginsConfiguration;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
public class LastSorterTest {
|
||||
|
||||
@ -78,7 +79,7 @@ public class LastSorterTest {
|
||||
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config);
|
||||
|
||||
// check order
|
||||
ModulePoolImpl res = fillOutResourceModulePool();
|
||||
ResourcePoolManager res = fillOutResourceResourcePool();
|
||||
|
||||
try {
|
||||
stack.visitResources(res);
|
||||
@ -89,18 +90,18 @@ public class LastSorterTest {
|
||||
}
|
||||
}
|
||||
|
||||
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]));
|
||||
private ResourcePoolManager fillOutResourceResourcePool() throws Exception {
|
||||
ResourcePoolManager res = new ResourcePoolManager();
|
||||
res.add(ResourcePoolEntry.create("/eee/bbb/res1.class", new byte[90]));
|
||||
res.add(ResourcePoolEntry.create("/aaaa/bbb/res2.class", new byte[90]));
|
||||
res.add(ResourcePoolEntry.create("/bbb/aa/res1.class", new byte[90]));
|
||||
res.add(ResourcePoolEntry.create("/aaaa/bbb/res3.class", new byte[90]));
|
||||
res.add(ResourcePoolEntry.create("/bbb/aa/res2.class", new byte[90]));
|
||||
res.add(ResourcePoolEntry.create("/fff/bbb/res1.class", new byte[90]));
|
||||
res.add(ResourcePoolEntry.create("/aaaa/bbb/res1.class", new byte[90]));
|
||||
res.add(ResourcePoolEntry.create("/bbb/aa/res3.class", new byte[90]));
|
||||
res.add(ResourcePoolEntry.create("/ccc/bbb/res1.class", new byte[90]));
|
||||
res.add(ResourcePoolEntry.create("/ddd/bbb/res1.class", new byte[90]));
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -122,7 +123,7 @@ public class LastSorterTest {
|
||||
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config);
|
||||
|
||||
// check order
|
||||
ModulePoolImpl res = fillOutResourceModulePool();
|
||||
ResourcePoolManager res = fillOutResourceResourcePool();
|
||||
|
||||
stack.visitResources(res);
|
||||
}
|
||||
@ -157,7 +158,7 @@ public class LastSorterTest {
|
||||
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config);
|
||||
|
||||
// check order
|
||||
ModulePoolImpl res = fillOutResourceModulePool();
|
||||
ResourcePoolManager res = fillOutResourceResourcePool();
|
||||
try {
|
||||
stack.visitResources(res);
|
||||
throw new AssertionError("Order was changed after the last sorter, but no exception occurred");
|
||||
@ -176,19 +177,21 @@ public class LastSorterTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool resources, ModulePool output) {
|
||||
List<ModuleEntry> paths = new ArrayList<>();
|
||||
public ResourcePool transform(ResourcePool resources, ResourcePoolBuilder output) {
|
||||
List<ResourcePoolEntry> paths = new ArrayList<>();
|
||||
resources.entries().forEach(res -> {
|
||||
if (res.getPath().startsWith(starts)) {
|
||||
if (res.path().startsWith(starts)) {
|
||||
paths.add(0, res);
|
||||
} else {
|
||||
paths.add(res);
|
||||
}
|
||||
});
|
||||
|
||||
for (ModuleEntry r : paths) {
|
||||
for (ResourcePoolEntry r : paths) {
|
||||
output.add(r);
|
||||
}
|
||||
|
||||
return output.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,145 +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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test sorter plugin
|
||||
* @author Jean-Francois Denise
|
||||
* @modules jdk.jlink/jdk.tools.jlink.internal
|
||||
* jdk.jlink/jdk.tools.jlink.internal.plugins
|
||||
* @run main OrderResourcesPluginTest
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jdk.tools.jlink.internal.ModulePoolImpl;
|
||||
import jdk.tools.jlink.internal.plugins.OrderResourcesPlugin;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
|
||||
public class OrderResourcesPluginTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new OrderResourcesPluginTest().test();
|
||||
}
|
||||
|
||||
public void test() throws Exception {
|
||||
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])
|
||||
};
|
||||
|
||||
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])
|
||||
};
|
||||
|
||||
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])
|
||||
};
|
||||
|
||||
ModulePool resources = new ModulePoolImpl();
|
||||
for (ModuleEntry r : array) {
|
||||
resources.add(r);
|
||||
}
|
||||
|
||||
{
|
||||
ModulePool out = new ModulePoolImpl();
|
||||
Map<String, String> config = new HashMap<>();
|
||||
config.put(OrderResourcesPlugin.NAME, "/zazou/**,**/module-info.class");
|
||||
Plugin p = new OrderResourcesPlugin();
|
||||
p.configure(config);
|
||||
p.visit(resources, out);
|
||||
check(out.entries().collect(Collectors.toList()), sorted);
|
||||
}
|
||||
|
||||
{
|
||||
// Order of resources in the file, then un-ordered resources.
|
||||
File order = new File("resources.order");
|
||||
order.createNewFile();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
// 5 first resources come from file
|
||||
for (int i = 0; i < 5; i++) {
|
||||
String path = sorted2[i].getPath();
|
||||
int index = path.indexOf('/', 1);
|
||||
path = path.substring(index + 1, path.length() - ".class".length());
|
||||
builder.append(path).append("\n");
|
||||
}
|
||||
Files.write(order.toPath(), builder.toString().getBytes());
|
||||
|
||||
ModulePool out = new ModulePoolImpl();
|
||||
Map<String, String> config = new HashMap<>();
|
||||
config.put(OrderResourcesPlugin.NAME, "@" + order.getAbsolutePath());
|
||||
Plugin p = new OrderResourcesPlugin();
|
||||
p.configure(config);
|
||||
p.visit(resources, out);
|
||||
check(out.entries().collect(Collectors.toList()), sorted2);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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 (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"
|
||||
+ "expected: " + Arrays.toString(sorted) + ",\n"
|
||||
+ " got: " + outResources);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
@ -38,12 +38,13 @@ import java.util.Map;
|
||||
import jdk.tools.jlink.internal.ImagePluginConfiguration;
|
||||
import jdk.tools.jlink.internal.PluginRepository;
|
||||
import jdk.tools.jlink.internal.ImagePluginStack;
|
||||
import jdk.tools.jlink.internal.ModulePoolImpl;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
import jdk.tools.jlink.Jlink;
|
||||
import jdk.tools.jlink.Jlink.PluginsConfiguration;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
public class PluginsNegativeTest {
|
||||
|
||||
@ -95,8 +96,8 @@ public class PluginsNegativeTest {
|
||||
plugins.add(createPlugin("plugin"));
|
||||
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new PluginsConfiguration(plugins,
|
||||
null, null));
|
||||
ModulePoolImpl inResources = new ModulePoolImpl();
|
||||
inResources.add(ModuleEntry.create("/aaa/bbb/A", new byte[10]));
|
||||
ResourcePoolManager inResources = new ResourcePoolManager();
|
||||
inResources.add(ResourcePoolEntry.create("/aaa/bbb/A", new byte[10]));
|
||||
try {
|
||||
stack.visitResources(inResources);
|
||||
throw new AssertionError("Exception expected when output resource is empty");
|
||||
@ -109,8 +110,8 @@ public class PluginsNegativeTest {
|
||||
plugins.add(createPlugin("plugin"));
|
||||
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new PluginsConfiguration(plugins,
|
||||
null, null));
|
||||
ModulePoolImpl inResources = new ModulePoolImpl();
|
||||
ModulePoolImpl outResources = (ModulePoolImpl) stack.visitResources(inResources);
|
||||
ResourcePoolManager inResources = new ResourcePoolManager();
|
||||
ResourcePool outResources = stack.visitResources(inResources);
|
||||
if (!outResources.isEmpty()) {
|
||||
throw new AssertionError("Output resource is not empty");
|
||||
}
|
||||
@ -125,8 +126,9 @@ public class PluginsNegativeTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool inResources, ModulePool outResources) {
|
||||
// do nothing
|
||||
public ResourcePool transform(ResourcePool inResources, ResourcePoolBuilder outResources) {
|
||||
// don't add anything to the builder
|
||||
return outResources.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -42,13 +42,15 @@ 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.ModulePoolImpl;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
|
||||
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.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
|
||||
public class PrevisitorTest {
|
||||
|
||||
@ -67,13 +69,13 @@ public class PrevisitorTest {
|
||||
plugins.add(createPlugin(CustomPlugin.NAME));
|
||||
ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new Jlink.PluginsConfiguration(plugins,
|
||||
null, null));
|
||||
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);
|
||||
ResourcePoolManager inResources = new ResourcePoolManager(ByteOrder.nativeOrder(), new CustomStringTable());
|
||||
inResources.add(ResourcePoolEntry.create("/aaa/bbb/res1.class", new byte[90]));
|
||||
inResources.add(ResourcePoolEntry.create("/aaa/bbb/res2.class", new byte[90]));
|
||||
inResources.add(ResourcePoolEntry.create("/aaa/bbb/res3.class", new byte[90]));
|
||||
inResources.add(ResourcePoolEntry.create("/aaa/ddd/res1.class", new byte[90]));
|
||||
inResources.add(ResourcePoolEntry.create("/aaa/res1.class", new byte[90]));
|
||||
ResourcePool outResources = stack.visitResources(inResources);
|
||||
Collection<String> input = inResources.entries()
|
||||
.map(Object::toString)
|
||||
.collect(Collectors.toList());
|
||||
@ -113,19 +115,18 @@ public class PrevisitorTest {
|
||||
private boolean isPrevisitCalled = false;
|
||||
|
||||
@Override
|
||||
public void visit(ModulePool inResources, ModulePool outResources) {
|
||||
public ResourcePool transform(ResourcePool inResources, ResourcePoolBuilder outResources) {
|
||||
if (!isPrevisitCalled) {
|
||||
throw new AssertionError("Previsit was not called");
|
||||
}
|
||||
CustomStringTable table = (CustomStringTable)
|
||||
((ModulePoolImpl) inResources).getStringTable();
|
||||
CustomStringTable table = (CustomStringTable)((ResourcePoolImpl)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);
|
||||
Optional<ModuleEntry> e = inResources.findEntry(s);
|
||||
Optional<ResourcePoolEntry> e = inResources.findEntry(s);
|
||||
if (e.isPresent()) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
@ -139,6 +140,8 @@ public class PrevisitorTest {
|
||||
inResources.entries().forEach(r -> {
|
||||
outResources.add(r);
|
||||
});
|
||||
|
||||
return outResources.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -147,10 +150,10 @@ public class PrevisitorTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void previsit(ModulePool resources, StringTable strings) {
|
||||
public void previsit(ResourcePool resources, StringTable strings) {
|
||||
isPrevisitCalled = true;
|
||||
resources.entries().forEach(r -> {
|
||||
String s = r.getPath();
|
||||
String s = r.path();
|
||||
int lastIndexOf = s.lastIndexOf('/');
|
||||
if (lastIndexOf >= 0) {
|
||||
strings.addString(s.substring(0, lastIndexOf));
|
||||
|
@ -52,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.ModulePoolImpl;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
import jdk.tools.jlink.internal.StringTable;
|
||||
import jdk.tools.jlink.internal.plugins.StringSharingPlugin;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import tests.Helper;
|
||||
import tests.JImageValidator;
|
||||
@ -80,7 +80,7 @@ public class StringSharingPluginTest {
|
||||
Map<String, Integer> map = new HashMap<>();
|
||||
Map<Integer, String> reversedMap = new HashMap<>();
|
||||
|
||||
ModulePoolImpl resources = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() {
|
||||
ResourcePoolManager resources = new ResourcePoolManager(ByteOrder.nativeOrder(), new StringTable() {
|
||||
@Override
|
||||
public int addString(String str) {
|
||||
Integer id = map.get(str);
|
||||
@ -109,7 +109,7 @@ public class StringSharingPluginTest {
|
||||
if (path.charAt(0) != '/') {
|
||||
path = "/" + path;
|
||||
}
|
||||
ModuleEntry res = ModuleEntry.create(path, content);
|
||||
ResourcePoolEntry res = ResourcePoolEntry.create(path, content);
|
||||
resources.add(res);
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
@ -120,17 +120,17 @@ public class StringSharingPluginTest {
|
||||
stream.forEach(c);
|
||||
}
|
||||
Plugin plugin = new StringSharingPlugin();
|
||||
ModulePoolImpl result = new ModulePoolImpl(resources.getByteOrder(), resources.getStringTable());
|
||||
plugin.visit(resources, result);
|
||||
ResourcePoolManager resultMgr = new ResourcePoolManager(resources.byteOrder(), resources.getStringTable());
|
||||
ResourcePool result = plugin.transform(resources.resourcePool(), resultMgr.resourcePoolBuilder());
|
||||
|
||||
if (result.isEmpty()) {
|
||||
throw new AssertionError("No result");
|
||||
}
|
||||
|
||||
result.entries().forEach(res -> {
|
||||
if (res.getPath().endsWith(".class")) {
|
||||
if (res.path().endsWith(".class")) {
|
||||
try {
|
||||
byte[] uncompacted = StringSharingDecompressor.normalize(reversedMap::get, res.getBytes(),
|
||||
byte[] uncompacted = StringSharingDecompressor.normalize(reversedMap::get, res.contentBytes(),
|
||||
CompressedResourceHeader.getSize());
|
||||
JImageValidator.readClass(uncompacted);
|
||||
} catch (IOException exp) {
|
||||
|
@ -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.ModulePoolImpl;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
import jdk.tools.jlink.internal.plugins.StripDebugPlugin;
|
||||
import jdk.tools.jlink.plugin.ModuleEntry;
|
||||
import jdk.tools.jlink.plugin.ModulePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.Plugin;
|
||||
import tests.Helper;
|
||||
|
||||
@ -106,36 +106,38 @@ public class StripDebugPluginTest {
|
||||
path = path.replace('\\', '/');
|
||||
StripDebugPlugin debug = new StripDebugPlugin();
|
||||
debug.configure(new HashMap<>());
|
||||
ModuleEntry result1 = stripDebug(debug, ModuleEntry.create(path,content), path, infoPath, moduleInfo);
|
||||
ResourcePoolEntry result1 = stripDebug(debug, ResourcePoolEntry.create(path,content), path, infoPath, moduleInfo);
|
||||
|
||||
if (!path.endsWith("module-info.class")) {
|
||||
if (result1.getLength() >= content.length) {
|
||||
if (result1.contentLength() >= content.length) {
|
||||
throw new AssertionError("Class size not reduced, debug info not "
|
||||
+ "removed for " + path);
|
||||
}
|
||||
checkDebugAttributes(result1.getBytes());
|
||||
checkDebugAttributes(result1.contentBytes());
|
||||
}
|
||||
|
||||
ModuleEntry result2 = stripDebug(debug, result1, path, infoPath, moduleInfo);
|
||||
if (result1.getLength() != result2.getLength()) {
|
||||
ResourcePoolEntry result2 = stripDebug(debug, result1, path, infoPath, moduleInfo);
|
||||
if (result1.contentLength() != result2.contentLength()) {
|
||||
throw new AssertionError("removing debug info twice reduces class size of "
|
||||
+ path);
|
||||
}
|
||||
checkDebugAttributes(result1.getBytes());
|
||||
checkDebugAttributes(result1.contentBytes());
|
||||
}
|
||||
|
||||
private ModuleEntry stripDebug(Plugin debug, ModuleEntry classResource,
|
||||
private ResourcePoolEntry stripDebug(Plugin debug, ResourcePoolEntry classResource,
|
||||
String path, String infoPath, byte[] moduleInfo) throws Exception {
|
||||
ModulePool resources = new ModulePoolImpl();
|
||||
ResourcePoolManager resources = new ResourcePoolManager();
|
||||
resources.add(classResource);
|
||||
if (!path.endsWith("module-info.class")) {
|
||||
ModuleEntry res2 = ModuleEntry.create(infoPath, moduleInfo);
|
||||
ResourcePoolEntry res2 = ResourcePoolEntry.create(infoPath, moduleInfo);
|
||||
resources.add(res2);
|
||||
}
|
||||
ModulePool results = new ModulePoolImpl();
|
||||
debug.visit(resources, results);
|
||||
System.out.println(classResource.getPath());
|
||||
return results.findEntry(classResource.getPath()).get();
|
||||
ResourcePoolManager results = new ResourcePoolManager();
|
||||
ResourcePool resPool = debug.transform(resources.resourcePool(),
|
||||
results.resourcePoolBuilder());
|
||||
System.out.println(classResource.path());
|
||||
|
||||
return resPool.findEntry(classResource.path()).get();
|
||||
}
|
||||
|
||||
private void checkDebugAttributes(byte[] strippedClassFile) throws IOException, ConstantPoolException {
|
||||
|
Loading…
Reference in New Issue
Block a user