You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by "brian yoder (JIRA)" <ji...@apache.org> on 2014/07/25 01:19:39 UTC
[jira] [Commented] (XALANJ-2589) ObjectFactory is reloading classes
over-and-over causing performance issues with XPATH.
[ https://issues.apache.org/jira/browse/XALANJ-2589?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14073823#comment-14073823 ]
brian yoder commented on XALANJ-2589:
-------------------------------------
Here is a fix, which I think should be checked in. You will notice that it uses Class.forName passing the classLoader as needed, which will ensure the class is cached, and returned WITHOUT loading it each-and-every time.
/**
* Find a Class using the specified ClassLoader
*/
static Class findProviderClass(String className, ClassLoader cl,
boolean doFallback)
throws ClassNotFoundException, ConfigurationError
{
//throw security exception if the calling thread is not allowed to access the
//class. Restrict the access to the package classes as specified in java.security policy.
SecurityManager security = System.getSecurityManager();
try{
if (security != null){
final int lastDot = className.lastIndexOf('.');
String packageName = className;
if (lastDot != -1) packageName = className.substring(0, lastDot);
security.checkPackageAccess(packageName);
}
}catch(SecurityException e){
throw e;
}
Class providerClass=null;
if (cl == null) {
// XXX Use the bootstrap ClassLoader. There is no way to
// load a class using the bootstrap ClassLoader that works
// in both JDK 1.1 and Java 2. However, this should still
// work b/c the following should be true:
//
// (cl == null) iff current ClassLoader == null
//
// Thus Class.forName(String) will use the current
// ClassLoader which will be the bootstrap ClassLoader.
providerClass = Class.forName(className);
} else {
try {
providerClass = Class.forName(className, true, cl);
} catch (ClassNotFoundException x) {
if (doFallback) {
// Fall back to current classloader
ClassLoader current = ObjectFactory.class.getClassLoader();
if (current == null) {
providerClass = Class.forName(className);
} else if (cl != current) {
providerClass = Class.forName(className, true, current);
} else {
throw x;
}
} else {
throw x;
}
}
}
return providerClass;
}
> ObjectFactory is reloading classes over-and-over causing performance issues with XPATH.
> ---------------------------------------------------------------------------------------
>
> Key: XALANJ-2589
> URL: https://issues.apache.org/jira/browse/XALANJ-2589
> Project: XalanJ2
> Issue Type: Bug
> Security Level: No security risk; visible to anyone(Ordinary problems in Xalan projects. Anybody can view the issue.)
> Affects Versions: 2.7.2
> Environment: Glassfish 3.1 with JDK 1.6 u37
> Reporter: brian yoder
> Assignee: Steven J. Hathaway
>
> I have done some performance benchmarking on XPath, and found that the ObjectFactory kept calling findProviderClass, which has code that is calling the following:
> providerClass = cl.loadClass(className);
> This is VERY inefficient, and is causing a severe bottleneck. If i comment this code out, and instead use the following I see a significant performance improvement.
> Class providerClass = Class.forName(className);
> I am running on Glassfish 3.1 - and the bottlneck is really bad because my JAR files were on SAN, so this code is running very slow.
> // Here is the code which I commented out, and rely ONLY on the Class.forName method. Not sure why the other stuff is needed, maybe only to support older JVM's?
> /**
> * Find a Class using the specified ClassLoader
> */
> static Class findProviderClass(String className, ClassLoader cl,
> boolean doFallback)
> throws ClassNotFoundException, ConfigurationError
> {
> //throw security exception if the calling thread is not allowed to access the
> //class. Restrict the access to the package classes as specified in java.security policy.
> SecurityManager security = System.getSecurityManager();
> try{
> if (security != null){
> final int lastDot = className.lastIndexOf('.');
> String packageName = className;
> if (lastDot != -1) packageName = className.substring(0, lastDot);
> security.checkPackageAccess(packageName);
> }
> }catch(SecurityException e){
> throw e;
> }
>
> Class providerClass = Class.forName(className);
> /*
> if (cl == null) {
> // XXX Use the bootstrap ClassLoader. There is no way to
> // load a class using the bootstrap ClassLoader that works
> // in both JDK 1.1 and Java 2. However, this should still
> // work b/c the following should be true:
> //
> // (cl == null) iff current ClassLoader == null
> //
> // Thus Class.forName(String) will use the current
> // ClassLoader which will be the bootstrap ClassLoader.
> providerClass = Class.forName(className);
> } else {
> try {
> providerClass = cl.loadClass(className);
> } catch (ClassNotFoundException x) {
> if (doFallback) {
> // Fall back to current classloader
> ClassLoader current = ObjectFactory.class.getClassLoader();
> if (current == null) {
> providerClass = Class.forName(className);
> } else if (cl != current) {
> cl = current;
> providerClass = cl.loadClass(className);
> } else {
> throw x;
> }
> } else {
> throw x;
> }
> }
> }
> */
> return providerClass;
> }
--
This message was sent by Atlassian JIRA
(v6.2#6252)
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@xalan.apache.org
For additional commands, e-mail: dev-help@xalan.apache.org