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

David Blevins commented on OWB-306:
-----------------------------------

Here is the basic code we use in OpenEJB for this.  Essentially all annotated 
methods we find are collected as CallbackInfo objects (that part is not 
important) then we go back and find the first method of that name+params by 
starting at the top of the inheritance and going backwards till we hit 
something (important) then we check to see if the declaring classes are the 
same, if they are not we throw the entry away as that means the method was 
overridden in a subclass.  We don't need to check if that method itself is 
annotated with the callback annotation because if it was there will be another 
CallbackInfo in the list for it, so we can just ignore that aspect and let it 
be found when it comes up in the list.

{code}
    public static class CallbackInfo extends InfoObject {
        public String className;
        public String method;
    }

    /**
     * Used for getting the java.lang.reflect.Method objects for the following 
callbacks:
     *
     *  - @PostConstruct <any-scope> void <method-name>(InvocationContext)
     *  - @PreDestroy <any-scope> void <method-name>(InvocationContext)
     *  - @PrePassivate <any-scope> void <method-name>(InvocationContext)
     *  - @PostActivate <any-scope> void <method-name>(InvocationContext)
     *  - @AroundInvoke <any-scope> Object <method-name>(InvocationContext) 
throws Exception
     *
     * @param clazz
     * @param callbackInfos the raw CallbackInfo objects
     * @param methods the collection where the created methods will be placed
     */
    private void toMethods(Class clazz, List<CallbackInfo> callbackInfos, 
List<Method> methods) {
        for (CallbackInfo callbackInfo : callbackInfos) {
            try {
                Method method = getMethod(clazz, callbackInfo.method, 
InvocationContext.class);
                if (callbackInfo.className == null && 
method.getDeclaringClass().equals(clazz)){
                    methods.add(method);
                }
                if 
(method.getDeclaringClass().getName().equals(callbackInfo.className)){
                    methods.add(method);
                }
            } catch (NoSuchMethodException e) {
                logger.warning("Interceptor method not found (skipping): public 
Object " + callbackInfo.method + "(InvocationContext); in class " + 
clazz.getName());
            }
        }

        // I can't remember why we sort them, think it's just for easy debugging
        Collections.sort(methods, new MethodCallbackComparator());
    }

    /**
     * Used by toMethods and toCallbacks to find the nearest 
java.lang.reflect.Method with the given
     * name and parameters.  Callbacks can be private so class.getMethod() 
cannot be used.  Searching
     * starts by looking in the specified class, if the method is not found 
searching continues with
     * the immediate parent and continues recurssively until the method is 
found or java.lang.Object
     * is reached.  If the method is not found a NoSuchMethodException is 
thrown.
     *
     * @param clazz
     * @param methodName
     * @param parameterTypes
     * @return
     * @throws NoSuchMethodException if the method is not found in this class 
or any of its parent classes
     */
    private Method getMethod(Class clazz, String methodName, Class... 
parameterTypes) throws NoSuchMethodException {
        NoSuchMethodException original = null;
        while (clazz != null){
            try {
                Method method = clazz.getDeclaredMethod(methodName, 
parameterTypes);
                return SetAccessible.on(method);
            } catch (NoSuchMethodException e) {
                if (original == null) original = e;
            }
            clazz = clazz.getSuperclass();
        }
        throw original;
    }
{code}


> overrridden @AroundInvoke and lifecycle interceptors are still run
> ------------------------------------------------------------------
>
>                 Key: OWB-306
>                 URL: https://issues.apache.org/jira/browse/OWB-306
>             Project: OpenWebBeans
>          Issue Type: Bug
>    Affects Versions: M3
>            Reporter: Eric Covener
>            Assignee: Eric Covener
>             Fix For: 1.0.0
>
>   Original Estimate: 8h
>  Remaining Estimate: 8h
>
> Interceptor spec says:
> ---
> If an around-invoke method is overridden by another method (regardless of 
> whether that method is itself an around-invoke method), it will not be 
> invoked.
> If a lifecycle callback interceptor method is overridden by another method 
> (regardless of whether that
> method is itself a lifecycle callback interceptor method (of the same or 
> different type)), it will not be
> invoked.
> ---
> I don't have a fix for this issue, but it is at least conceptually pretty 
> easy to grok.
> It seems that we can't just check the stack or even all enabled interceptors

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to