[
https://issues.apache.org/jira/browse/OWB-803?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Romain Manni-Bucau closed OWB-803.
----------------------------------
Resolution: Fixed
Assignee: Romain Manni-Bucau
works on 1.2.0/openejb 4.6.0-SNAPSHOT
> 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
> Assignee: Romain Manni-Bucau
> Labels: decorator
> Fix For: 1.2.0
>
> 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