[ 
https://issues.apache.org/jira/browse/OWB-803?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13655609#comment-13655609
 ] 

Mark Struberg commented on OWB-803:
-----------------------------------

I think this should work already. Can you please retest with owb-1.2.0?
                
> Forever loop when abstract decorator does not implement invoked method
> ----------------------------------------------------------------------
>
>                 Key: OWB-803
>                 URL: https://issues.apache.org/jira/browse/OWB-803
>             Project: OpenWebBeans
>          Issue Type: Bug
>          Components: Interceptor and Decorators
>    Affects Versions: 1.1.7
>            Reporter: Thomas Herzog
>              Labels: decorator
>             Fix For: 1.1.9
>
>         Attachments: DecoratorForeverLoopDemo.zip
>
>
> If there is a decorated service, where the decorator is abstract and does not 
> implement all methods of the interface,
> then there will occur a forever loop within the 
> org.apache.webbeans.decorator.DelegateHandler#invoke(Object instance, Method 
> method, Object[] arguments) (line: 89),
> if a method, which is not implemented in the abstract decorator, is tried to 
> be invoked on the proxied decorator instance.
> This occured within the openEjb-Lite 4.5.1 which uses openwebbeans 1.1.7.
> As we have seen, owb 1.1.6 did implement it differently, so we switched back 
> to OpebEjb-lite 4.5.0 which uses openwebbeans 1.1.6
> {code:title="org.apache.webbeans.decorator.DelegateHandler#invoke(Object 
> instance, Method method, Object[] arguments) openwebbeans 1.1.7"}
>  public Object invoke(Object instance, Method method, Object[] arguments) 
> throws Exception
>     {
>         // Tuck away a reference to the bean being Decorated
>         if (actualInstance == null)
>         {
>             actualInstance = instance;
>         }
>         int hit = 0;
>         int decoratorsSize = decorators.size();
>         while (position.get().intValue() < decoratorsSize)
>         {
>             hit++;
>             // !!!!!! Current position will always be 1, this part is 
> implemented differntly in 1.1.6  !!!!!!
>             int currentPosition = position.get().intValue();
>             Object decorator = 
> decorators.get(position.get().getAndIncrement());
>             try
>             {
>                 Method decMethod = 
> decorator.getClass().getMethod(method.getName(), method.getParameterTypes());
>                 boolean methodInInterface = 
> checkForMethodInInterfaces(decorator.getClass(), method);
>                 if (decMethod != null && methodInInterface)
>                 {
>                     if (!decMethod.isAccessible())
>                     {
>                         
> bean.getWebBeansContext().getSecurityService().doPrivilegedSetAccessible(decMethod,
>  true);
>                     }
>                     try
>                     {
>                         return decMethod.invoke(decorator, arguments);
>                     }
>                     finally
>                     {
>                         if (currentPosition == 0) // if we go back on the 
> first decorator no more need of this thread local
>                         {
>                             position.remove();
>                         }
>                     }
>                 }
>             }
>             catch (SecurityException e)
>             {
>                 logger.log(Level.SEVERE, OWBLogConst.ERROR_0011, 
> WebBeansLoggerFacade.args(method.getName(), decorator.getClass().getName()));
>                 throw new WebBeansException(e);
>             }
>             catch (NoSuchMethodException e)
>             {
>                 continue;
>             }
>             catch (InvocationTargetException e)
>             {
>                 Throwable cause = e.getCause();
>                 //If the wrapped exception tells us the method didn't exist, 
> continue
>                 if(cause instanceof NoSuchMethodException)
>                 {
>                     continue;
>                 }
>                 logger.log(Level.SEVERE, OWBLogConst.ERROR_0012, 
> WebBeansLoggerFacade.args(e.getTargetException(), method.getName(), 
> decorator.getClass().getName()));
>                 if (cause instanceof Exception)
>                 {
>                     throw (Exception) cause;
>                 }
>                 else if (cause instanceof Error)
>                 {
>                     throw (Error) cause;
>                 }
>                 else
>                 {
>                     throw new WebBeansException(e);
>                 }
>             }
>             catch (IllegalAccessException e)
>             {
>                 logger.log(Level.SEVERE, OWBLogConst.ERROR_0014, 
> WebBeansLoggerFacade.args(method.getName(), decorator.getClass().getName()));
>                 throw new WebBeansException(e);
>             }
>         }
>         if (hit == decoratorsSize) // if we hit all decorators but noone was 
> called (see while loop) then clean here
>         {
>             position.remove();
>         }
>         if (!method.isAccessible())
>         {
>             
> bean.getWebBeansContext().getSecurityService().doPrivilegedSetAccessible(method,
>  true);
>         }
>         Object result = null;
>         
>         if(!(bean instanceof EnterpriseBeanMarker))
>         {
>             result = method.invoke(actualInstance, arguments);
>         }
>         else
>         {
>             if(ejbContext != null)
>             {
>                 Method ejbMethod = ejbContext.getMethod();
>                 
>                 // don't use method.equals(), it may only differ by being 
> abstract in the EJB proxy.
>                  
>                 if (method.getName().equals(ejbMethod.getName()) && 
>                         
> method.getReturnType().equals(ejbMethod.getReturnType())) 
>                 {
>                     result = ejbContext.proceed();
>                 }
>                 else 
>                 {
>                     Object ejbInstance = ejbContext.getTarget();
>                     result = method.invoke(ejbInstance, arguments);
>                 }
>             }
>         }
>         return result;
>     }
> {code}
> {code:title="org.apache.webbeans.decorator.DelegateHandler#invoke(Object 
> instance, Method method, Object[] arguments) openwebbeans 1.1.6"}
>    public Object invoke(Object instance, Method method, Object[] arguments) 
> throws Exception
>     {
>         // Tuck away a reference to the bean being Decorated
>         if (actualInstance == null)
>         {
>             actualInstance = instance;
>         }
>         while (position.get().intValue() < decorators.size())
>         {
>                   // !!!! No current position occurs here !!!!!
>                       // !!!! This works when not implemented method of 
> abstract decorator is tried to be invoked !!!!!
>             Object decorator = 
> decorators.get(position.get().getAndIncrement());
>             try
>             {
>                 Method decMethod = 
> decorator.getClass().getMethod(method.getName(), method.getParameterTypes());
>                 boolean methodInInterface = 
> checkForMethodInInterfaces(decorator.getClass(), method);
>                 if (decMethod != null && methodInInterface)
>                 {
>                     if (!decMethod.isAccessible())
>                     {
>                         
> bean.getWebBeansContext().getSecurityService().doPrivilegedSetAccessible(decMethod,
>  true);
>                     }
>                     Object returnValue = decMethod.invoke(decorator, 
> arguments);
>                     position.remove();
>                     return returnValue;
>                 }
>             }
>             catch (SecurityException e)
>             {
>                 logger.log(Level.SEVERE, OWBLogConst.ERROR_0011, 
> WebBeansLoggerFacade.args(method.getName(), decorator.getClass().getName()));
>                 throw new WebBeansException(e);
>             }
>             catch (NoSuchMethodException e)
>             {
>                 continue;
>             }
>             catch (InvocationTargetException e)
>             {
>                 Throwable cause = e.getCause();
>                 //If the wrapped exception tells us the method didn't exist, 
> continue
>                 if(cause instanceof NoSuchMethodException)
>                 {
>                     continue;
>                 }
>                 logger.log(Level.SEVERE, OWBLogConst.ERROR_0012, 
> WebBeansLoggerFacade.args(e.getTargetException(), method.getName(), 
> decorator.getClass().getName()));
>                 if (cause instanceof Exception)
>                 {
>                     throw (Exception) cause;
>                 }
>                 else if (cause instanceof Error)
>                 {
>                     throw (Error) cause;
>                 }
>                 else
>                 {
>                     throw new WebBeansException(e);
>                 }
>             }
>             catch (IllegalAccessException e)
>             {
>                 logger.log(Level.SEVERE, OWBLogConst.ERROR_0014, 
> WebBeansLoggerFacade.args(method.getName(), decorator.getClass().getName()));
>                 throw new WebBeansException(e);
>             }
>         }
>         position.remove();
>         if (!method.isAccessible())
>         {
>             
> bean.getWebBeansContext().getSecurityService().doPrivilegedSetAccessible(method,
>  true);
>         }
>         Object result = null;
>         
>         if(!(bean instanceof EnterpriseBeanMarker))
>         {
>             result = method.invoke(actualInstance, arguments);
>         }
>         else
>         {
>             if(ejbContext != null)
>             {
>                 Method ejbMethod = ejbContext.getMethod();
>                 
>                 // don't use method.equals(), it may only differ by being 
> abstract in the EJB proxy.
>                  
>                 if (method.getName().equals(ejbMethod.getName()) && 
>                         
> method.getReturnType().equals(ejbMethod.getReturnType())) 
>                 {
>                     result = ejbContext.proceed();
>                 }
>                 else 
>                 {
>                     Object ejbInstance = ejbContext.getTarget();
>                     result = method.invoke(ejbInstance, arguments);
>                 }
>             }
>         }
>         
>         return result;
>     }
> {code}

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to