8171138: Remove FileCopierPlugin

Reviewed-by: mchung, jlaskey
This commit is contained in:
Athijegannathan Sundararajan 2016-12-15 10:47:46 +05:30
parent b140a35684
commit 0273a6202d
8 changed files with 6 additions and 482 deletions

View File

@ -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:

View File

@ -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());
}
}
}

View File

@ -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);
}
}

View File

@ -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
}
/**

View File

@ -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=\

View File

@ -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,

View File

@ -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();

View File

@ -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"));
}
}