JDK 11 jdk.jlink.jmod - JLink Tool

JDK 11 jdk.jlink.jmod is the JMOD file for JDK 11 JLink tool, which can be invoked by the "jlink" command.

JDK 11 JLink tool compiled class files are stored in \fyicenter\jdk-11.0.1\jmods\jdk.jlink.jmod.

JDK 11 JLink tool compiled class files are also linked and stored in the \fyicenter\jdk-11.0.1\lib\modules JImage file.

JDK 11 JLink tool source code files are stored in \fyicenter\jdk-11.0.1\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/internal/ResourcePoolManager.java

/*
 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */
package jdk.tools.jlink.internal;

import java.lang.module.ModuleDescriptor;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
import jdk.internal.jimage.decompressor.CompressedResourceHeader;
import jdk.internal.module.Resources;
import jdk.internal.module.ModuleInfo;
import jdk.internal.module.ModuleInfo.Attributes;
import jdk.internal.module.ModuleTarget;
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;

/**
 * A manager for pool of resources.
 */
public class ResourcePoolManager {
    // utility to read Module Attributes of the given ResourcePoolModule
    static Attributes readModuleAttributes(ResourcePoolModule mod) {
        String p = "/" + mod.name() + "/module-info.class";
        Optional<ResourcePoolEntry> content = mod.findEntry(p);
        if (!content.isPresent()) {
              throw new PluginException("module-info.class not found for " +
                  mod.name() + " module");
        }
        ByteBuffer bb = ByteBuffer.wrap(content.get().contentBytes());
        try {
            return ModuleInfo.read(bb, null);
        } catch (RuntimeException re) {
            throw new RuntimeException("module info cannot be read for " + mod.name(), re);
        }
    }

    /**
     * Returns true if a resource has an effective package.
     */
    public static boolean isNamedPackageResource(String path) {
        return (path.endsWith(".class") && !path.endsWith("module-info.class")) ||
                Resources.canEncapsulate(path);
    }

    class ResourcePoolModuleImpl implements ResourcePoolModule {

        final Map<String, ResourcePoolEntry> moduleContent = new LinkedHashMap<>();
        // lazily initialized
        private ModuleDescriptor descriptor;
        private ModuleTarget target;

        final String name;

        private ResourcePoolModuleImpl(String name) {
            this.name = name;
        }

        @Override
        public String name() {
            return name;
        }

        @Override
        public Optional<ResourcePoolEntry> findEntry(String path) {
            if (!path.startsWith("/")) {
                path = "/" + path;
            }
            if (!path.startsWith("/" + name + "/")) {
                path = "/" + name + path; // path already starts with '/'
            }
            return Optional.ofNullable(moduleContent.get(path));
        }

        @Override
        public ModuleDescriptor descriptor() {
            initModuleAttributes();
            return descriptor;
        }

        @Override
        public String targetPlatform() {
            initModuleAttributes();
            return target != null? target.targetPlatform() : null;
        }

        private void initModuleAttributes() {
            if (this.descriptor == null) {
                Attributes attr = readModuleAttributes(this);
                this.descriptor = attr.descriptor();
                this.target = attr.target();
            }
        }

        @Override
        public Set<String> packages() {
            Set<String> pkgs = new HashSet<>();
            moduleContent.values().stream()
                .filter(m -> m.type() == ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
                .forEach(res -> {
                    String name = ImageFileCreator.resourceName(res.path());
                    if (isNamedPackageResource(name)) {
                        String pkg = ImageFileCreator.toPackage(name);
                        if (!pkg.isEmpty()) {
                            pkgs.add(pkg);
                        }
                    }
                });
            return pkgs;
        }

        @Override
        public String toString() {
            return name();
        }

        @Override
        public Stream<ResourcePoolEntry> entries() {
            return moduleContent.values().stream();
        }

        @Override
        public int entryCount() {
            return moduleContent.values().size();
        }
    }

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

        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 ByteOrder order;
    private final StringTable table;
    private final ResourcePool poolImpl;
    private final ResourcePoolBuilder poolBuilderImpl;
    private final ResourcePoolModuleView moduleViewImpl;

    public ResourcePoolManager() {
        this(ByteOrder.nativeOrder());
    }

    public ResourcePoolManager(ByteOrder order) {
        this(order, new StringTable() {

            @Override
            public int addString(String str) {
                return -1;
            }

            @Override
            public String getString(int id) {
                return null;
            }
        });
    }

    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 ResourcePoolEntry.
     *
     * @param data The ResourcePoolEntry to add.
     */
    public void add(ResourcePoolEntry data) {
        Objects.requireNonNull(data);
        if (resources.get(data.path()) != null) {
            throw new PluginException("Resource " + data.path()
                    + " already present");
        }
        String modulename = data.moduleName();
        ResourcePoolModuleImpl m = (ResourcePoolModuleImpl)modules.get(modulename);
        if (m == null) {
            m = new ResourcePoolModuleImpl(modulename);
            modules.put(modulename, m);
        }
        resources.put(data.path(), data);
        m.moduleContent.put(data.path(), data);
    }

    /**
     * Retrieves the module for the provided name.
     *
     * @param name The module name
     * @return the module of matching name, if found
     */
    public Optional<ResourcePoolModule> findModule(String name) {
        Objects.requireNonNull(name);
        return Optional.ofNullable(modules.get(name));
    }

    /**
     * The stream of modules contained in this ResourcePool.
     *
     * @return The stream of modules.
     */
    public Stream<ResourcePoolModule> modules() {
        return modules.values().stream();
    }

    /**
     * Return the number of ResourcePoolModule count in this ResourcePool.
     *
     * @return the module count.
     */
    public int moduleCount() {
        return modules.size();
    }

    /**
     * Get all ResourcePoolEntry contained in this ResourcePool instance.
     *
     * @return The stream of ResourcePoolModuleEntries.
     */
    public Stream<ResourcePoolEntry> entries() {
        return resources.values().stream();
    }

    /**
     * Return the number of ResourcePoolEntry count in this ResourcePool.
     *
     * @return the entry count.
     */
    public int entryCount() {
        return resources.values().size();
    }

    /**
     * Get the ResourcePoolEntry for the passed path.
     *
     * @param path A data path
     * @return A ResourcePoolEntry instance or null if the data is not found
     */
    public Optional<ResourcePoolEntry> findEntry(String path) {
        Objects.requireNonNull(path);
        return Optional.ofNullable(resources.get(path));
    }

    /**
     * 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 ResourcePoolEntry instance or null if the data is not found
     */
    public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context) {
        Objects.requireNonNull(path);
        Objects.requireNonNull(context);
        ResourcePoolModule module = modules.get(context.moduleName());
        Objects.requireNonNull(module);
        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 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(ResourcePoolEntry data) {
        Objects.requireNonNull(data);
        return findEntry(data.path()).isPresent();
    }

    /**
     * Check if the ResourcePool contains some content at all.
     *
     * @return True, no content, false otherwise.
     */
    public boolean isEmpty() {
        return resources.isEmpty();
    }

    /**
     * The ByteOrder currently in use when generating the jimage file.
     *
     * @return The ByteOrder.
     */
    public ByteOrder byteOrder() {
        return order;
    }

    public StringTable getStringTable() {
        return table;
    }

    /**
     * A resource that has been compressed.
     */
    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, ResourcePoolEntry.Type.CLASS_OR_RESOURCE, content);
            this.uncompressed_size = uncompressed_size;
        }

        public long getUncompressedSize() {
            return uncompressed_size;
        }

        @Override
        public boolean equals(Object other) {
            if (!(other instanceof CompressedModuleData)) {
                return false;
            }
            CompressedModuleData f = (CompressedModuleData) other;
            return f.path().equals(path());
        }

        @Override
        public int hashCode() {
            return super.hashCode();
        }
    }

    public static CompressedModuleData newCompressedResource(ResourcePoolEntry original,
            ByteBuffer compressed,
            String plugin, String pluginConfig, StringTable strings,
            ByteOrder order) {
        Objects.requireNonNull(original);
        Objects.requireNonNull(compressed);
        Objects.requireNonNull(plugin);

        boolean isTerminal = !(original instanceof CompressedModuleData);
        long uncompressed_size = original.contentLength();
        if (original instanceof CompressedModuleData) {
            CompressedModuleData comp = (CompressedModuleData) original;
            uncompressed_size = comp.getUncompressedSize();
        }
        int nameOffset = strings.addString(plugin);
        int configOffset = -1;
        if (pluginConfig != null) {
            configOffset = strings.addString(plugin);
        }
        CompressedResourceHeader rh
                = new CompressedResourceHeader(compressed.limit(), original.contentLength(),
                        nameOffset, configOffset, isTerminal);
        // Merge header with content;
        byte[] h = rh.getBytes(order);
        ByteBuffer bb = ByteBuffer.allocate(compressed.limit() + h.length);
        bb.order(order);
        bb.put(h);
        bb.put(compressed);
        byte[] contentWithHeader = bb.array();

        CompressedModuleData compressedResource
                = new CompressedModuleData(original.moduleName(), original.path(),
                        contentWithHeader, uncompressed_size);
        return compressedResource;
    }
}

jdk/tools/jlink/internal/ResourcePoolManager.java

 

JDK 11 jdk.jshell.jmod - JShell Tool

JDK 11 jdk.jfr.jmod - JFR Module

Download and Use JDK 11

⇑⇑ FAQ for JDK (Java Development Kit)

2018-11-09, 2849👍, 0💬