<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<body link="#355491" alink="#4262a1" vlink="#355491" style="background: #e2e2e2; margin: 0; padding: 20px;">
<div>
        <table cellpadding="0" bgcolor="#FFFFFF" border="0" cellspacing="0" style="border: 1px solid #dadada; margin-bottom: 30px; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                <tbody>
                        <tr>
                                <td>
                                        <table border="0" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" style="border: solid 2px #ccc; background: #dadada; width: 100%; -moz-border-radius: 6px; -webkit-border-radius: 6px;">
                                                <tbody>
                                                        <tr>
                                                                <td bgcolor="#000000" valign="middle" height="58px" style="border-bottom: 1px solid #ccc; padding: 20px; -moz-border-radius-topleft: 3px; -moz-border-radius-topright: 3px; -webkit-border-top-right-radius: 5px; -webkit-border-top-left-radius: 5px;">
                                                                        <h1 style="color: #333333; font: bold 22px Arial, Helvetica, sans-serif; margin: 0; display: block !important;">
                                                                        <!-- To have a header image/logo replace the name below with your img tag -->
                                                                        <!-- Email clients will render the images when the message is read so any image -->
                                                                        <!-- must be made available on a public server, so that all recipients can load the image. -->
                                                                        <a href="http://community.jboss.org/index.jspa" style="text-decoration: none; color: #E1E1E1">Community</a></h1>
                                                                </td>
                                                        </tr>
                                                        <tr>
                                                                <td bgcolor="#FFFFFF" style="font: normal 12px Arial, Helvetica, sans-serif; color:#333333; padding: 20px; -moz-border-radius-bottomleft: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 5px; -webkit-border-bottom-left-radius: 5px;"><h3 style="margin: 10px 0 5px; font-size: 17px; font-weight: normal;">
JBoss Reflect Performance Javassist vs Introspection
</h3>
<span style="margin-bottom: 10px;">
reply from <a href="http://community.jboss.org/people/flavia.rainone%40jboss.com">Flavia Rainone</a> in <i>JBoss Microcontainer Development</i> - <a href="http://community.jboss.org/message/543946#543946">View the full discussion</a>
</span>
<hr style="margin: 20px 0; border: none; background-color: #dadada; height: 1px;">
<div class="jive-rendered-content"><blockquote class="jive-quote"><p>Kabir Khan wrote:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>Once I am done with caching things as much as possible, we'll see if the classpools are still a bottleneck since there will be a lot less calls. If they are, I have an idea for how to change them into something simpler, but just want to jot it down so Flavia can take a look and see if she thinks it is a good idea or if I have missed something.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>The idea is quite simple, rather than managing the domains and pools and essentially recreating what the classloaders do, it might make sense to delegate everything to the classloaders. If we had a method like this, as I discussed with Ales (let's say it goes in the ClassLoading class, although where is up to Ales):</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><pre class="jive-pre"><code class="jive-code jive-java">ClassLoader getClassLoaderForClass(ClassLoader initiating, String classname);
</code></pre>
<p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p>
<p>And we have a map of classpools by classloader in the classpool registry.</p>
<p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p>
<p>Then I think our "dumb" class pool would not need much more than this - it has a null parent</p>
<p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p>
<p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p>
<pre class="jive-pre"><code class="jive-code jive-java"><span style="color: navy;"><strong>class</strong></span> DumbClassPool <span style="color: navy;"><strong>extends</strong></span> ClassPool<span style="color: navy;">{</span>
    WeakReference<ClassLoader> cl;
    ClassPoolRepository repo;
    DumbClassPool(ClassLoader cl, ClassPoolRepository repo)<span style="color: navy;">{</span>
      this.cl = <span style="color: navy;"><strong>new</strong></span> WeakReference<ClassLoader>(cl);
      this.repo = repo;
    <span style="color: navy;">}</span>
    CtClass get(String classname)<span style="color: navy;">{</span>
        <span style="color: darkgreen;">//Check cache first, if not found then do the rest</span>
        CtClass clazz = super.get0(classname);
        <span style="color: navy;"><strong>if</strong></span> (clazz != <span style="color: navy;"><strong>null</strong></span>)
           <span style="color: navy;"><strong>return</strong></span> clazz;
        String real = adjustForArraysAndPrimitives(classname);
        ClassLoader loader = ClassLoading.getClassLoaderForClass(cl.get(), real);
        ClassPool pool = repo.registerClassLoader(loader);
        <span style="color: navy;"><strong>if</strong></span> (pool != <span style="color: navy;"><strong>null</strong></span>)
        <span style="color: navy;">{</span>
           clazz = pool.getOrNull(classname); <span style="color: darkgreen;">//new method from Chiba that does not throw NFE, but behaves like get()</span>
        <span style="color: navy;">}</span>
        <span style="color: navy;"><strong>if</strong></span> (clazz != <span style="color: navy;"><strong>null</strong></span>)
           <span style="color: darkgreen;">//cache class</span>
        <span style="color: navy;"><strong>else</strong></span>
           <span style="color: navy;"><strong>throw</strong></span> <span style="color: navy;"><strong>new</strong></span> NotFoundException
    <span style="color: navy;">}</span>
<span style="color: navy;">}</span>
</code></pre>
<p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p>
<p>I'd obviously be extending ScopedClassPool or whatever is needed in AOP and other places. It would also have some knowledge of the domain and get notified when loaders get added/removed to the domain so the caches in the pools can be invalidated. There will probably be a bit more to it than this, but this is the basic idea.</p>
<pre ___default_attr="java" jivemacro="code"><p><span style="white-space: pre; font-family: monospace,helvetica,sans-serif;"><br/></span></p></pre>
</blockquote><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>I only see pros at implementing the classpools this way:</p><p>- it is fast to do it. I know that there is a lot of detail that needs to be filled in, but nobody is talking about reimplementing them with the same level of complexity of before</p><p>- it is so clean that we will be able of seeing the real impact of classpools in the performance</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>Regarding the last sentence, as has already been discussed on our team calls, it is not a piece of cake to outperform reflection:</p><p>- it is good that we don't force classes to be loaded... but what if the class has already been loaded? Do we want to use an extra loading level in that case? We can of course try to create a clever mechanism for working around this, but this is more complexity to a code that is already complex.</p><p>- we are doing with Java and Javassist (one more layer of indirection) something that the JDK already does (apart from bytecodes manipulation, of course). After years of JDK improvements, we can expect that they do this natively and fast. The JDK can use its own internal structures (the ones it uses to load and run code) for answering reflection invocations.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>Thus, if we have the cleanest possible implementation of the ClassPools, we have less overhead and we will finally be able to see if it is possible to improve the performance with Javassist/Classpools and to beat our reflection-based implementation. </p><p>This is the main question we've been trying to answer all this time.</p><p>Using the ClassLoaders SPI to find the appropriate ClassLoader/ClassPool is definitely a plus in this regard, as we are using the same ClassLoader structure that the reflection implementation uses.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;"> </p><p>The only drawback is that we won't be able of getting rid of the old structure for AS 4 (ie, erasing all classpool code for as 4), unless we use an older version of the project for JBoss AOP. Which is not really a drawback, it is more like a constraint that we have to face for being backwards compatible with an older version of AS.</p></div>
<div style="background-color: #f4f4f4; padding: 10px; margin-top: 20px;">
<p style="margin: 0;">Reply to this message by <a href="http://community.jboss.org/message/543946#543946">going to Community</a></p>
        <p style="margin: 0;">Start a new discussion in JBoss Microcontainer Development at <a href="http://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2115">Community</a></p>
</div></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>