<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">Hey<br>
      <br>
      I need someone to take a look at <a
        href="https://github.com/weld/core/pull/225">https://github.com/weld/core/pull/225</a><br>
      <br>
      My initial change was to add bridge methods to the proxy (when
      proxying an interface), but later realized this could never work,
      because the interceptors expect a Method object that would have to
      point to a non-existing method (the method exists only on the
      proxy, but not on the interface). <br>
      <br>
      That's why the only solution was to make
      Beans.getInterceptableMethods() return the bridge methods also.
      The reason why you guys had problems with this in the past was the
      fact that MethodReference was missing the return type and thus
      treated two methods with the same name and parameters but
      different return types as equal, when they clearly aren't. This is
      why Weld was throwing the duplicate interceptor definition errors.
      <br>
      <br>
      Marko<br>
      <br>
      On 7.9.2012 17:43, Marko Lukša wrote:<br>
    </div>
    <blockquote cite="mid:504A1608.8080602@gmail.com" type="cite">
      <meta content="text/html; charset=windows-1252"
        http-equiv="Content-Type">
      <div class="moz-cite-prefix">Yes, when the proxy extends a class,
        everything is taken care of by the bridge method in the
        superclass. But, when dealing with local EJB interfaces, the
        proxy's superclass is Object, so there is no bridge method at
        all. <br>
        <br>
        For EJBs, the stacktrace would look something like this:<br>
            StringFooImpl.doSth(String)<br>
            StringFooImpl.doSth(Object)<br>
            methodHandler.invoke("doSth(Object)")<br>
            StringFoo$Proxy.doSth(Object)            &lt;-- proxy
        extends Object, implements StringFoo interface (no bridge
        method)<br>
        <br>
        For regular managed beans, the stacktrace would look like this:<br>
            StringFooImpl.doSth(String)<br>
            methodHandler.invoke("doSth(String)")<br>
            StringFooImpl$Proxy.doSth(String)<br>
            StringFooImpl$Proxy.doSth(Object)        &lt;-- proxy
        extends StringFooImpl (and has bridge method)<br>
        <br>
        Note the different methods methodHandler is handling. <br>
        <br>
        Marko<br>
        <br>
        <br>
        On 7.9.2012 17:27, Stuart Douglas wrote:<br>
      </div>
      <blockquote cite="mid:504A126C.4060204@gmail.com" type="cite">
        <meta content="text/html; charset=windows-1252"
          http-equiv="Content-Type">
        IMHO the correct way to deal with this is to simply make bridge
        methods delegate to super(), which will then result in the
        actual intercepted method being called. <br>
        <br>
        To be honest I thought we already did this, as we have had
        multiple related bugs in the past. Do you have a test case that
        I can look at?<br>
        <br>
        Stuart<br>
        <br>
        <blockquote style="border: 0px none;"
          cite="mid:5049BC14.9030108@gmail.com" type="cite">
          <div style="margin:30px 25px 10px 25px;" class="__pbConvHr">
            <div style="display:table;width:100%;border-top:1px solid
              #EDEEF0;padding-top:5px">
              <div
                style="display:table-cell;vertical-align:middle;padding-right:6px;"><img
                  photoaddress="marko.luksa@gmail.com" photoname="Marko
                  Lukša" src="cid:part2.08080201.02050001@gmail.com"
                  name="postbox-contact.jpg" height="25px" width="25px"></div>
              <div
style="display:table-cell;white-space:nowrap;vertical-align:middle;width:100%">
                <a moz-do-not-send="true"
                  href="mailto:marko.luksa@gmail.com"
                  style="color:#737F92
                  !important;padding-right:6px;font-weight:bold;text-decoration:none
                  !important;">Marko Lukša</a></div>
              <div
                style="display:table-cell;white-space:nowrap;vertical-align:middle;">
                <font color="#9FA2A5"><span style="padding-left:6px">7
                    September 2012 7:19 PM</span></font></div>
            </div>
          </div>
          <div style="color:#888888;margin-left:24px;margin-right:24px;"
            __pbrmquotes="true" class="__pbConvBody">
            <meta http-equiv="Content-Type" content="text/html;
              charset=windows-1252">
            Hey all.<br>
            <br>
            I've been working on <a moz-do-not-send="true"
              href="https://issues.jboss.org/browse/WELD-1162"
              class="moz-txt-link-freetext">https://issues.jboss.org/browse/WELD-1162</a>
            and need your opinion.<br>
            <br>
            Say we have:<br>
            <br>
            public interface Foo&lt;T&gt; {<br>
               void doSomething(T t);<br>
            }<br>
            public interface StringFoo extends Foo&lt;String&gt; {}<br>
            public class StringFooImpl implements StringFoo {}<br>
            <br>
            and<br>
            <br>
            @Inject StringFoo stringFoo;<br>
            <br>
            The proxy created by Weld is a subclass of StringFooImpl and
            therefore has two declared methods:<br>
            <br>
            void doSomething(Object o) { doSomething((String) o); }<br>
            void doSomething(String) {...}<br>
            <br>
            However, when StringFooImpl is a session bean, with
            StringFoo as its local interface, the proxy is a subclass of
            Object and therefore the proxy only has the following
            declared method:<br>
            <br>
            void doSomething(Object o);<br>
            <br>
            In both cases, when a client invokes
            stringFoo.doSomething("foo"), the method doSomething(Object)
            is invoked. But there's a difference in what happens next:<br>
            <ul>
              <li>In the non-ejb version, the bridge method then
                immediately invokes doSomething(String) and only then is
                the proxy's method handler invoked. The handler is
                therefore dealing with the method doSomething(<b>String</b>)</li>
              <li>in the EJB version, doSomething(Object) is not a
                bridge method, and so the method handler is invoked
                directly and it (the handler) is operating on
                doSomething(<b>Object</b>).</li>
            </ul>
            <p>In the second case, this ultimately means that Weld will
              check whether doSomething(Object) is intercepted. It
              isn't, since Beans.getInterceptableMethods() is ignoring
              bridge methods. The interceptor will not be invoked. On
              the other hand, in the first case, the interceptor _will_
              be invoked, since Weld will be checking whether
              doSomething(String) is intercepted. <br>
            </p>
            <p>My initial solution was to make
              Beans.getInterceptableMethods() also return bridge
              methods, but now I'm thinking the actual problem is in the
              proxy itself. IMO, when creating a proxy based on an
              interface, we should also generate bridge methods on the
              proxy (this should be either done by Weld or by Javassist
              directly). These bridge methods should be perfectly normal
              bridge methods and should not invoke the method handler
              directly. They should simply invoke the non-bridge method
              and the non-bridge method should then invoke the method
              handler.<br>
            </p>
            <p>The java compiler can't add bridge methods directly to
              interfaces which require them, so it adds them to all the
              classes implementing the interface (StringFooImpl in our
              case). Since we are creating StringFoo$Proxy, which is
              also a class implementing an interface which requires
              bridge methods, we should add the bridge methods <br>
              to it - exactly as the java compiler would.<br>
            </p>
            <p>This would solve the interceptor problem and possibly
              other similar problems as well.<br>
            </p>
            What do you think?<br>
            <p>Marko<br>
            </p>
            <p><br>
            </p>
            <div>_______________________________________________<br>
              weld-dev mailing list<br>
              <a moz-do-not-send="true" class="moz-txt-link-abbreviated"
                href="mailto:weld-dev@lists.jboss.org">weld-dev@lists.jboss.org</a><br>
              <a moz-do-not-send="true" class="moz-txt-link-freetext"
                href="https://lists.jboss.org/mailman/listinfo/weld-dev">https://lists.jboss.org/mailman/listinfo/weld-dev</a></div>
          </div>
        </blockquote>
      </blockquote>
      <br>
    </blockquote>
    <br>
  </body>
</html>