All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jdk.internal.loader.NativeImageResources Maven / Gradle / Ivy

/*
 * This code is based on OpenJDK source file(s) which contain the following copyright notice:
 *
 * ------
 * Copyright (c) 2001, 2021, 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.
 * ------
 *
 * This file may contain additional modifications which are Copyright (c) Red Hat and other
 * contributors.
 */

package jdk.internal.loader;

import java.net.URL;
import java.net.MalformedURLException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.HashMap;

import sun.net.www.protocol.resource.Handler;

import org.qbicc.runtime.ReflectivelyAccesses;
import org.qbicc.runtime.ReflectivelyAccessedElement;

/**
 * This class provides a mechanism to make selected resources that were available
 * on the build-time classpath also available at runtime.
 *
 * The URLS returned from addResource are of the form:  NativeImageResources.PROTOCOL:///qbiccimage/resource/resource-N
 * where N is the index into the resources for the backing byte[].
 */
 @ReflectivelyAccesses({
    @ReflectivelyAccessedElement(clazz = Handler.class, method = "", params = {}),
    @ReflectivelyAccessedElement(clazz = Handler.class, method = "openConnection", params = {java.net.URL.class})
 })
public class NativeImageResources {
    private static final HashMap> mappings = new HashMap<>();
    private static byte[][] resources = new byte[0][0];
    private static final boolean TRACE_ACCESS = false;
    private static final String PROTOCOL = "resource"; // Graal nativeimage compatability for vertx.  We'd prefer to use nativeimage

    // For now, keep this simple and sequential until it proves to be a bottleneck
    static synchronized URL addResource(ClassLoader cl, String resourceName, byte[] resourceBytes) {
        // First de-duplicate resourceBytes and either reuse an existing entry or create a new one.
        int resourceNumber = -1;
        for (int i=0; i clMap = mappings.get(cl);
            if (clMap == null) {
                clMap = new HashMap<>();
                mappings.put(cl, clMap);
            }
            URL[] current = clMap.get(resourceName);
            if (current == null) {
                clMap.put(resourceName, new URL[]{url});
                return url;
            } else {
                // Deduplicate
                for (int i = 0; i < current.length; i++) {
                    if (current[i].getPath().equals(url.getPath())) {
                        return url;
                    }
                }
                URL[] enhanced = Arrays.copyOf(current, current.length + 1);
                enhanced[current.length] = url;
                clMap.put(resourceName, enhanced);
                return url;
            }
        } catch (MalformedURLException e) {
            throw new InternalError("Failed to create resource URL", e);
        }
    }

    static URL findResource(ClassLoader cl, String resourceName) {
        if (TRACE_ACCESS) System.out.println("findResource "+cl+" "+resourceName);
        HashMap clMap = mappings.get(cl);
        if (clMap == null) {
            return null;
        }
        URL[] resources = clMap.get(resourceName);
        if (resources == null) {
            return null;
        } else {
            if (TRACE_ACCESS) System.out.println("\tfound "+resources[0]);
            return resources[0];
        }
    }

    static Enumeration findResources(ClassLoader cl, String resourceName) {
        if (TRACE_ACCESS) System.out.println("findResources "+cl+" "+resourceName);
        HashMap clMap = mappings.get(cl);
        if (clMap == null) {
            return Collections.emptyEnumeration();
        }
        URL[] resources = clMap.get(resourceName);
        if (resources == null) {
            return Collections.emptyEnumeration();
         } else {
            if (TRACE_ACCESS) {
                System.out.println("\tfound "+resources.length);
                for (int i=0; i= resources.length) {
            return null;
        }
        if (TRACE_ACCESS) System.out.println("Success: "+resources[idx].length);
        return resources[idx];
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy