8192986: Inconsistent handling of exploded modules in jlink

Reviewed-by: redestad, jlaskey
This commit is contained in:
Athijegannathan Sundararajan 2017-12-08 20:46:40 +05:30
parent 93aa3ae4d7
commit b93586c51e
7 changed files with 143 additions and 15 deletions

View File

@ -267,15 +267,17 @@ public final class DefaultImageBuilder implements ImageBuilder {
assert !mainClassName.isEmpty();
}
String path = "/" + module + "/module-info.class";
Optional<ResourcePoolEntry> res = imageContent.findEntry(path);
if (!res.isPresent()) {
throw new IOException("module-info.class not found for " + module + " module");
}
ByteArrayInputStream stream = new ByteArrayInputStream(res.get().contentBytes());
Optional<String> mainClass = ModuleDescriptor.read(stream).mainClass();
if (mainClassName == null && mainClass.isPresent()) {
mainClassName = mainClass.get();
if (mainClassName == null) {
String path = "/" + module + "/module-info.class";
Optional<ResourcePoolEntry> res = imageContent.findEntry(path);
if (!res.isPresent()) {
throw new IOException("module-info.class not found for " + module + " module");
}
ByteArrayInputStream stream = new ByteArrayInputStream(res.get().contentBytes());
Optional<String> mainClass = ModuleDescriptor.read(stream).mainClass();
if (mainClass.isPresent()) {
mainClassName = mainClass.get();
}
}
if (mainClassName != null) {

View File

@ -85,17 +85,17 @@ public class DirArchive implements Archive {
private static final Consumer<String> noopConsumer = (String t) -> {
};
public DirArchive(Path dirPath) {
this(dirPath, noopConsumer);
public DirArchive(Path dirPath, String moduleName) {
this(dirPath, moduleName, noopConsumer);
}
public DirArchive(Path dirPath, Consumer<String> log) {
public DirArchive(Path dirPath, String moduleName, Consumer<String> log) {
Objects.requireNonNull(dirPath);
if (!Files.isDirectory(dirPath)) {
throw new IllegalArgumentException(dirPath + " is not a directory");
}
chop = dirPath.toString().length() + 1;
this.moduleName = Objects.requireNonNull(dirPath.getFileName()).toString();
this.moduleName = Objects.requireNonNull(moduleName);
this.dirPath = dirPath;
this.log = log;
}

View File

@ -24,6 +24,7 @@
*/
package jdk.tools.jlink.internal;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
@ -824,13 +825,29 @@ public class JlinkTask {
return modularJarArchive;
} else if (Files.isDirectory(path)) {
return new DirArchive(path);
Path modInfoPath = path.resolve("module-info.class");
if (Files.isRegularFile(modInfoPath)) {
return new DirArchive(path, findModuleName(modInfoPath));
} else {
throw new IllegalArgumentException(
taskHelper.getMessage("err.not.a.module.directory", path));
}
} else {
throw new IllegalArgumentException(
taskHelper.getMessage("err.not.modular.format", module, path));
}
}
private static String findModuleName(Path modInfoPath) {
try (BufferedInputStream bis = new BufferedInputStream(
Files.newInputStream(modInfoPath))) {
return ModuleDescriptor.read(bis).name();
} catch (IOException exp) {
throw new IllegalArgumentException(taskHelper.getMessage(
"err.cannot.read.module.info", modInfoPath), exp);
}
}
@Override
public ExecutableImage retrieve(ImagePluginStack stack) throws IOException {
ExecutableImage image = ImageFileCreator.create(archives, order, stack);

View File

@ -135,6 +135,8 @@ err.orphan.arguments=invalid argument: {0}
err.config.defaults=property {0} is missing from configuration
err.config.defaults.value=wrong value in defaults property: {0}
err.bom.generation=bom file generation failed: {0}
err.not.a.module.directory=directory {0} does not contain module-info.class file under it
err.cannot.read.module.info=cannot read module descriptor from {0}
err.not.modular.format=selected module {0} ({1}) not in jmod or modular JAR format
err.signing=signed modular JAR {0} is currently not supported,\
\ use --ignore-signing-information to suppress error

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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.
*/
import java.io.IOException;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.Files;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.util.spi.ToolProvider;
import tests.Helper;
import tests.JImageGenerator;
import tests.Result;
/*
* @test
* @bug 8192986
* @summary Inconsistent handling of exploded modules in jlink
* @library ../lib
* @modules java.base/jdk.internal.jimage
* jdk.jdeps/com.sun.tools.classfile
* jdk.jlink/jdk.tools.jlink.internal
* jdk.jlink/jdk.tools.jmod
* jdk.jlink/jdk.tools.jimage
* jdk.compiler
* @build tests.*
* @run main ExplodedModuleNameTest
*/
public class ExplodedModuleNameTest {
static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
.orElseThrow(() ->
new RuntimeException("jlink tool not found")
);
public static void main(String[] args) throws Exception {
Helper helper = Helper.newHelper();
if (helper == null) {
System.err.println("Test not run");
return;
}
// generate a new exploded module
String modName = "mod8192986";
Path modDir = helper.generateDefaultExplodedModule(modName).getFile();
// rename the module containing directory
Path renamedModDir = modDir.resolveSibling("modified_mod8192986");
// copy the content from original directory to modified name directory
copyDir(modDir, renamedModDir);
Path outputDir = helper.createNewImageDir("image8192986");
JImageGenerator.getJLinkTask()
.modulePath(renamedModDir.toAbsolutePath().toString())
.output(outputDir)
.addMods(modName)
.launcher(modName + "=" + modName + "/" + modName +".Main")
.call().assertSuccess();
}
private static void copyDir(Path srcDir, Path destDir) throws IOException {
Files.walkFileTree(srcDir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
Path target = destDir.resolve(srcDir.relativize(dir));
Files.createDirectory(target);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.copy(file, destDir.resolve(srcDir.relativize(file)));
return FileVisitResult.CONTINUE;
}
});
}
}

View File

@ -219,7 +219,7 @@ public class Helper {
generateModuleCompiledClasses(explodedmodssrc, explodedmodsclasses,
moduleName, classNames, dependencies);
Path dir = explodedmods.resolve(moduleName);
Path dir = explodedmods.resolve("classes").resolve(moduleName);
return new Result(0, "", dir);
}

View File

@ -110,6 +110,7 @@ public class JImageGenerator {
private static final String ADD_MODULES_OPTION = "--add-modules";
private static final String LIMIT_MODULES_OPTION = "--limit-modules";
private static final String PLUGIN_MODULE_PATH = "--plugin-module-path";
private static final String LAUNCHER = "--launcher";
private static final String CMDS_OPTION = "--cmds";
private static final String CONFIG_OPTION = "--config";
@ -579,12 +580,18 @@ public class JImageGenerator {
private String repeatedLimitMods;
private Path output;
private Path existing;
private String launcher; // optional
public JLinkTask modulePath(String modulePath) {
this.modulePath = modulePath;
return this;
}
public JLinkTask launcher(String cmd) {
launcher = Objects.requireNonNull(cmd);
return this;
}
public JLinkTask repeatedModulePath(String modulePath) {
this.repeatedModulePath = modulePath;
return this;
@ -682,6 +689,10 @@ public class JImageGenerator {
options.add(PLUGIN_MODULE_PATH);
options.add(toPath(pluginModulePath));
}
if (launcher != null && !launcher.isEmpty()) {
options.add(LAUNCHER);
options.add(launcher);
}
options.addAll(this.options);
return options.toArray(new String[options.size()]);
}