001/*
002 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package jdk.internal.jvmci.service;
024
025import java.io.*;
026import java.net.*;
027import java.util.*;
028
029/**
030 * Utility called from the VM to create and register a separate class loader for loading JVMCI
031 * classes (i.e., those in found in lib/jvmci/*.jar).
032 */
033class JVMCIClassLoaderFactory {
034
035    /**
036     * Copy of the {@code UseJVMCIClassLoader} VM option. Set by the VM before the static
037     * initializer is called.
038     */
039    private static boolean useJVMCIClassLoader;
040
041    /**
042     * Registers the JVMCI class loader in the VM.
043     */
044    private static native void init(ClassLoader loader);
045
046    static {
047        init(useJVMCIClassLoader ? newClassLoader() : null);
048    }
049
050    /**
051     * Creates a new class loader for loading JVMCI classes.
052     */
053    private static ClassLoader newClassLoader() {
054        URL[] urls = getJVMCIJarsUrls();
055        ClassLoader parent = null;
056        return URLClassLoader.newInstance(urls, parent);
057    }
058
059    /**
060     * Gets the URLs for lib/jvmci/*.jar.
061     */
062    private static URL[] getJVMCIJarsUrls() {
063        File javaHome = new File(System.getProperty("java.home"));
064        File lib = new File(javaHome, "lib");
065        File jvmci = new File(lib, "jvmci");
066        if (!jvmci.exists()) {
067            throw new InternalError(jvmci + " does not exist");
068        }
069
070        List<URL> urls = new ArrayList<>();
071        for (String fileName : jvmci.list()) {
072            if (fileName.endsWith(".jar")) {
073                File file = new File(jvmci, fileName);
074                if (file.isDirectory()) {
075                    continue;
076                }
077                try {
078                    urls.add(file.toURI().toURL());
079                } catch (MalformedURLException e) {
080                    throw new InternalError(e);
081                }
082            }
083        }
084
085        return urls.toArray(new URL[urls.size()]);
086    }
087}