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
52c522d310
commit
7cba8e72a3
|
@ -34,6 +34,7 @@ import java.util.Properties;
|
|||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.PropertiesBuilder;
|
||||
import org.jclouds.util.ClassLoadingUtils;
|
||||
import org.jclouds.util.SaxUtils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
@ -90,7 +91,7 @@ public class Providers {
|
|||
String provider = get(Splitter.on('.').split(keyString), 0);
|
||||
Class<RestContextBuilder<Object, Object>> clazz = Providers.resolveContextBuilderClass(provider,
|
||||
properties);
|
||||
if (type.isAssignableFrom(clazz))
|
||||
if (clazz != null && type.isAssignableFrom(clazz))
|
||||
return provider;
|
||||
} catch (ClassNotFoundException e) {
|
||||
} catch (Exception e) {
|
||||
|
@ -111,13 +112,18 @@ public class Providers {
|
|||
String asyncClassName = properties.getProperty(provider + ".async");
|
||||
if (syncClassName != null) {
|
||||
checkArgument(asyncClassName != null, "please configure async class for " + syncClassName);
|
||||
Class.forName(syncClassName);
|
||||
Class.forName(asyncClassName);
|
||||
return (Class<RestContextBuilder<S, A>>) (contextBuilderClassName != null ? Class
|
||||
.forName(contextBuilderClassName) : RestContextBuilder.class);
|
||||
if(ClassLoadingUtils.loadClass(Providers.class, syncClassName) == null) {
|
||||
throw new ClassNotFoundException();
|
||||
}
|
||||
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 {
|
||||
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 {
|
||||
String propertiesBuilderClassName = props.getProperty(providerName + ".propertiesbuilder", null);
|
||||
if (propertiesBuilderClassName != null) {
|
||||
return (Class<PropertiesBuilder>) Class.forName(propertiesBuilderClassName);
|
||||
return (Class<PropertiesBuilder>) ClassLoadingUtils.loadClass(Providers.class, propertiesBuilderClassName);
|
||||
} else {
|
||||
return PropertiesBuilder.class;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import javax.inject.Inject;
|
|||
|
||||
import org.jclouds.PropertiesBuilder;
|
||||
import org.jclouds.location.reference.LocationConstants;
|
||||
import org.jclouds.util.ClassLoadingUtils;
|
||||
import org.jclouds.util.Modules2;
|
||||
import org.jclouds.util.Strings2;
|
||||
|
||||
|
@ -303,8 +304,8 @@ public class RestContextFactory {
|
|||
try {
|
||||
contextBuilderClass = Providers.resolveContextBuilderClass(providerName, props);
|
||||
propertiesBuilderClass = Providers.resolvePropertiesBuilderClass(providerName, props);
|
||||
sync = (Class<S>) (syncClassName != null ? Class.forName(syncClassName) : null);
|
||||
async = (Class<A>) (asyncClassName != null ? Class.forName(asyncClassName) : null);
|
||||
sync = (Class<S>) (syncClassName != null ? ClassLoadingUtils.loadClass(getClass(), syncClassName) : null);
|
||||
async = (Class<A>) (asyncClassName != null ? ClassLoadingUtils.loadClass(getClass(), asyncClassName) : null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IllegalArgumentException(
|
||||
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
|
||||
public Module apply(String from) {
|
||||
try {
|
||||
return (Module) Class.forName(from).newInstance();
|
||||
return (Module) ClassLoadingUtils.loadClass(Modules2.class, from).newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new RuntimeException("error instantiating " + from, e);
|
||||
} catch (IllegalAccessException 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.io.CharStreams;
|
||||
import com.google.common.io.Resources;
|
||||
import org.jclouds.util.ClassLoadingUtils;
|
||||
|
||||
/**
|
||||
* Utilities used to build init scripts.
|
||||
|
@ -135,8 +136,8 @@ public class Utils {
|
|||
|
||||
public static String writeFunctionFromResource(String function, OsFamily family) {
|
||||
try {
|
||||
String toReturn = CharStreams.toString(Resources.newReaderSupplier(Resources.getResource(Utils.class, String
|
||||
.format("/functions/%s.%s", function, ShellToken.SH.to(family))), Charsets.UTF_8));
|
||||
String toReturn = CharStreams.toString(Resources.newReaderSupplier(ClassLoadingUtils.loadResource(Utils.class, String
|
||||
.format("/functions/%s.%s", function, ShellToken.SH.to(family))), Charsets.UTF_8));
|
||||
String lf = ShellToken.LF.to(family);
|
||||
return toReturn.endsWith(lf) ? toReturn : new StringBuilder(toReturn).append(lf).toString();
|
||||
} catch (IOException e) {
|
||||
|
|
Loading…
Reference in New Issue