
com.qwazr.classloader.ClassLoaderManager Maven / Gradle / Ivy
/**
* Copyright 2016 Emmanuel Keller / QWAZR
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package com.qwazr.classloader;
import com.qwazr.server.GenericServer;
import com.qwazr.utils.ClassLoaderUtils;
import com.qwazr.utils.IOUtils;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
public class ClassLoaderManager {
public final File javaResourceDirectory;
public final File javaClassesDirectory;
public final File javaLibrariesDirectory;
private final ClassLoader mainThreadClassLoader;
private final Thread mainThread;
private volatile ClassLoader classLoader;
private volatile ClassFactory classFactory;
public ClassLoaderManager(final File dataDirectory, final Thread mainThread) throws MalformedURLException {
this.mainThread = mainThread == null ? Thread.currentThread() : mainThread;
this.classFactory = ClassFactory.DefaultFactory.INSTANCE;
this.mainThreadClassLoader = this.mainThread.getContextClassLoader();
if (dataDirectory == null) {
this.javaResourceDirectory = null;
this.javaClassesDirectory = null;
this.javaLibrariesDirectory = null;
} else {
this.javaResourceDirectory = new File(dataDirectory, "src/main/resources");
this.javaClassesDirectory = new File(dataDirectory, "target/classes");
this.javaLibrariesDirectory = new File(dataDirectory, "lib");
}
reload();
}
public ClassLoaderManager(final GenericServer.Builder builder, final Thread mainThread)
throws MalformedURLException {
this(builder == null ? null : builder.getConfiguration().dataDirectory, mainThread);
if (builder != null)
builder.contextAttribute(this);
}
public synchronized void reload() throws MalformedURLException {
final ClassLoader oldClassLoader = classLoader;
final List urlList = new ArrayList<>();
if (javaResourceDirectory != null && javaResourceDirectory.exists())
urlList.add(javaResourceDirectory.toURI().toURL());
if (javaClassesDirectory != null && javaClassesDirectory.exists())
urlList.add(javaClassesDirectory.toURI().toURL());
if (javaLibrariesDirectory != null && javaLibrariesDirectory.exists())
urlList.add(javaLibrariesDirectory.toURI().toURL());
if (urlList.isEmpty()) {
classLoader = mainThreadClassLoader;
return;
}
final URL[] urls = urlList.toArray(new URL[urlList.size()]);
final URLClassLoader newClassLoader = new URLClassLoader(urls, mainThreadClassLoader);
mainThread.setContextClassLoader(newClassLoader);
classLoader = newClassLoader;
if (oldClassLoader != null && oldClassLoader != mainThreadClassLoader && oldClassLoader instanceof Closeable)
IOUtils.close((Closeable) oldClassLoader);
}
final public void register(final ClassFactory classFactory) {
this.classFactory = classFactory == null ? ClassFactory.DefaultFactory.INSTANCE : classFactory;
}
final public T newInstance(final Class clazz) throws ReflectiveOperationException {
return clazz == null ? null : classFactory.newInstance(clazz);
}
final public T newInstance(final String className, final String[] classPrefixes)
throws IOException, ReflectiveOperationException {
return newInstance(ClassLoaderUtils.findClass(classLoader, className, classPrefixes));
}
final public T newInstance(final String className) throws IOException, ReflectiveOperationException {
return newInstance(ClassLoaderUtils.findClass(classLoader, className));
}
final public Class findClass(final String className) throws ClassNotFoundException {
return ClassLoaderUtils.findClass(classLoader, className);
}
final public InputStream getResourceAsStream(final String name) {
return ClassLoaderUtils.getResourceAsStream(classLoader, name);
}
final public ClassLoader getClassLoader() {
return classLoader;
}
}