8171138: Remove FileCopierPlugin
Reviewed-by: mchung, jlaskey
This commit is contained in:
parent
b140a35684
commit
0273a6202d
@ -58,7 +58,6 @@ import java.util.Set;
|
||||
import static java.util.stream.Collectors.*;
|
||||
|
||||
import jdk.tools.jlink.internal.BasicImageWriter;
|
||||
import jdk.tools.jlink.internal.plugins.FileCopierPlugin.SymImageFile;
|
||||
import jdk.tools.jlink.internal.ExecutableImage;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
@ -149,20 +148,6 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
Files.createDirectories(mdir);
|
||||
}
|
||||
|
||||
private void storeRelease(ResourcePool pool) throws IOException {
|
||||
Properties props = new Properties();
|
||||
Optional<ResourcePoolEntry> release = pool.findEntry("/java.base/release");
|
||||
if (release.isPresent()) {
|
||||
try (InputStream is = release.get().content()) {
|
||||
props.load(is);
|
||||
}
|
||||
}
|
||||
File r = new File(root.toFile(), "release");
|
||||
try (FileOutputStream fo = new FileOutputStream(r)) {
|
||||
props.store(fo, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeFiles(ResourcePool files) {
|
||||
try {
|
||||
@ -180,9 +165,6 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
throw new PluginException("TargetPlatform attribute is missing for java.base module");
|
||||
}
|
||||
|
||||
// store 'release' file
|
||||
storeRelease(files);
|
||||
|
||||
Path bin = root.resolve(BIN_DIRNAME);
|
||||
|
||||
// check any duplicated resource files
|
||||
@ -373,8 +355,6 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
return Paths.get(LEGAL_DIRNAME, entryToFileName(entry));
|
||||
case TOP:
|
||||
return Paths.get(entryToFileName(entry));
|
||||
case OTHER:
|
||||
return Paths.get("other", entryToFileName(entry));
|
||||
default:
|
||||
throw new IllegalArgumentException("invalid type: " + entry);
|
||||
}
|
||||
@ -412,19 +392,11 @@ public final class DefaultImageBuilder implements ImageBuilder {
|
||||
}
|
||||
break;
|
||||
case TOP:
|
||||
break;
|
||||
case OTHER:
|
||||
String filename = entryToFileName(file);
|
||||
if (file instanceof SymImageFile) {
|
||||
SymImageFile sym = (SymImageFile) file;
|
||||
Path target = root.resolve(sym.getTargetPath());
|
||||
if (!Files.exists(target)) {
|
||||
throw new IOException("Sym link target " + target
|
||||
+ " doesn't exist");
|
||||
}
|
||||
writeSymEntry(root.resolve(filename), target);
|
||||
// Copy TOP files of the "java.base" module (only)
|
||||
if ("java.base".equals(file.moduleName())) {
|
||||
writeEntry(in, root.resolve(entryToImagePath(file)));
|
||||
} else {
|
||||
writeEntry(in, root.resolve(filename));
|
||||
throw new InternalError("unexpected TOP entry: " + file.path());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -80,7 +80,7 @@ final class ArchiveEntryResourcePoolEntry extends AbstractResourcePoolEntry {
|
||||
case NATIVE_LIB:
|
||||
return Type.NATIVE_LIB;
|
||||
default:
|
||||
return ResourcePoolEntry.Type.OTHER;
|
||||
throw new IllegalArgumentException("Unknown archive entry type: " + entry.type());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,263 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package jdk.tools.jlink.internal.plugins;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.FileVisitor;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import jdk.tools.jlink.internal.PathResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
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;
|
||||
|
||||
/**
|
||||
*
|
||||
* Copy files to image from various locations.
|
||||
*/
|
||||
public class FileCopierPlugin implements Plugin {
|
||||
|
||||
public static final String NAME = "copy-files";
|
||||
|
||||
private static final class CopiedFile {
|
||||
|
||||
Path source;
|
||||
Path target;
|
||||
}
|
||||
private final List<CopiedFile> files = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Symbolic link to another path.
|
||||
*/
|
||||
public static abstract class SymImageFile extends PathResourcePoolEntry {
|
||||
|
||||
private final String targetPath;
|
||||
|
||||
public SymImageFile(String targetPath, String module, String path,
|
||||
ResourcePoolEntry.Type type, Path file) {
|
||||
super(module, path, type, file);
|
||||
this.targetPath = targetPath;
|
||||
}
|
||||
|
||||
public String getTargetPath() {
|
||||
return targetPath;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class SymImageFileImpl extends SymImageFile {
|
||||
|
||||
public SymImageFileImpl(String targetPath, Path file, String module,
|
||||
String path, ResourcePoolEntry.Type type) {
|
||||
super(targetPath, module, path, type, file);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class DirectoryCopy implements FileVisitor<Path> {
|
||||
|
||||
private final Path source;
|
||||
private final ResourcePoolBuilder pool;
|
||||
private final String targetDir;
|
||||
private final List<SymImageFile> symlinks = new ArrayList<>();
|
||||
|
||||
DirectoryCopy(Path source, ResourcePoolBuilder pool, String targetDir) {
|
||||
this.source = source;
|
||||
this.pool = pool;
|
||||
this.targetDir = targetDir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path dir,
|
||||
BasicFileAttributes attrs) throws IOException {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file,
|
||||
BasicFileAttributes attrs) throws IOException {
|
||||
Objects.requireNonNull(file);
|
||||
Objects.requireNonNull(attrs);
|
||||
String path = targetDir + "/" + source.relativize(file);
|
||||
if (attrs.isSymbolicLink()) {
|
||||
Path symTarget = Files.readSymbolicLink(file);
|
||||
if (!Files.exists(symTarget)) {
|
||||
// relative to file parent?
|
||||
Path parent = file.getParent();
|
||||
if (parent != null) {
|
||||
symTarget = parent.resolve(symTarget);
|
||||
}
|
||||
}
|
||||
if (!Files.exists(symTarget)) {
|
||||
System.err.println("WARNING: Skipping sym link, target "
|
||||
+ Files.readSymbolicLink(file) + "not found");
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
SymImageFileImpl impl = new SymImageFileImpl(symTarget.toString(),
|
||||
file, path, Objects.requireNonNull(file.getFileName()).toString(),
|
||||
ResourcePoolEntry.Type.OTHER);
|
||||
symlinks.add(impl);
|
||||
} else {
|
||||
addFile(pool, file, path);
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc)
|
||||
throws IOException {
|
||||
if (exc != null) {
|
||||
throw exc;
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFileFailed(Path file, IOException exc)
|
||||
throws IOException {
|
||||
throw exc;
|
||||
}
|
||||
}
|
||||
|
||||
private static void addFile(ResourcePoolBuilder pool, Path file, String path)
|
||||
throws IOException {
|
||||
Objects.requireNonNull(pool);
|
||||
Objects.requireNonNull(file);
|
||||
Objects.requireNonNull(path);
|
||||
ResourcePoolEntry impl = ResourcePoolEntry.create(
|
||||
"/java.base/other/" + path,
|
||||
ResourcePoolEntry.Type.OTHER, file);
|
||||
try {
|
||||
pool.add(impl);
|
||||
} catch (Exception ex) {
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(Map<String, String> config) {
|
||||
List<String> arguments = Utils.parseList(config.get(NAME));
|
||||
if (arguments.isEmpty()) {
|
||||
throw new RuntimeException("Invalid argument for " + NAME);
|
||||
}
|
||||
|
||||
String javahome = System.getProperty("java.home");
|
||||
for (String a : arguments) {
|
||||
int i = a.indexOf("=");
|
||||
CopiedFile cf = new CopiedFile();
|
||||
if (i == -1) {
|
||||
Path file = Paths.get(a);
|
||||
if (file.isAbsolute()) {
|
||||
cf.source = file;
|
||||
// The target is the image root directory.
|
||||
cf.target = file.getFileName();
|
||||
} else {
|
||||
file = new File(javahome, a).toPath();
|
||||
cf.source = file;
|
||||
cf.target = Paths.get(a);
|
||||
}
|
||||
} else {
|
||||
String target = a.substring(i + 1);
|
||||
String f = a.substring(0, i);
|
||||
Path file = Paths.get(f);
|
||||
if (file.isAbsolute()) {
|
||||
cf.source = file;
|
||||
} else {
|
||||
cf.source = new File(javahome,
|
||||
file.toFile().getPath()).toPath();
|
||||
}
|
||||
cf.target = Paths.get(target);
|
||||
}
|
||||
if (!Files.exists(cf.source)) {
|
||||
System.err.println("Skipping file " + cf.source
|
||||
+ ", it doesn't exist");
|
||||
} else {
|
||||
files.add(cf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
|
||||
in.transformAndCopy((file) -> {
|
||||
return file;
|
||||
}, out);
|
||||
|
||||
// Add new files.
|
||||
try {
|
||||
for (CopiedFile file : files) {
|
||||
if (Files.isRegularFile(file.source)) {
|
||||
addFile(out, file.source, file.target.toString());
|
||||
} else if (Files.isDirectory(file.source)) {
|
||||
DirectoryCopy dc = new DirectoryCopy(file.source,
|
||||
out, file.target.toString());
|
||||
Files.walkFileTree(file.source, dc);
|
||||
// Add symlinks after actual content
|
||||
for (SymImageFile imf : dc.symlinks) {
|
||||
try {
|
||||
out.add(imf);
|
||||
} catch (Exception ex) {
|
||||
throw new PluginException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new UncheckedIOException(ex);
|
||||
}
|
||||
|
||||
return out.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return PluginsResourceBundle.getDescription(NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasArguments() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgumentsDescription() {
|
||||
return PluginsResourceBundle.getArgument(NAME);
|
||||
}
|
||||
}
|
@ -58,7 +58,6 @@ public interface ResourcePoolEntry {
|
||||
* <ul>NATIVE_CMD: A native executable launcher.</ul>
|
||||
* <ul>NATIVE_LIB: A native library.</ul>
|
||||
* <ul>TOP: A top-level file in the jdk run-time image directory.</ul>
|
||||
* <ul>OTHER: Other kind of file.</ul>
|
||||
* </li>
|
||||
*/
|
||||
public enum Type {
|
||||
@ -69,8 +68,7 @@ public interface ResourcePoolEntry {
|
||||
MAN_PAGE,
|
||||
NATIVE_CMD,
|
||||
NATIVE_LIB,
|
||||
TOP,
|
||||
OTHER
|
||||
TOP
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,12 +52,6 @@ compact-cp.description=Constant Pool strings sharing.\n\
|
||||
By default, all resources are compressed. You can express the set \n\
|
||||
of resources to compress or not compress (use ^ for negation).
|
||||
|
||||
copy-files.argument=<List of <file path>=<image target> to copy to the image>.
|
||||
|
||||
copy-files.description=\
|
||||
If files to copy are not absolute path, JDK home dir is used.\n\
|
||||
e.g.: /home/me/myfile.txt=somewhere/conf.txt
|
||||
|
||||
dedup-legal-notices.argument=[error-if-not-same-content]
|
||||
|
||||
dedup-legal-notices.description=\
|
||||
|
@ -36,7 +36,6 @@ module jdk.jlink {
|
||||
jdk.tools.jlink.internal.Main.JlinkToolProvider;
|
||||
|
||||
provides jdk.tools.jlink.plugin.Plugin with
|
||||
jdk.tools.jlink.internal.plugins.FileCopierPlugin,
|
||||
jdk.tools.jlink.internal.plugins.StripDebugPlugin,
|
||||
jdk.tools.jlink.internal.plugins.ExcludePlugin,
|
||||
jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin,
|
||||
|
@ -190,19 +190,6 @@ public class JLinkTest {
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// License files
|
||||
Path file = Paths.get("LICENSE");
|
||||
Files.createFile(file);
|
||||
String copied = "LICENSE";
|
||||
String[] arr = copied.split(",");
|
||||
String[] copyFiles = new String[2];
|
||||
copyFiles[0] = "--copy-files";
|
||||
copyFiles[1] = file.toAbsolutePath().toString();
|
||||
Path imageDir = helper.generateDefaultImage(copyFiles, "composite2").assertSuccess();
|
||||
helper.checkImage(imageDir, "composite2", null, null, arr);
|
||||
}
|
||||
|
||||
{
|
||||
// List plugins
|
||||
StringWriter writer = new StringWriter();
|
||||
|
@ -1,163 +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 files copy plugin
|
||||
* @author Jean-Francois Denise
|
||||
* @modules jdk.jlink/jdk.tools.jlink.internal
|
||||
* jdk.jlink/jdk.tools.jlink.builder
|
||||
* jdk.jlink/jdk.tools.jlink.internal.plugins
|
||||
* @run main FileCopierPluginTest
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import jdk.tools.jlink.internal.ResourcePoolManager;
|
||||
import jdk.tools.jlink.builder.DefaultImageBuilder;
|
||||
|
||||
import jdk.tools.jlink.internal.plugins.FileCopierPlugin;
|
||||
import jdk.tools.jlink.plugin.PluginException;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolEntry;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
|
||||
public class FileCopierPluginTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new FileCopierPluginTest().test();
|
||||
}
|
||||
|
||||
/**
|
||||
* 3 cases - Absolute, no target ==> copy in image root dir - Absolute and
|
||||
* target ==> copy in image root dir/target - Relative ==> copy from JDK
|
||||
* home dir.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void test() throws Exception {
|
||||
FileCopierPlugin plug = new FileCopierPlugin();
|
||||
String content = "You \n should \n be \bthere.\n";
|
||||
String name = "sample.txt";
|
||||
File src = new File("src");
|
||||
src.mkdir();
|
||||
// Need a fake bin
|
||||
File bin = new File("bin");
|
||||
bin.mkdir();
|
||||
|
||||
File txt = new File(src, name);
|
||||
txt.createNewFile();
|
||||
|
||||
String target = "target" + File.separator + name;
|
||||
Files.write(txt.toPath(), content.getBytes());
|
||||
File lic = new File(System.getProperty("java.home"), "LICENSE.txt");
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int expected = lic.exists() ? 4 : 3;
|
||||
if (lic.exists()) {
|
||||
builder.append("LICENSE.txt,");
|
||||
}
|
||||
builder.append(txt.getAbsolutePath()+",");
|
||||
builder.append(txt.getAbsolutePath() + "=" + target+",");
|
||||
builder.append(src.getAbsolutePath() + "=src2");
|
||||
|
||||
Map<String, String> conf = new HashMap<>();
|
||||
conf.put(FileCopierPlugin.NAME, builder.toString());
|
||||
plug.configure(conf);
|
||||
ResourcePoolManager poolMgr = new ResourcePoolManager();
|
||||
// java.base/module-info.class is used to add "release" file
|
||||
// We read it from jrt-fs and add a ResourcePoolEntry
|
||||
poolMgr.add(
|
||||
ResourcePoolEntry.create("/java.base/module-info.class",
|
||||
ResourcePoolEntry.Type.CLASS_OR_RESOURCE, getJavaBaseModuleInfo()));
|
||||
expected++;
|
||||
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.type().equals(ResourcePoolEntry.Type.OTHER) &&
|
||||
!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
|
||||
throw new AssertionError("Invalid type " + f.type()
|
||||
+ " for file " + f.path());
|
||||
}
|
||||
if (f.content() == null) {
|
||||
throw new AssertionError("Null stream for file " + f.path());
|
||||
}
|
||||
});
|
||||
Path root = new File(".").toPath();
|
||||
DefaultImageBuilder imgbuilder = new DefaultImageBuilder(root);
|
||||
imgbuilder.storeFiles(pool);
|
||||
|
||||
if (lic.exists()) {
|
||||
File license = new File(root.toFile(), "LICENSE.txt");
|
||||
if (!license.exists() || license.length() == 0) {
|
||||
throw new AssertionError("Invalid license file "
|
||||
+ license.getAbsoluteFile());
|
||||
}
|
||||
}
|
||||
|
||||
File sample1 = new File(root.toFile(), txt.getName());
|
||||
if (!sample1.exists() || sample1.length() == 0) {
|
||||
throw new AssertionError("Invalide sample1 file "
|
||||
+ sample1.getAbsoluteFile());
|
||||
}
|
||||
if (!new String(Files.readAllBytes(sample1.toPath())).equals(content)) {
|
||||
throw new AssertionError("Invalid Content in sample1");
|
||||
}
|
||||
|
||||
File sample2 = new File(root.toFile(), target);
|
||||
if (!sample2.exists() || sample2.length() == 0) {
|
||||
throw new AssertionError("Invalide sample2 file "
|
||||
+ sample2.getAbsoluteFile());
|
||||
}
|
||||
if (!new String(Files.readAllBytes(sample2.toPath())).equals(content)) {
|
||||
throw new AssertionError("Invalid Content in sample2");
|
||||
}
|
||||
|
||||
File src2 = new File(root.toFile(), "src2");
|
||||
if (!src2.exists() || src2.list().length != 1) {
|
||||
throw new AssertionError("Invalide src2 dir "
|
||||
+ src2.getAbsoluteFile());
|
||||
}
|
||||
File f = src2.listFiles()[0];
|
||||
if (!f.getName().equals(txt.getName())) {
|
||||
throw new AssertionError("Invalide file name in src2 dir "
|
||||
+ f.getAbsoluteFile());
|
||||
}
|
||||
if (!new String(Files.readAllBytes(f.toPath())).equals(content)) {
|
||||
throw new AssertionError("Invalid Content in src2 dir");
|
||||
}
|
||||
}
|
||||
|
||||
// read java.base/module-info.class from jrt-fs
|
||||
private static Path getJavaBaseModuleInfo() {
|
||||
return Paths.get(URI.create("jrt:/modules/java.base/module-info.class"));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user