SOLR-921 -- SolrResourceLoader must cache short class name vs fully qualified classname

git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@745394 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Shalin Shekhar Mangar 2009-02-18 06:54:10 +00:00
parent bbda7419e5
commit f6185b71a7
2 changed files with 46 additions and 5 deletions

View File

@ -179,6 +179,9 @@ Optimizations
6. SOLR-971: Replace StringBuffer with StringBuilder for instances that do not require thread-safety. 6. SOLR-971: Replace StringBuffer with StringBuilder for instances that do not require thread-safety.
(Kay Kay via shalin) (Kay Kay via shalin)
7. SOLR-921: SolrResourceLoader must cache short class name vs fully qualified classname
(Noble Paul, hossman via shalin)
Bug Fixes Bug Fixes
---------------------- ----------------------
1. SOLR-774: Fixed logging level display (Sean Timm via Otis Gospodnetic) 1. SOLR-774: Fixed logging level display (Sean Timm via Otis Gospodnetic)

View File

@ -23,11 +23,12 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -50,7 +51,6 @@ import org.apache.solr.schema.FieldType;
import org.apache.solr.update.processor.UpdateRequestProcessorFactory; import org.apache.solr.update.processor.UpdateRequestProcessorFactory;
import org.apache.solr.util.plugin.ResourceLoaderAware; import org.apache.solr.util.plugin.ResourceLoaderAware;
import org.apache.solr.util.plugin.SolrCoreAware; import org.apache.solr.util.plugin.SolrCoreAware;
import org.apache.solr.spelling.SpellingQueryConverter;
/** /**
* @since solr 1.3 * @since solr 1.3
@ -258,9 +258,37 @@ public class SolrResourceLoader implements ResourceLoader
return lines; return lines;
} }
/*
* A static map of short class name to fully qualified class name
*/
private static Map<String, String> classNameCache = new ConcurrentHashMap<String, String>();
/**
* This method loads a class either with it's FQN or a short-name (solr.class-simplename or class-simplename).
* It tries to load the class with the name that is given first and if it fails, it tries all the known
* solr packages. This method caches the FQN of a short-name in a static map in-order to make subsequent lookups
* for the same class faster. The caching is done only if the class is loaded by the webapp classloader and it
* is loaded using a shortname.
*
* @param cname The name or the short name of the class.
* @param subpackages the packages to be tried if the cnams starts with solr.
* @return the loaded class. An exception is thrown if it fails
*/
public Class findClass(String cname, String... subpackages) { public Class findClass(String cname, String... subpackages) {
if (subpackages.length==0) subpackages = packages; if (subpackages.length == 0 || subpackages == packages) {
subpackages = packages;
String c = classNameCache.get(cname);
if(c != null) {
try {
return Class.forName(c, true, classLoader);
} catch (ClassNotFoundException e) {
//this is unlikely
log.error("Unable to load cached class-name : "+ c +" for shortname : "+cname + e);
}
}
}
Class clazz = null;
// first try cname == full name // first try cname == full name
try { try {
return Class.forName(cname, true, classLoader); return Class.forName(cname, true, classLoader);
@ -273,13 +301,23 @@ public class SolrResourceLoader implements ResourceLoader
try { try {
String name = base + '.' + subpackage + newName; String name = base + '.' + subpackage + newName;
log.trace("Trying class name " + name); log.trace("Trying class name " + name);
return Class.forName(name, true, classLoader); return clazz = Class.forName(name,true,classLoader);
} catch (ClassNotFoundException e1) { } catch (ClassNotFoundException e1) {
// ignore... assume first exception is best. // ignore... assume first exception is best.
} }
} }
throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, "Error loading class '" + cname + "'", e, false); throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, "Error loading class '" + cname + "'", e, false);
}finally{
//cache the shortname vs FQN if it is loaded by the webapp classloader and it is loaded
// using a shortname
if ( clazz != null &&
clazz.getClassLoader() == SolrResourceLoader.class.getClassLoader() &&
!cname.equals(clazz.getName()) &&
(subpackages.length == 0 || subpackages == packages)) {
//store in the cache
classNameCache.put(cname, clazz.getName());
}
} }
} }