mirror of https://github.com/apache/jclouds.git
Provided utility for loading classes that falls back to the Thread Context Class Loader if class is not found.
This commit is contained in:
parent
10d617a4ca
commit
148b6abbb8
|
@ -34,6 +34,7 @@ import java.util.Properties;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.PropertiesBuilder;
|
import org.jclouds.PropertiesBuilder;
|
||||||
|
import org.jclouds.util.ClassLoadingUtils;
|
||||||
import org.jclouds.util.SaxUtils;
|
import org.jclouds.util.SaxUtils;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -90,7 +91,7 @@ public class Providers {
|
||||||
String provider = get(Splitter.on('.').split(keyString), 0);
|
String provider = get(Splitter.on('.').split(keyString), 0);
|
||||||
Class<RestContextBuilder<Object, Object>> clazz = Providers.resolveContextBuilderClass(provider,
|
Class<RestContextBuilder<Object, Object>> clazz = Providers.resolveContextBuilderClass(provider,
|
||||||
properties);
|
properties);
|
||||||
if (type.isAssignableFrom(clazz))
|
if (clazz != null && type.isAssignableFrom(clazz))
|
||||||
return provider;
|
return provider;
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -111,13 +112,18 @@ public class Providers {
|
||||||
String asyncClassName = properties.getProperty(provider + ".async");
|
String asyncClassName = properties.getProperty(provider + ".async");
|
||||||
if (syncClassName != null) {
|
if (syncClassName != null) {
|
||||||
checkArgument(asyncClassName != null, "please configure async class for " + syncClassName);
|
checkArgument(asyncClassName != null, "please configure async class for " + syncClassName);
|
||||||
Class.forName(syncClassName);
|
if(ClassLoadingUtils.loadClass(Providers.class, syncClassName) == null) {
|
||||||
Class.forName(asyncClassName);
|
throw new ClassNotFoundException();
|
||||||
return (Class<RestContextBuilder<S, A>>) (contextBuilderClassName != null ? Class
|
}
|
||||||
.forName(contextBuilderClassName) : RestContextBuilder.class);
|
if(ClassLoadingUtils.loadClass(Providers.class, asyncClassName) == null) {
|
||||||
|
throw new ClassNotFoundException();
|
||||||
|
}
|
||||||
|
return (Class<RestContextBuilder<S, A>>) (contextBuilderClassName != null ? ClassLoadingUtils.
|
||||||
|
loadClass(Providers.class, contextBuilderClassName) : RestContextBuilder.class);
|
||||||
} else {
|
} else {
|
||||||
checkArgument(contextBuilderClassName != null, "please configure contextbuilder class for " + provider);
|
checkArgument(contextBuilderClassName != null, "please configure contextbuilder class for " + provider);
|
||||||
return (Class<RestContextBuilder<S, A>>) Class.forName(contextBuilderClassName);
|
return (Class<RestContextBuilder<S, A>>) ClassLoadingUtils.
|
||||||
|
loadClass(Providers.class, contextBuilderClassName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +148,7 @@ public class Providers {
|
||||||
NoSuchMethodException {
|
NoSuchMethodException {
|
||||||
String propertiesBuilderClassName = props.getProperty(providerName + ".propertiesbuilder", null);
|
String propertiesBuilderClassName = props.getProperty(providerName + ".propertiesbuilder", null);
|
||||||
if (propertiesBuilderClassName != null) {
|
if (propertiesBuilderClassName != null) {
|
||||||
return (Class<PropertiesBuilder>) Class.forName(propertiesBuilderClassName);
|
return (Class<PropertiesBuilder>) ClassLoadingUtils.loadClass(Providers.class, propertiesBuilderClassName);
|
||||||
} else {
|
} else {
|
||||||
return PropertiesBuilder.class;
|
return PropertiesBuilder.class;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import javax.inject.Inject;
|
||||||
|
|
||||||
import org.jclouds.PropertiesBuilder;
|
import org.jclouds.PropertiesBuilder;
|
||||||
import org.jclouds.location.reference.LocationConstants;
|
import org.jclouds.location.reference.LocationConstants;
|
||||||
|
import org.jclouds.util.ClassLoadingUtils;
|
||||||
import org.jclouds.util.Modules2;
|
import org.jclouds.util.Modules2;
|
||||||
import org.jclouds.util.Strings2;
|
import org.jclouds.util.Strings2;
|
||||||
|
|
||||||
|
@ -303,8 +304,8 @@ public class RestContextFactory {
|
||||||
try {
|
try {
|
||||||
contextBuilderClass = Providers.resolveContextBuilderClass(providerName, props);
|
contextBuilderClass = Providers.resolveContextBuilderClass(providerName, props);
|
||||||
propertiesBuilderClass = Providers.resolvePropertiesBuilderClass(providerName, props);
|
propertiesBuilderClass = Providers.resolvePropertiesBuilderClass(providerName, props);
|
||||||
sync = (Class<S>) (syncClassName != null ? Class.forName(syncClassName) : null);
|
sync = (Class<S>) (syncClassName != null ? ClassLoadingUtils.loadClass(getClass(), syncClassName) : null);
|
||||||
async = (Class<A>) (asyncClassName != null ? Class.forName(asyncClassName) : null);
|
async = (Class<A>) (asyncClassName != null ? ClassLoadingUtils.loadClass(getClass(), asyncClassName) : null);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
String.format(
|
String.format(
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.jclouds.util;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import com.google.common.io.Resources;
|
||||||
|
|
||||||
|
public class ClassLoadingUtils {
|
||||||
|
|
||||||
|
public ClassLoadingUtils() {
|
||||||
|
//Utility Class
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a class using the class loader.
|
||||||
|
* 1. The class loader of the context class is being used.
|
||||||
|
* 2. The thread context class loader is being used.
|
||||||
|
* If both approaches fail, returns null.
|
||||||
|
*
|
||||||
|
* @param contextClass The name of a context class to use.
|
||||||
|
* @param className The name of the class to load
|
||||||
|
* @return The class or null if no class loader could load the class.
|
||||||
|
*/
|
||||||
|
public static Class<?> loadClass(Class<?> contextClass, String className) {
|
||||||
|
Class clazz = null;
|
||||||
|
if (contextClass.getClassLoader() != null) {
|
||||||
|
clazz = silentLoadClass(className, contextClass.getClassLoader());
|
||||||
|
}
|
||||||
|
if (clazz == null && Thread.currentThread().getContextClassLoader() != null) {
|
||||||
|
clazz = silentLoadClass(className, Thread.currentThread().getContextClassLoader());
|
||||||
|
}
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the url of a resource.
|
||||||
|
* 1. The context class is being used.
|
||||||
|
* 2. The thread context class loader is being used.
|
||||||
|
* If both approach fail, returns null.
|
||||||
|
*
|
||||||
|
* @param contextClass
|
||||||
|
* @param resourceName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static URL loadResource(Class contextClass, String resourceName) {
|
||||||
|
URL url = null;
|
||||||
|
if (contextClass != null) {
|
||||||
|
url = Resources.getResource(contextClass, resourceName);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (url == null && Thread.currentThread().getContextClassLoader() != null) {
|
||||||
|
url = Thread.currentThread().getContextClassLoader().getResource(resourceName);
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a {@link Class} from the specified {@link ClassLoader} without throwing {@ClassNotFoundException}.
|
||||||
|
*
|
||||||
|
* @param className
|
||||||
|
* @param classLoader
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static Class<?> silentLoadClass(String className, ClassLoader classLoader) {
|
||||||
|
Class clazz = null;
|
||||||
|
if (classLoader != null && className != null) {
|
||||||
|
try {
|
||||||
|
clazz = classLoader.loadClass(className);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
//Ignore and proceed to the next class loader.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,13 +47,11 @@ public class Modules2 {
|
||||||
@Override
|
@Override
|
||||||
public Module apply(String from) {
|
public Module apply(String from) {
|
||||||
try {
|
try {
|
||||||
return (Module) Class.forName(from).newInstance();
|
return (Module) ClassLoadingUtils.loadClass(Modules2.class, from).newInstance();
|
||||||
} catch (InstantiationException e) {
|
} catch (InstantiationException e) {
|
||||||
throw new RuntimeException("error instantiating " + from, e);
|
throw new RuntimeException("error instantiating " + from, e);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new RuntimeException("error instantiating " + from, e);
|
throw new RuntimeException("error instantiating " + from, e);
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new RuntimeException("error instantiating " + from, e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.io.CharStreams;
|
import com.google.common.io.CharStreams;
|
||||||
import com.google.common.io.Resources;
|
import com.google.common.io.Resources;
|
||||||
|
import org.jclouds.util.ClassLoadingUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities used to build init scripts.
|
* Utilities used to build init scripts.
|
||||||
|
@ -135,7 +136,7 @@ public class Utils {
|
||||||
|
|
||||||
public static String writeFunctionFromResource(String function, OsFamily family) {
|
public static String writeFunctionFromResource(String function, OsFamily family) {
|
||||||
try {
|
try {
|
||||||
String toReturn = CharStreams.toString(Resources.newReaderSupplier(Resources.getResource(Utils.class, String
|
String toReturn = CharStreams.toString(Resources.newReaderSupplier(ClassLoadingUtils.loadResource(Utils.class, String
|
||||||
.format("/functions/%s.%s", function, ShellToken.SH.to(family))), Charsets.UTF_8));
|
.format("/functions/%s.%s", function, ShellToken.SH.to(family))), Charsets.UTF_8));
|
||||||
String lf = ShellToken.LF.to(family);
|
String lf = ShellToken.LF.to(family);
|
||||||
return toReturn.endsWith(lf) ? toReturn : new StringBuilder(toReturn).append(lf).toString();
|
return toReturn.endsWith(lf) ? toReturn : new StringBuilder(toReturn).append(lf).toString();
|
||||||
|
|
Loading…
Reference in New Issue