Categories:
Audio (13)
Biotech (29)
Bytecode (36)
Database (77)
Framework (7)
Game (7)
General (507)
Graphics (53)
I/O (35)
IDE (2)
JAR Tools (102)
JavaBeans (21)
JDBC (121)
JDK (426)
JSP (20)
Logging (108)
Mail (58)
Messaging (8)
Network (84)
PDF (97)
Report (7)
Scripting (84)
Security (32)
Server (121)
Servlet (26)
SOAP (24)
Testing (54)
Web (15)
XML (322)
Collections:
Other Resources:
JDK 17 jdk.jlink.jmod - JLink Tool
JDK 17 jdk.jlink.jmod is the JMOD file for JDK 17 JLink tool,
which can be invoked by the "jlink" command.
JDK 17 JLink tool compiled class files are stored in \fyicenter\jdk-17.0.5\jmods\jdk.jlink.jmod.
JDK 17 JLink tool compiled class files are also linked and stored in the \fyicenter\jdk-17.0.5\lib\modules JImage file.
JDK 17 JLink tool source code files are stored in \fyicenter\jdk-17.0.5\lib\src.zip\jdk.jlink.
You can click and view the content of each source code file in the list below.
✍: FYIcenter
⏎ jdk/tools/jlink/builder/DefaultImageBuilder.java
/*
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package jdk.tools.jlink.builder;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.lang.module.ModuleDescriptor;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import jdk.tools.jlink.internal.BasicImageWriter;
import jdk.tools.jlink.internal.ExecutableImage;
import jdk.tools.jlink.internal.Platform;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.ResourcePoolEntry.Type;
import jdk.tools.jlink.plugin.ResourcePoolModule;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toSet;
/**
*
* Default Image Builder. This builder creates the default runtime image layout.
*/
public final class DefaultImageBuilder implements ImageBuilder {
// Top-level directory names in a modular runtime image
public static final String BIN_DIRNAME = "bin";
public static final String CONF_DIRNAME = "conf";
public static final String INCLUDE_DIRNAME = "include";
public static final String LIB_DIRNAME = "lib";
public static final String LEGAL_DIRNAME = "legal";
public static final String MAN_DIRNAME = "man";
/**
* The default java executable Image.
*/
static final class DefaultExecutableImage implements ExecutableImage {
private final Path home;
private final List<String> args;
private final Set<String> modules;
DefaultExecutableImage(Path home, Set<String> modules) {
Objects.requireNonNull(home);
if (!Files.exists(home)) {
throw new IllegalArgumentException("Invalid image home");
}
this.home = home;
this.modules = Collections.unmodifiableSet(modules);
this.args = createArgs(home);
}
private static List<String> createArgs(Path home) {
Objects.requireNonNull(home);
Path binDir = home.resolve("bin");
String java = Files.exists(binDir.resolve("java"))? "java" : "java.exe";
return List.of(binDir.resolve(java).toString());
}
@Override
public Path getHome() {
return home;
}
@Override
public Set<String> getModules() {
return modules;
}
@Override
public List<String> getExecutionArgs() {
return args;
}
@Override
public void storeLaunchArgs(List<String> args) {
try {
patchScripts(this, args);
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
}
private final Path root;
private final Map<String, String> launchers;
private final Path mdir;
private final Set<String> modules = new HashSet<>();
private Platform targetPlatform;
/**
* Default image builder constructor.
*
* @param root The image root directory.
* @throws IOException
*/
public DefaultImageBuilder(Path root, Map<String, String> launchers) throws IOException {
this.root = Objects.requireNonNull(root);
this.launchers = Objects.requireNonNull(launchers);
this.mdir = root.resolve("lib");
Files.createDirectories(mdir);
}
@Override
public void storeFiles(ResourcePool files) {
try {
String value = files.moduleView()
.findModule("java.base")
.map(ResourcePoolModule::targetPlatform)
.orElse(null);
if (value == null) {
throw new PluginException("ModuleTarget attribute is missing for java.base module");
}
this.targetPlatform = Platform.toPlatform(value);
checkResourcePool(files);
Path bin = root.resolve(BIN_DIRNAME);
// write non-classes resource files to the image
files.entries()
.filter(f -> f.type() != ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
.forEach(f -> {
try {
accept(f);
} catch (FileAlreadyExistsException e) {
// Should not happen! Duplicates checking already done!
throw new AssertionError("Duplicate entry!", e);
} catch (IOException ioExp) {
throw new UncheckedIOException(ioExp);
}
});
files.moduleView().modules().forEach(m -> {
// Only add modules that contain packages
if (!m.packages().isEmpty()) {
modules.add(m.name());
}
});
if (root.getFileSystem().supportedFileAttributeViews()
.contains("posix")) {
// launchers in the bin directory need execute permission.
// On Windows, "bin" also subdirectories containing jvm.dll.
if (Files.isDirectory(bin)) {
Files.find(bin, 2, (path, attrs) -> {
return attrs.isRegularFile() && !path.toString().endsWith(".diz");
}).forEach(this::setExecutable);
}
// jspawnhelper is in lib or lib/<arch>
Path lib = root.resolve(LIB_DIRNAME);
if (Files.isDirectory(lib)) {
Files.find(lib, 2, (path, attrs) -> {
return path.getFileName().toString().equals("jspawnhelper")
|| path.getFileName().toString().equals("jexec");
}).forEach(this::setExecutable);
}
// read-only legal notices/license files
Path legal = root.resolve(LEGAL_DIRNAME);
if (Files.isDirectory(legal)) {
Files.find(legal, 2, (path, attrs) -> {
return attrs.isRegularFile();
}).forEach(this::setReadOnly);
}
}
// If native files are stripped completely, <root>/bin dir won't exist!
// So, don't bother generating launcher scripts.
if (Files.isDirectory(bin)) {
prepareApplicationFiles(files);
}
} catch (IOException ex) {
throw new PluginException(ex);
}
}
private void checkResourcePool(ResourcePool pool) {
// For now, only duplicate resources check. Add more checks here (if any)
checkDuplicateResources(pool);
}
private void checkDuplicateResources(ResourcePool pool) {
// check any duplicated resources
Map<Path, Set<String>> duplicates = new HashMap<>();
pool.entries()
.filter(f -> f.type() != ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
.collect(groupingBy(this::entryToImagePath,
mapping(ResourcePoolEntry::moduleName, toSet())))
.entrySet()
.stream()
.filter(e -> e.getValue().size() > 1)
.forEach(e -> duplicates.put(e.getKey(), e.getValue()));
if (!duplicates.isEmpty()) {
throw new PluginException("Duplicate resources: " + duplicates);
}
}
/**
* Generates launcher scripts.
*
* @param imageContent The image content.
* @throws IOException
*/
protected void prepareApplicationFiles(ResourcePool imageContent) throws IOException {
// generate launch scripts for the modules with a main class
for (Map.Entry<String, String> entry : launchers.entrySet()) {
String launcherEntry = entry.getValue();
int slashIdx = launcherEntry.indexOf("/");
String module, mainClassName;
if (slashIdx == -1) {
module = launcherEntry;
mainClassName = null;
} else {
module = launcherEntry.substring(0, slashIdx);
assert !module.isEmpty();
mainClassName = launcherEntry.substring(slashIdx + 1);
assert !mainClassName.isEmpty();
}
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) {
// make sure main class exists!
if (!imageContent.findEntry("/" + module + "/" +
mainClassName.replace('.', '/') + ".class").isPresent()) {
throw new IllegalArgumentException(module + " does not have main class: " + mainClassName);
}
String launcherFile = entry.getKey();
Path cmd = root.resolve("bin").resolve(launcherFile);
// generate shell script for Unix platforms
StringBuilder sb = new StringBuilder();
sb.append("#!/bin/sh")
.append("\n");
sb.append("JLINK_VM_OPTIONS=")
.append("\n");
sb.append("DIR=`dirname $0`")
.append("\n");
sb.append("$DIR/java $JLINK_VM_OPTIONS -m ")
.append(module).append('/')
.append(mainClassName)
.append(" \"$@\"\n");
try (BufferedWriter writer = Files.newBufferedWriter(cmd,
StandardCharsets.ISO_8859_1,
StandardOpenOption.CREATE_NEW)) {
writer.write(sb.toString());
}
if (root.resolve("bin").getFileSystem()
.supportedFileAttributeViews().contains("posix")) {
setExecutable(cmd);
}
// generate .bat file for Windows
if (isWindows()) {
Path bat = root.resolve(BIN_DIRNAME).resolve(launcherFile + ".bat");
sb = new StringBuilder();
sb.append("@echo off")
.append("\r\n");
sb.append("set JLINK_VM_OPTIONS=")
.append("\r\n");
sb.append("set DIR=%~dp0")
.append("\r\n");
sb.append("\"%DIR%\\java\" %JLINK_VM_OPTIONS% -m ")
.append(module).append('/')
.append(mainClassName)
.append(" %*\r\n");
try (BufferedWriter writer = Files.newBufferedWriter(bat,
StandardCharsets.ISO_8859_1,
StandardOpenOption.CREATE_NEW)) {
writer.write(sb.toString());
}
}
} else {
throw new IllegalArgumentException(module + " doesn't contain main class & main not specified in command line");
}
}
}
@Override
public DataOutputStream getJImageOutputStream() {
try {
Path jimageFile = mdir.resolve(BasicImageWriter.MODULES_IMAGE_NAME);
OutputStream fos = Files.newOutputStream(jimageFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
return new DataOutputStream(bos);
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
/**
* Returns the file name of this entry
*/
private String entryToFileName(ResourcePoolEntry entry) {
if (entry.type() == ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
throw new IllegalArgumentException("invalid type: " + entry);
String module = "/" + entry.moduleName() + "/";
String filename = entry.path().substring(module.length());
// Remove radical lib|config|...
return filename.substring(filename.indexOf('/') + 1);
}
/**
* Returns the path of the given entry to be written in the image
*/
private Path entryToImagePath(ResourcePoolEntry entry) {
switch (entry.type()) {
case NATIVE_LIB:
String filename = entryToFileName(entry);
return Paths.get(nativeDir(filename), filename);
case NATIVE_CMD:
return Paths.get(BIN_DIRNAME, entryToFileName(entry));
case CONFIG:
return Paths.get(CONF_DIRNAME, entryToFileName(entry));
case HEADER_FILE:
return Paths.get(INCLUDE_DIRNAME, entryToFileName(entry));
case MAN_PAGE:
return Paths.get(MAN_DIRNAME, entryToFileName(entry));
case LEGAL_NOTICE:
return Paths.get(LEGAL_DIRNAME, entryToFileName(entry));
case TOP:
return Paths.get(entryToFileName(entry));
default:
throw new IllegalArgumentException("invalid type: " + entry);
}
}
private void accept(ResourcePoolEntry file) throws IOException {
if (file.linkedTarget() != null && file.type() != Type.LEGAL_NOTICE) {
throw new UnsupportedOperationException("symbolic link not implemented: " + file);
}
try (InputStream in = file.content()) {
switch (file.type()) {
case NATIVE_LIB:
Path dest = root.resolve(entryToImagePath(file));
writeEntry(in, dest);
break;
case NATIVE_CMD:
Path p = root.resolve(entryToImagePath(file));
writeEntry(in, p);
p.toFile().setExecutable(true);
break;
case CONFIG:
case HEADER_FILE:
case MAN_PAGE:
writeEntry(in, root.resolve(entryToImagePath(file)));
break;
case LEGAL_NOTICE:
Path source = entryToImagePath(file);
if (file.linkedTarget() == null) {
writeEntry(in, root.resolve(source));
} else {
Path target = entryToImagePath(file.linkedTarget());
Path relPath = source.getParent().relativize(target);
writeSymLinkEntry(root.resolve(source), relPath);
}
break;
case TOP:
// Copy TOP files of the "java.base" module (only)
if ("java.base".equals(file.moduleName())) {
writeEntry(in, root.resolve(entryToImagePath(file)));
} else {
throw new InternalError("unexpected TOP entry: " + file.path());
}
break;
default:
throw new InternalError("unexpected entry: " + file.path());
}
}
}
private void writeEntry(InputStream in, Path dstFile) throws IOException {
Objects.requireNonNull(in);
Objects.requireNonNull(dstFile);
Files.createDirectories(Objects.requireNonNull(dstFile.getParent()));
Files.copy(in, dstFile);
}
/*
* Create a symbolic link to the given target if the target platform
* supports symbolic link; otherwise, it will create a tiny file
* to contain the path to the target.
*/
private void writeSymLinkEntry(Path dstFile, Path target) throws IOException {
Objects.requireNonNull(dstFile);
Objects.requireNonNull(target);
Files.createDirectories(Objects.requireNonNull(dstFile.getParent()));
if (!isWindows() && root.getFileSystem()
.supportedFileAttributeViews()
.contains("posix")) {
Files.createSymbolicLink(dstFile, target);
} else {
try (BufferedWriter writer = Files.newBufferedWriter(dstFile)) {
writer.write(String.format("Please see %s%n", target.toString()));
}
}
}
private String nativeDir(String filename) {
if (isWindows()) {
if (filename.endsWith(".dll") || filename.endsWith(".diz")
|| filename.endsWith(".pdb") || filename.endsWith(".map")) {
return BIN_DIRNAME;
} else {
return LIB_DIRNAME;
}
} else {
return LIB_DIRNAME;
}
}
private boolean isWindows() {
return targetPlatform == Platform.WINDOWS;
}
/**
* chmod ugo+x file
*/
private void setExecutable(Path file) {
try {
Set<PosixFilePermission> perms = Files.getPosixFilePermissions(file);
perms.add(PosixFilePermission.OWNER_EXECUTE);
perms.add(PosixFilePermission.GROUP_EXECUTE);
perms.add(PosixFilePermission.OTHERS_EXECUTE);
Files.setPosixFilePermissions(file, perms);
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
}
}
/**
* chmod ugo-w file
*/
private void setReadOnly(Path file) {
try {
Set<PosixFilePermission> perms = Files.getPosixFilePermissions(file);
perms.remove(PosixFilePermission.OWNER_WRITE);
perms.remove(PosixFilePermission.GROUP_WRITE);
perms.remove(PosixFilePermission.OTHERS_WRITE);
Files.setPosixFilePermissions(file, perms);
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
}
}
@Override
public ExecutableImage getExecutableImage() {
return new DefaultExecutableImage(root, modules);
}
// This is experimental, we should get rid-off the scripts in a near future
private static void patchScripts(ExecutableImage img, List<String> args) throws IOException {
Objects.requireNonNull(args);
if (!args.isEmpty()) {
Files.find(img.getHome().resolve(BIN_DIRNAME), 2, (path, attrs) -> {
return img.getModules().contains(path.getFileName().toString());
}).forEach((p) -> {
try {
String pattern = "JLINK_VM_OPTIONS=";
byte[] content = Files.readAllBytes(p);
String str = new String(content, StandardCharsets.UTF_8);
int index = str.indexOf(pattern);
StringBuilder builder = new StringBuilder();
if (index != -1) {
builder.append(str.substring(0, index)).
append(pattern);
for (String s : args) {
builder.append(s).append(" ");
}
String remain = str.substring(index + pattern.length());
builder.append(remain);
str = builder.toString();
try (BufferedWriter writer = Files.newBufferedWriter(p,
StandardCharsets.ISO_8859_1,
StandardOpenOption.WRITE)) {
writer.write(str);
}
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
});
}
}
public static ExecutableImage getExecutableImage(Path root) {
Path binDir = root.resolve(BIN_DIRNAME);
if (Files.exists(binDir.resolve("java")) ||
Files.exists(binDir.resolve("java.exe"))) {
return new DefaultExecutableImage(root, retrieveModules(root));
}
return null;
}
private static Set<String> retrieveModules(Path root) {
Path releaseFile = root.resolve("release");
Set<String> modules = new HashSet<>();
if (Files.exists(releaseFile)) {
Properties release = new Properties();
try (FileInputStream fi = new FileInputStream(releaseFile.toFile())) {
release.load(fi);
} catch (IOException ex) {
System.err.println("Can't read release file " + ex);
}
String mods = release.getProperty("MODULES");
if (mods != null) {
String[] arr = mods.substring(1, mods.length() - 1).split(" ");
for (String m : arr) {
modules.add(m.trim());
}
}
}
return modules;
}
}
⏎ jdk/tools/jlink/builder/DefaultImageBuilder.java
Or download all of them as a single archive file:
File name: jdk.jlink-17.0.5-src.zip File size: 164180 bytes Release date: 2022-09-13 Download
⇒ JDK 17 jdk.jpackage.jmod - JPackage Tool
2023-08-03, ≈19🔥, 0💬
Popular Posts:
Apache Log4j IOStreams is a Log4j API extension that provides numerous classes from java.io that can...
layout.jar is a component in iText Java library to provide layout functionalities. iText Java librar...
Apache Log4j 1.2 Bridge allows applications coded to use Log4j 1.2 API to use Log4j 2 instead. Bytec...
maven-model-builder-3.5. 4.jaris the JAR file for Apache Maven 3.5.4 Model Builder module. Apache Ma...
JDK 11 jdk.compiler.jmod is the JMOD file for JDK 11 Compiler tool, which can be invoked by the "jav...