Reputation: 1687
I have an aspect (written with aspectj syntax public aspect ....
) that manipulates the result of many methods that return a Collection
in order to paginate the result.
I can't (or I don't know how to) use generics in advices, so wherever I call one of the advised methods I get the warning
unchecked conversion when advice applied at shadow method-call(java.util.Collection ...), expected java.util.Collection<T> but advice uses java.util.Collection [Xlint:uncheckedAdviceConversion]
How can I get rid of this?
Stefano
-- Adding aspect code excerpt
public aspect PaginationSupportAspect extends ServiceSupportAspect {
private static final Logger log = LoggerFactory.getLogger(PaginationSupportAspect.class);
private pointcut paginate(Criteria criteria) : call(Collection org.jcz.persistence.Service+.*(Criteria));
@SuppressWarnings({ "unchecked", "rawtypes" })
Collection around(Criteria criteria, Service service) : paginate(criteria) && target(service) {
log.trace(String.format("Executing <%s> @ <%s>", this.getClass(), thisJoinPoint.toLongString()));
return doPaginate(proceed(criteria, service), criteria.getPagination(), service);
}
/**
*
* @param source
* @param criteria
* @return
*/
private <T extends EntitySupport> Collection<T> doPaginate(Collection<T> source, Pagination pagination, Service<T> service) {
// IMPLEMENTATION OMITTED BECAUSE IT'S QUITE LONG
// What it does is to create another Collection<T> that holds the pagination coordinates (page number, size, count)
// and only the elements of the requested page
}
}
Usage example
Collection<MyEntity> entities = myEntityService.findAll(criteria);
That's where I get the warning
Upvotes: 0
Views: 838
Reputation: 67297
The bad news: I do not know how to avoid the warning because I am not so proficient in Java generics, specifically not in connection with AspectJ because there not everything you might expect is syntactically allowed, e.g. binding the target()
to a parametrised type (because of type erasure limitations).
Probably you are having the same problem as this one on the AspectJ mailing list.
The good news: I finally managed to reproduce your problem with a minimal code sample, using a lot of dummy classes, doing some educated guesses about how you use them in your application:
Dummy/helper classes/aspects:
package org.jcz.persistence;
public class EntitySupport {}
package org.jcz.persistence;
public class MyEntity {}
package org.jcz.persistence;
public class Pagination {}
package org.jcz.persistence;
public class Criteria {
public Pagination getPagination() {
return new Pagination();
}
}
package org.jcz.persistence;
import java.util.ArrayList;
import java.util.Collection;
public class Service<T> {
public Collection<T> findAll(Criteria criteria) {
return new ArrayList<T>();
}
}
package org.jcz.persistence;
public abstract aspect ServiceSupportAspect {}
Your aspect, slightly changed:
package org.jcz.persistence;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.log4j.Logger;
public aspect PaginationSupportAspect extends ServiceSupportAspect {
private static final Logger log = Logger.getLogger(PaginationSupportAspect.class);
private pointcut paginate(Criteria criteria) :
call(Collection org.jcz.persistence.Service+.*(Criteria)) && args(criteria);
@SuppressWarnings({ "unchecked", "rawtypes" })
Collection around(Criteria criteria, Service service) : paginate(criteria) && target(service) {
log.trace(String.format("Executing <%s> @ <%s>", this.getClass(), thisJoinPoint.toLongString()));
return doPaginate(proceed(criteria, service), criteria.getPagination(), service);
}
private <T extends EntitySupport> Collection<T> doPaginate(
Collection<T> source, Pagination pagination, Service<T> service)
{
System.out.println("doPaginate");
return new ArrayList<T>();
}
}
And now a little driver application reproducing the Xlint warning:
import java.util.Collection;
import org.jcz.persistence.Criteria;
import org.jcz.persistence.MyEntity;
import org.jcz.persistence.Service;
public class Application {
public static void main(String[] args) {
Service<MyEntity> myEntityService = new Service<MyEntity>();
Criteria criteria = new Criteria();
Collection<MyEntity> entities = myEntityService.findAll(criteria);
System.out.println("Found entities: " + entities);
}
}
Maybe someone else can make something of it which I cannot. The best I could do was reproduce it. I will try to point Andy Clement to this post. Good luck!
Upvotes: 1