Bug 404192 - Bug for mailing list post 'Generics in return types causing warnings'
Summary: Bug for mailing list post 'Generics in return types causing warnings'
Status: NEW
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: DEVELOPMENT   Edit
Hardware: PC Mac OS X
: P3 critical (vote)
Target Milestone: ---   Edit
Assignee: aspectj inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-03-22 18:19 EDT by Andrew Clement CLA
Modified: 2021-06-18 06:47 EDT (History)
1 user (show)

See Also:


Attachments
testcode (4.38 KB, application/zip)
2013-03-22 18:19 EDT, Andrew Clement CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Clement CLA 2013-03-22 18:19:17 EDT
Created attachment 228948 [details]
testcode

Hi everybody,

I've been trying to get a hierarchy of classes return defensive copies of instances of the Java Collections Framework. The idea is, that a caller should not be able to add/remove elements of a returned List<?> for instance, because the entity that returned that list should be the one managing it.

I thought of using an aspect, and when trying to do so, I found out that it works, but it produces quite a bunch of warnings in both my Eclipse workspace as well as during weaving during a Maven build. I'm wondering if there's anything I can do to get rid of those warnings.

I wrote the following class to define the aspect (stripped to only contain an example method):

@Aspect
public final class DefensiveCopyCollectionsReturningAspect {

    /**
     * Every 'getter' method in the portal model hierarchy that returns a
     * {@link List} should return a defensive copy so that calling clients
     * don't change the internal structure of the portal model.
     *
     * @param   joinPoint  The joinpoint.
     * @return  An defensive copy of the returned list.
     */
    @SuppressWarnings("unchecked", "rawtypes")
    @Around("execution(public !static java.util.List<*> (AbstractPM+).get*())")
    public List makeDefensiveCopyOfReturnedList(final ProceedingJoinPoint joinPoint) {
        try {
            return new ArrayList((List) joinPoint.proceed());
        } catch (final Throwable exception) {
            throw new PortalRuntimeException(exception);
        }
    }
}

I've defined methods that do similar things for Set and Map as well, which works like a charm. However, since the return type of the method is java.util.List, without any generics involved, I see the following warnings:

-- unchecked conversion when advice applied at shadow method-execution(java.util.List com.leanapps.portal.model.pension.participation.ParticipationPM.getDocuments()), expected java.util.List<com.leanapps.portal.model.report.DocumentPM> but advice uses java.util.List [Xlint:uncheckedAdviceConversion]

Now here's the million (OK, maybe a little less ;)) dollar question: Is there any way to get the generics to work? I've tried several things, but they all don't seem to work. I've tried

    <T> List<T> makeDefensiveCopyOfReturnedList(final ProceedingJoinPoint joinPoint) { .. }

which results in compilation errors:

-- incompatible return type applying to method-execution(java.util.List com.leanapps.portal.model.pension.participation.ParticipationPM.getDocuments())

If I try to add generics to the annotation:

    @Around("execution(public !static java.util.List<T+> (AbstractPM+).get*())")

I see that no advice has been applied at all:

-- advice defined in com.leanapps.portal.model.DefensiveCopyCollectionsReturningAspect has not been applied

Hope that somebody on this list has an answer to this.

Kind regards,

Rens
===============
Hi Andy.

I found a pretty similar problem on StackOverflow:
http://stackoverflow.com/questions/15110442/how-to-handle-generic-result-with-aspectj

Because the guy who asked the question had a lot of dependencies in his
sample code, I reproduced the problem using some dummy classes, see my
answer:
http://stackoverflow.com/a/15448896/1082681

For your convenience I am also adding my sample project for you to play
around with. Maybe it helps to analyse the problem. Good Luck!
--
Alexander Kriegisch
http://scrum-master.de


Andy Clement, 12.02.2013 19:26:
> I'm pretttty sure there are AspectJ bugs in this area that you are
> hitting (around advice and generics). Feels like this kind of thing is
> what you wanted:
>
> <T> List<T> makeDefensiveCopyOfReturnedList(final ProceedingJoinPoint
> joinPoint) { .. }
>
> what compile errors do you get? Maybe raise a bugzilla for it.
>
>
> On 4 February 2013 03:27, Rens van Leeuwen
> <rens.van.leeuwen@leanapps.com <mailto:rens.van.leeuwen@leanapps.com>>
Comment 1 Andrew Clement CLA 2013-06-26 18:23:30 EDT
For now you could probably get rid of the warnings by suppressing them although I must say I'm not 100% sure @SuppressAjWarnings is implemented for "uncheckedAdviceConversion". Making suppression work (if it doesn't) would be much easier than sorting out the generics!

I'm not sure this is supported right now.