<!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;">
    AbstractRealDeployerWithInput fails to call undeploy() on deployer, for failed deployments
</h3>
<span style="margin-bottom: 10px;">
    created by <a href="http://community.jboss.org/people/jaikiran">jaikiran pai</a> in <i>JBoss Microcontainer</i> - <a href="http://community.jboss.org/message/555208#555208">View the full discussion</a>
</span>
<hr style="margin: 20px 0; border: none; background-color: #dadada; height: 1px;">

<div class="jive-rendered-content"><p><span>While investigating this issue </span><a class="jive-link-external-small" href="http://community.jboss.org/message/555195#555195" target="_blank">http://community.jboss.org/message/555195#555195</a><span>, I have stumbled upon a MC deployer bug. Here's an simplified version of what's happening:</span></p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><pre class="jive-pre"><code class="jive-code jive-java"><font color="navy"><b>public</b></font> <font color="navy"><b>class</b></font> MyDeployer <font color="navy"><b>extends</b></font> AbstractRealDeployerWithInput&lt;JBossEnterpriseBeanMetaData&gt;
&#160;&#160;&#160;&#160;&#160; <font color="navy"><b>implements</b></font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DeploymentVisitor&lt;JBossEnterpriseBeanMetaData&gt;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 
<font color="navy">{</font>
&#160;
...
&#160;&#160; @Override
&#160;&#160; <font color="navy"><b>public</b></font> <font color="navy"><b>void</b></font> deploy(DeploymentUnit unit, JBossEnterpriseBeanMetaData beanMetaData) <font color="navy"><b>throws</b></font> DeploymentException
&#160;&#160; <font color="navy">{</font>
&#160;&#160;&#160;&#160; doStepOne(); <font color="darkgreen">// like register component to some service name</font>
&#160;&#160;&#160;&#160; 
&#160;&#160;&#160;&#160; doStepTwo(); <font color="darkgreen">// can be any operation which ends up throwing an runtime exception</font>
&#160;
&#160;&#160; <font color="navy">}</font>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 
&#160;&#160; 
&#160;&#160; @Override
&#160;&#160; <font color="navy"><b>public</b></font> <font color="navy"><b>void</b></font> undeploy(DeploymentUnit unit, JBossEnterpriseBeanMetaData enterpriseBean)
&#160;&#160; <font color="navy">{</font>
&#160;&#160;&#160;&#160;&#160; undoStepOne(); <font color="darkgreen">// i.e. unregister the service</font>
&#160;&#160; <font color="navy">}</font>
&#160;&#160; 
<font color="navy">}</font>
&#160;
As can be seen, the deploy() involves more than one step. The first step does registering of services (or some functionality internal to my deployer). The second step of deploy() does some other thing but ends up throwing an exception. I would expect that the undeploy() method
would be called on MyDeployer <font color="navy"><b>for</b></font> <font color="navy"><b>this</b></font> (failed) deployment unit, so that I can undo/cleanup whatever was done in doStepOne() of deploy() operation.
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>However, the undeploy() never gets called. Looking at MC's AbstractRealDeployerWithInput.deploy() method:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><pre class="jive-pre"><code class="jive-code jive-java">&#160; <font color="navy"><b>protected</b></font> &lt;U&gt; <font color="navy"><b>void</b></font> deploy(DeploymentUnit unit, DeploymentVisitor&lt;U&gt; visitor) <font color="navy"><b>throws</b></font> DeploymentException
&#160;&#160; <font color="navy">{</font>
&#160;&#160;&#160;&#160;&#160; <font color="navy"><b>if</b></font> (visitor == <font color="navy"><b>null</b></font>)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy"><b>throw</b></font> <font color="navy"><b>new</b></font> IllegalArgumentException(<font color="red">"Null visitor."</font>);
&#160;
&#160;&#160;&#160;&#160;&#160; List&lt;U&gt; visited = <font color="navy"><b>new</b></font> ArrayList&lt;U&gt;();
&#160;&#160;&#160;&#160;&#160; <font color="navy"><b>try</b></font>
&#160;&#160;&#160;&#160;&#160; <font color="navy">{</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Set&lt;? <font color="navy"><b>extends</b></font> U&gt; deployments = unit.getAllMetaData(visitor.getVisitorType());
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy"><b>for</b></font> (U deployment : deployments)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy">{</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; visitor.deploy(unit, deployment);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; visited.add(deployment);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy">}</font>
&#160;&#160;&#160;&#160;&#160; <font color="navy">}</font>
&#160;&#160;&#160;&#160;&#160; <font color="navy"><b>catch</b></font> (Throwable t)
&#160;&#160;&#160;&#160;&#160; <font color="navy">{</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy"><b>for</b></font> (<font color="navy"><b>int</b></font> i = visited.size()-1; i &gt;= 0; --i)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy">{</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy"><b>try</b></font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy">{</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; visitor.undeploy(unit, visited.get(i));
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy">}</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy"><b>catch</b></font> (Throwable ignored)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy">{</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; log.warn(<font color="red">"Error during undeploy: "</font> + unit.getName(), ignored);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy">}</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy">}</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy"><b>throw</b></font> DeploymentException.rethrowAsDeploymentException(<font color="red">"Error deploying: "</font> + unit.getName(), t);
&#160;&#160;&#160;&#160;&#160; <font color="navy">}</font>
&#160;&#160; <font color="navy">}</font>
&#160;&#160; 
&#160;
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>More specifically:</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;&#160; 
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; visitor.deploy(unit, deployment);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; visited.add(deployment);
&#160;
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>visitor.deploy(...) throws the exception and hence the deployment is never added to "visited" which effectively means that in the catch block:</p><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><pre class="jive-pre"><code class="jive-code jive-java"><font color="navy"><b>for</b></font> (<font color="navy"><b>int</b></font> i = visited.size()-1; i &gt;= 0; --i)
<font color="navy">{</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy"><b>try</b></font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy">{</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; visitor.undeploy(unit, visited.get(i));
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy">}</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy"><b>catch</b></font> (Throwable ignored)
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy">{</font>
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; log.warn(<font color="red">"Error during undeploy: "</font> + unit.getName(), ignored);
&#160;&#160;&#160;&#160;&#160;&#160;&#160; <font color="navy">}</font>
<font color="navy">}</font>
&#160;
</code></pre><p style="min-height: 8pt; height: 8pt; padding: 0px;">&#160;</p><p>The "visited" will never contain this failed deployment. Ultimately, the undeploy() will never get called for that failed deployment unit.</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/555208#555208">going to Community</a></p>
        <p style="margin: 0;">Start a new discussion in JBoss Microcontainer at <a href="http://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2114">Community</a></p>
</div></td>
                        </tr>
                    </tbody>
                </table>


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

</div>

</body>
</html>