org.apache.kafka.common.utils.ChildFirstClassLoader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jena-fmod-kafka Show documentation
Show all versions of jena-fmod-kafka Show documentation
Apache Jena Fuseki server Kafka connector
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.kafka.common.utils;
import org.apache.kafka.common.KafkaException;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Locale;
import java.util.NoSuchElementException;
/**
* A class loader that looks for classes and resources in a specified class path first, before delegating to its parent
* class loader.
*/
public class ChildFirstClassLoader extends URLClassLoader {
static {
ClassLoader.registerAsParallelCapable();
}
/**
* @param classPath Class path string
* @param parent The parent classloader. If the required class / resource cannot be found in the given classPath,
* this classloader will be used to find the class / resource.
*/
public ChildFirstClassLoader(String classPath, ClassLoader parent) {
super(classpathToURLs(classPath), parent);
}
static private URL[] classpathToURLs(String classPath) {
ArrayList urls = new ArrayList<>();
for (String path : classPath.split(File.pathSeparator)) {
if (path == null || path.trim().isEmpty())
continue;
File file = new File(path);
try {
if (path.endsWith("/*")) {
File parent = new File(new File(file.getCanonicalPath()).getParent());
if (parent.isDirectory()) {
File[] files = parent.listFiles((dir, name) -> {
String lower = name.toLowerCase(Locale.ROOT);
return lower.endsWith(".jar") || lower.endsWith(".zip");
});
if (files != null) {
for (File jarFile : files) {
urls.add(jarFile.getCanonicalFile().toURI().toURL());
}
}
}
} else if (file.exists()) {
urls.add(file.getCanonicalFile().toURI().toURL());
}
} catch (IOException e) {
throw new KafkaException(e);
}
}
return urls.toArray(new URL[0]);
}
@Override
protected Class> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
Class> c = findLoadedClass(name);
if (c == null) {
try {
c = findClass(name);
} catch (ClassNotFoundException e) {
// Try parent
c = super.loadClass(name, false);
}
}
if (resolve)
resolveClass(c);
return c;
}
}
@Override
public URL getResource(String name) {
URL url = findResource(name);
if (url == null) {
// try parent
url = super.getResource(name);
}
return url;
}
@Override
public Enumeration getResources(String name) throws IOException {
Enumeration urls1 = findResources(name);
Enumeration urls2 = getParent() != null ? getParent().getResources(name) : null;
return new Enumeration() {
@Override
public boolean hasMoreElements() {
return (urls1 != null && urls1.hasMoreElements()) || (urls2 != null && urls2.hasMoreElements());
}
@Override
public URL nextElement() {
if (urls1 != null && urls1.hasMoreElements())
return urls1.nextElement();
if (urls2 != null && urls2.hasMoreElements())
return urls2.nextElement();
throw new NoSuchElementException();
}
};
}
}