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