<!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">JBoss 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;">
    VerifyError when invoking a modified method
</h3>
<span style="margin-bottom: 10px;">
    created by <a href="http://community.jboss.org/people/ahmed.s.mostafa">Ahmed Mostafa</a> in <i>Javassist</i> - <a href="http://community.jboss.org/message/574803#574803">View the full discussion</a>
</span>
<hr style="margin: 20px 0; border: none; background-color: #dadada; height: 1px;">

<div class="jive-rendered-content"><p>Hello everyone,</p><p>I'm working on a demo for dependency injection automation. My work is divided between creating new classes and modifying an existing class.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>The new generated classes are running fine when trying to instantiate them from any new java program I create.</p><p>However, the modified class isn't running and throws the following exception, although I'm able to use the three classes within eclipse; i can browse the methods, I can even decompile them and see to the generated code, it is only a matter of running the main (existing) class:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><pre class="jive-pre"><code class="jive-code jive-java">Exception in thread <font color="red">"main"</font> java.lang.VerifyError: (<font color="navy"><b>class</b></font>: generated/myjseuss/EmailSender, method: sendEmail signature: (Lch/unibnf/scg/sample/model/Email;)V) Bad type in putfield/putstatic
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>The modifications I do are the following:</p><p>1- create Guice binder instance variable.</p><p>2- create Guice injector instance variable.</p><p>3- add the instance variables (CtField) into the target class.</p><p>4- I have faced some troubles for initializing the objects, only the following approach worked with me:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><pre class="jive-pre"><code class="jive-code jive-java">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;String constructorSrc = <font color="red">""</font>;
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;String constructBinder = <font color="red">"dummyBinder"</font> + <font color="red">" = new "</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;+ ctGuiceBinder.getName() + <font color="red">"();"</font>;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;String constructInjector = <font color="red">"dummyInjector"</font> + <font color="red">" = "</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;+ Guice.class.getName()
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;+ <font color="red">".createInjector( new com.google.inject.Module[]{"</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;+ <font color="red">"dummyBinder"</font> + <font color="red">"});"</font>;
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;String binderEqual = binderField.getName() + <font color="red">" = dummyBinder;"</font>;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;String injectorEqual = injectorField.getName() + <font color="red">" = dummyInjector;"</font>;
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ctConstructor.addLocalVariable(<font color="red">"dummyBinder"</font>,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;binderField.getType());
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ctConstructor.addLocalVariable(<font color="red">"dummyInjector"</font>,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;injectorField.getType());
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;constructorSrc = <font color="red">"{"</font> + constructBinder + constructInjector
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;+ <font color="red">"}"</font>;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ctConstructor.insertAfter(constructorSrc);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;constructorSrc = <font color="red">"{"</font> + binderEqual + <font color="red">"\n"</font> + injectorEqual
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;+ <font color="red">"};"</font>;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ctConstructor.insertAfter(constructorSrc);
&#160;
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">private static void createConstructor(CtClass ctContainer,</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">CtClass ctGuiceBinder, CtField binderField, CtField injectorField)</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">throws CannotCompileException, NotFoundException {</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">String constructorSrc = "";</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"> </div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">String constructBinder = "dummyBinder" + " = new "</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">+ ctGuiceBinder.getName() + "();";</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">String constructInjector = "dummyInjector" + " = "</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">+ Guice.class.getName()</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">+ ".createInjector( new com.google.inject.Module[]{"</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">+ "dummyBinder" + "});";</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"> </div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">String binderEqual = binderField.getName() + " = dummyBinder;";</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">String injectorEqual = injectorField.getName() + " = dummyInjector;";</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"> </div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">CtConstructor[] inits = ctContainer.getConstructors();</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">if (inits != null &amp;&amp; inits.length &gt; 0) {</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">for (CtConstructor ctConstructor : inits) {</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">ctConstructor.addLocalVariable("dummyBinder",</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">binderField.getType());</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">ctConstructor.addLocalVariable("dummyInjector",</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">injectorField.getType());</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">constructorSrc = "{" + constructBinder + constructInjector</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">+ "}";</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">ctConstructor.insertAfter(constructorSrc);</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"> </div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">constructorSrc = "{" + binderEqual + "\n" + injectorEqual</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">+ "};";</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">ctConstructor.insertAfter(constructorSrc);</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">}</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">} else {</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">String constructorPrefix = "public " + ctContainer.getSimpleName()</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">+ "(){";</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">String constructorSuffix = "}";</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"> </div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">// create a new constructor</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">constructorSrc = constructorPrefix + constructBinder</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">+ constructInjector + constructorSuffix;</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">CtConstructor constructor = CtNewConstructor.make(constructorSrc,</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">ctContainer);</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">ctContainer.addConstructor(constructor);</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">}</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">}String constructorSrc = "";</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"> </div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space:pre"> </span>String constructBinder = "dummyBinder" + " = new "</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space:pre"> </span>+ ctGuiceBinder.getName() + "();";</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space:pre"> </span>String constructInjector = "dummyInjector" + " = "</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space:pre"> </span>+ Guice.class.getName()</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space:pre"> </span>+ ".createInjector( new com.google.inject.Module[]{"</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space:pre"> </span>+ "dummyBinder" + "});";</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"> </div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space:pre"> </span>String binderEqual = binderField.getName() + " = dummyBinder;";</div><div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;"><span style="white-space:pre"> </span>String injectorEqual = injectorField.getName() + " = dummyInjector;";</div><p>5- I'm changing the data type of one of the class instance variables to another interface type; which I then inject its concrete implementation using Guice, as follows:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><pre class="jive-pre"><code class="jive-code jive-java">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<font color="navy"><b>if</b></font> (ctField.getType().equals(ctCurrentType)) <font color="navy">{</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ctField.setType(ctNewType);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ctContainer.instrument(<font color="navy"><b>new</b></font> NewGuiceExprEditor(ctCurrentType,
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ctNewType, injectorField));
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<font color="navy">}</font>
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>6- The ExprEditor replaces the "new" expression with the injector's getInstance method, as follows:</p><p><pre class="jive-pre"><code class="jive-code jive-java">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;String replacement = <font color="red">"$_= ("</font> + (ctInterfaceType.getName()) + <font color="red">")"</font> + injectorField.getName()
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;+ <font color="red">".getInstance("</font> + ctInterfaceType.getName()
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;+ <font color="red">".class);"</font>;
&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;e.replace(replacement);
</code></pre></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>As I said earlier, the generated .class files are well accepted by eclipse (Helios), decompiling the .class files (including the above) to Java is also ok and no problems at all when running them.</p><p>I'm using Javassist 3.14.0GA on Windows XP with JDK 1.6</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p><strong>The generated bytecode are attached a long with a demo sample.<br/></strong></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>I will really appreciate your feedback asap.</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p><strong>NOTE</strong>: the sample demo needs Google Guice jars (guice-2.0.jar, aopalliance.jar, guice-assistedinject-2.0.jar)</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p><strong>Your quick response is highly appreciated.</strong></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>Thanks, Ahmed.</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/574803#574803">going to Community</a></p>
        <p style="margin: 0;">Start a new discussion in Javassist at <a href="http://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2062">Community</a></p>
</div></td>
                        </tr>
                    </tbody>
                </table>


                </td>
            </tr>
        </tbody>
    </table>

</div>

</body>
</html>