[ 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