001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.discovery;
018
019 import java.net.URL;
020 import java.security.AccessController;
021 import java.security.PrivilegedAction;
022
023 import org.apache.commons.discovery.log.DiscoveryLogFactory;
024 import org.apache.commons.logging.Log;
025
026
027 /**
028 * 'Resource' located by discovery.
029 * Naming of methods becomes a real pain ('getClass()')
030 * so I've patterned this after ClassLoader...
031 *
032 * I think it works well as it will give users a point-of-reference.
033 *
034 * @author Richard A. Sitze
035 */
036 public class ResourceClass extends Resource
037 {
038 private static Log log = DiscoveryLogFactory.newLog(ResourceClass.class);
039 public static void setLog(Log _log) {
040 log = _log;
041 }
042 protected Class resourceClass;
043
044 public ResourceClass(Class resourceClass, URL resource) {
045 super(resourceClass.getName(), resource, resourceClass.getClassLoader());
046 this.resourceClass = resourceClass;
047 }
048
049 public ResourceClass(String resourceName, URL resource, ClassLoader loader) {
050 super(resourceName, resource, loader);
051 }
052
053 /**
054 * Get the value of resourceClass.
055 * Loading the class does NOT guarentee that the class can be
056 * instantiated. Go figure.
057 * The class can be instantiated when the class is linked/resolved,
058 * and all dependencies are resolved.
059 * Various JDKs do this at different times, so beware:
060 * java.lang.NoClassDefFoundError when
061 * calling Class.getDeclaredMethod() (JDK14),
062 * java.lang.reflect.InvocationTargetException
063 * (wrapping java.lang.NoClassDefFoundError) when calling
064 * java.lang.newInstance (JDK13),
065 * and who knows what else..
066 *
067 * @return value of resourceClass.
068 */
069 public Class loadClass() {
070 if (resourceClass == null && getClassLoader() != null) {
071 if (log.isDebugEnabled())
072 log.debug("loadClass: Loading class '" + getName() + "' with " + getClassLoader());
073
074 resourceClass = (Class)AccessController.doPrivileged(
075 new PrivilegedAction() {
076 public Object run() {
077 try {
078 return getClassLoader().loadClass(getName());
079 } catch (ClassNotFoundException e) {
080 return null;
081 }
082 }
083 });
084 }
085 return resourceClass;
086 }
087
088 public String toString() {
089 return "ResourceClass[" + getName() + ", " + getResource() + ", " + getClassLoader() + "]";
090 }
091 }