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

_______________________________________________
aspectj-users mailing list
aspectj-users@eclipse.org
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Reply via email to