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/internal/ImagePluginStack.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.internal;

import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.module.ModuleDescriptor;
import java.nio.ByteOrder;
import java.util.*;
import java.util.stream.Stream;

import jdk.internal.jimage.decompressor.Decompressor;
import jdk.internal.module.ModuleInfo.Attributes;
import jdk.internal.module.ModuleTarget;
import jdk.tools.jlink.builder.ImageBuilder;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
import jdk.tools.jlink.plugin.ResourcePoolModule;

/**
 * Plugins Stack. Plugins entry point to apply transformations onto resources
 * and files.
 */
public final class ImagePluginStack {

    public interface ImageProvider {

        ExecutableImage retrieve(ImagePluginStack stack) throws IOException;
    }

    public static final class OrderedResourcePoolManager extends ResourcePoolManager {
        class OrderedResourcePool extends ResourcePoolImpl {
            List<ResourcePoolEntry> getOrderedList() {
                return OrderedResourcePoolManager.this.getOrderedList();
            }
        }

        private final List<ResourcePoolEntry> orderedList = new ArrayList<>();
        private final ResourcePoolImpl poolImpl = new OrderedResourcePool();

        public OrderedResourcePoolManager(ByteOrder order, StringTable table) {
            super(order, table);
        }

        @Override
        public ResourcePool resourcePool() {
            return poolImpl;
        }

        /**
         * Add a resource.
         *
         * @param resource The Resource to add.
         */
        @Override
        public void add(ResourcePoolEntry resource) {
            super.add(resource);
            orderedList.add(resource);
        }

        List<ResourcePoolEntry> getOrderedList() {
            return Collections.unmodifiableList(orderedList);
        }
    }

    private final static class CheckOrderResourcePoolManager extends ResourcePoolManager {

        private final List<ResourcePoolEntry> orderedList;
        private int currentIndex;

        public CheckOrderResourcePoolManager(ByteOrder order, List<ResourcePoolEntry> orderedList, StringTable table) {
            super(order, table);
            this.orderedList = Objects.requireNonNull(orderedList);
        }

        /**
         * Add a resource.
         *
         * @param resource The Resource to add.
         */
        @Override
        public void add(ResourcePoolEntry resource) {
            ResourcePoolEntry ordered = orderedList.get(currentIndex);
            if (!resource.equals(ordered)) {
                throw new PluginException("Resource " + resource.path() + " not in the right order");
            }
            super.add(resource);
            currentIndex += 1;
        }
    }

    private static final class PreVisitStrings implements StringTable {

        private int currentid = 0;
        private final Map<String, Integer> stringsUsage = new HashMap<>();
        private final Map<String, Integer> stringsMap = new HashMap<>();
        private final Map<Integer, String> reverseMap = new HashMap<>();

        @Override
        public int addString(String str) {
            Objects.requireNonNull(str);
            Integer count = stringsUsage.get(str);
            if (count == null) {
                count = 0;
            }
            count += 1;
            stringsUsage.put(str, count);
            Integer id = stringsMap.get(str);
            if (id == null) {
                id = currentid;
                stringsMap.put(str, id);
                currentid += 1;
                reverseMap.put(id, str);
            }

            return id;
        }

        private List<String> getSortedStrings() {
            Stream<java.util.Map.Entry<String, Integer>> stream
                    = stringsUsage.entrySet().stream();
            // Remove strings that have a single occurence
            List<String> result = stream.sorted(Comparator.comparing(e -> e.getValue(),
                    Comparator.reverseOrder())).filter((e) -> {
                        return e.getValue() > 1;
                    }).map(java.util.Map.Entry::getKey).
                    toList();
            return result;
        }

        @Override
        public String getString(int id) {
            return reverseMap.get(id);
        }
    }

    private final ImageBuilder imageBuilder;
    private final Plugin lastSorter;
    private final List<Plugin> plugins = new ArrayList<>();
    private final List<ResourcePrevisitor> resourcePrevisitors = new ArrayList<>();
    private final boolean validate;

    public ImagePluginStack() {
        this(null, Collections.emptyList(), null);
    }

    public ImagePluginStack(ImageBuilder imageBuilder,
            List<Plugin> plugins,
            Plugin lastSorter) {
        this(imageBuilder, plugins, lastSorter, true);
    }

    public ImagePluginStack(ImageBuilder imageBuilder,
            List<Plugin> plugins,
            Plugin lastSorter,
            boolean validate) {
        this.imageBuilder = Objects.requireNonNull(imageBuilder);
        this.lastSorter = lastSorter;
        this.plugins.addAll(Objects.requireNonNull(plugins));
        plugins.stream().forEach((p) -> {
            Objects.requireNonNull(p);
            if (p instanceof ResourcePrevisitor) {
                resourcePrevisitors.add((ResourcePrevisitor) p);
            }
        });
        this.validate = validate;
    }

    public void operate(ImageProvider provider) throws Exception {
        ExecutableImage img = provider.retrieve(this);
        List<String> arguments = new ArrayList<>();
        plugins.stream()
                .filter(PostProcessor.class::isInstance)
                .map((plugin) -> ((PostProcessor)plugin).process(img))
                .filter((lst) -> (lst != null))
                .forEach((lst) -> {
                     arguments.addAll(lst);
                });
        img.storeLaunchArgs(arguments);
    }

    public DataOutputStream getJImageFileOutputStream() throws IOException {
        return imageBuilder.getJImageOutputStream();
    }

    public ImageBuilder getImageBuilder() {
        return imageBuilder;
    }

    /**
     * Resource Plugins stack entry point. All resources are going through all
     * the plugins.
     *
     * @param resources The set of resources to visit
     * @return The result of the visit.
     * @throws IOException
     */
    public ResourcePool visitResources(ResourcePoolManager resources)
            throws Exception {
        Objects.requireNonNull(resources);
        if (resources.isEmpty()) {
            return new ResourcePoolManager(resources.byteOrder(),
                    resources.getStringTable()).resourcePool();
        }
        PreVisitStrings previsit = new PreVisitStrings();
        resourcePrevisitors.stream().forEach((p) -> {
            p.previsit(resources.resourcePool(), previsit);
        });

        // Store the strings resulting from the previsit.
        List<String> sorted = previsit.getSortedStrings();
        sorted.stream().forEach((s) -> {
            resources.getStringTable().addString(s);
        });

        ResourcePool resPool = resources.resourcePool();
        List<ResourcePoolEntry> frozenOrder = null;
        for (Plugin p : plugins) {
            ResourcePoolManager resMgr = null;
            if (p == lastSorter) {
                if (frozenOrder != null) {
                    throw new Exception("Order of resources is already frozen. Plugin "
                            + p.getName() + " is badly located");
                }
                // Create a special Resource pool to compute the indexes.
                resMgr = new OrderedResourcePoolManager(resPool.byteOrder(),
                        resources.getStringTable());
            } else {// If we have an order, inject it
                if (frozenOrder != null) {
                    resMgr = new CheckOrderResourcePoolManager(resPool.byteOrder(),
                            frozenOrder, resources.getStringTable());
                } else {
                    resMgr = new ResourcePoolManager(resPool.byteOrder(),
                            resources.getStringTable());
                }
            }
            try {
                resPool = p.transform(resPool, resMgr.resourcePoolBuilder());
            } catch (PluginException pe) {
                if (JlinkTask.DEBUG) {
                    System.err.println("Plugin " + p.getName() + " threw exception during transform");
                    pe.printStackTrace();
                }
                throw pe;
            }
            if (resPool.isEmpty()) {
                throw new Exception("Invalid resource pool for plugin " + p);
            }
            if (resPool instanceof OrderedResourcePoolManager.OrderedResourcePool) {
                frozenOrder = ((OrderedResourcePoolManager.OrderedResourcePool)resPool).getOrderedList();
            }
        }

        return resPool;
    }

    /**
     * This pool wrap the original pool and automatically uncompress ResourcePoolEntry
     * if needed.
     */
    private class LastPoolManager extends ResourcePoolManager {
        private class LastModule implements ResourcePoolModule {

            final ResourcePoolModule module;
            // lazily initialized
            ModuleDescriptor descriptor;
            ModuleTarget target;

            LastModule(ResourcePoolModule module) {
                this.module = module;
            }

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

            @Override
            public Optional<ResourcePoolEntry> findEntry(String path) {
                Optional<ResourcePoolEntry> d = module.findEntry(path);
                return d.isPresent()? Optional.of(getUncompressed(d.get())) : Optional.empty();
            }

            @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 = ResourcePoolManager.readModuleAttributes(this);
                    this.descriptor = attr.descriptor();
                    this.target = attr.target();
                }
            }

            @Override
            public Set<String> packages() {
                return module.packages();
            }

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

            @Override
            public Stream<ResourcePoolEntry> entries() {
                List<ResourcePoolEntry> lst = new ArrayList<>();
                module.entries().forEach(md -> {
                    lst.add(getUncompressed(md));
                });
                return lst.stream();
            }

            @Override
            public int entryCount() {
                return module.entryCount();
            }
        }

        private final ResourcePool pool;
        Decompressor decompressor = new Decompressor();
        Collection<ResourcePoolEntry> content;

        LastPoolManager(ResourcePool pool) {
            this.pool = pool;
        }

        @Override
        public void add(ResourcePoolEntry resource) {
            throw new PluginException("pool is readonly");
        }

        @Override
        public Optional<ResourcePoolModule> findModule(String name) {
            Optional<ResourcePoolModule> module = pool.moduleView().findModule(name);
            return module.isPresent()? Optional.of(new LastModule(module.get())) : Optional.empty();
        }

        /**
         * The collection of modules contained in this pool.
         *
         * @return The collection of modules.
         */
        @Override
        public Stream<ResourcePoolModule> modules() {
            List<ResourcePoolModule> modules = new ArrayList<>();
            pool.moduleView().modules().forEach(m -> {
                modules.add(new LastModule(m));
            });
            return modules.stream();
        }

        @Override
        public int moduleCount() {
            return pool.moduleView().moduleCount();
        }

        /**
         * Get all resources contained in this pool instance.
         *
         * @return The stream of resources;
         */
        @Override
        public Stream<ResourcePoolEntry> entries() {
            if (content == null) {
                content = new ArrayList<>();
                pool.entries().forEach(md -> {
                    content.add(getUncompressed(md));
                });
            }
            return content.stream();
        }

        @Override
        public int entryCount() {
            return pool.entryCount();
        }

        /**
         * Get the resource for the passed path.
         *
         * @param path A resource path
         * @return A Resource instance if the resource is found
         */
        @Override
        public Optional<ResourcePoolEntry> findEntry(String path) {
            Objects.requireNonNull(path);
            Optional<ResourcePoolEntry> res = pool.findEntry(path);
            return res.isPresent()? Optional.of(getUncompressed(res.get())) : Optional.empty();
        }

        @Override
        public Optional<ResourcePoolEntry> findEntryInContext(String path, ResourcePoolEntry context) {
            Objects.requireNonNull(path);
            Objects.requireNonNull(context);
            Optional<ResourcePoolEntry> res = pool.findEntryInContext(path, context);
            return res.map(this::getUncompressed);
        }

        @Override
        public boolean contains(ResourcePoolEntry res) {
            return pool.contains(res);
        }

        @Override
        public boolean isEmpty() {
            return pool.isEmpty();
        }

        @Override
        public ByteOrder byteOrder() {
            return pool.byteOrder();
        }

        private ResourcePoolEntry getUncompressed(ResourcePoolEntry res) {
            if (res != null) {
                if (res instanceof ResourcePoolManager.CompressedModuleData) {
                    try {
                        byte[] bytes = decompressor.decompressResource(byteOrder(),
                                (int offset) -> ((ResourcePoolImpl)pool).getStringTable().getString(offset),
                                res.contentBytes());
                        res = res.copyWithContent(bytes);
                    } catch (IOException ex) {
                        if (JlinkTask.DEBUG) {
                            System.err.println("IOException while reading resource: " + res.path());
                            ex.printStackTrace();
                        }
                        throw new PluginException(ex);
                    }
                }
            }
            return res;
        }
    }

    /**
     * Make the imageBuilder to store files.
     *
     * @param original
     * @param transformed
     * @param writer
     * @throws java.lang.Exception
     */
    public void storeFiles(ResourcePool original, ResourcePool transformed,
            BasicImageWriter writer)
            throws Exception {
        Objects.requireNonNull(original);
        Objects.requireNonNull(transformed);
        ResourcePool lastPool = new LastPoolManager(transformed).resourcePool();
        if (validate) {
            ResourcePoolConfiguration.validate(lastPool);
        }
        imageBuilder.storeFiles(lastPool);
    }

    public ExecutableImage getExecutableImage() throws IOException {
        return imageBuilder.getExecutableImage();
    }
}

jdk/tools/jlink/internal/ImagePluginStack.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

JDK 17 jdk.jfr.jmod - JFR Module

JDK 17 JMod/Module Files

⇑⇑ FAQ for JDK (Java Development Kit) 17

2023-08-03, 3524👍, 0💬