0

I am working with AspectJ at the moment. I seperated AspectJ code in a dependency. Within that dependency everything works as intended. But as soon as I import it in another project only some functionality does not work anymore. When using the defaultImpl of @DeclareParents, the interface is shown within the compiled code but not the default Implementation. Here is my code to show what I mean (every code snippet is its own File):

AspectJ code:

public interface IAspect
{
    String hello();
}

public class IAspectDefaultImpl implements IAspect
{
    @Override
    public String hello()
    {
        return "hello";
    }
}
@Aspect
public class AspectJ
{

    @DeclareParents(value = "@SomeAnnotation*", defaultImpl = IAspectDefaultImpl.class)
    private IAspect implementedInterface;
}

Target Class in a different project:

@SomeAnnotation
public class MyClass
{
    private final int myValue;

    public MyClass(final int wert)
    {
        this.myValue = wert;
    }


    public int getMyValue()
    {
        return myValue;
    }
}

Maven throws me:

The type MyClass must implement the inherited abstract method IAspect.hello()

Which implies that it works partially. When looking at the decompiled .class files the targeted Class does in fact implement IAspect. The method defined in IAspectDefaultImpl is still missing tho.

My pom is set up like in this example.

I am not sure where I should start to look for errors. Any help is apreciated.

Leslie
  • 333
  • 1
  • 3
  • 12
  • I think I can help you analyse this if you would be so kind as to push an [MCVE](https://stackoverflow.com/help/mcve) including Maven POMs to GitHub. I like to see your exact POM contents and which classes belong to which module. BTW, the same error can also occur in Eclipse with AJDT installed when you change something in the target class if everything is in one module. There it helps to recompile the project or the aspect. There might be a similar race condition or inconsistency in the compilation order of your own project. – kriegaex Dec 25 '19 at 05:09
  • Besides, `@SomeAnnotation*` definitely will not work because it is syntactically incorrect as a pointcut describing a set of classes. I fixed that locally in my project, but still I would like to see your full project. I don't want to recreate your project from scratch and while doing so also make guesses about how exactly you might have done what. Your sample code does not even include package names. – kriegaex Dec 25 '19 at 05:16
  • @kriegaex I uploaded a [MCVE](https://github.com/LeslieM98/Aspect-MCVE) first mvn install the lib, then try to compile the other directory. It should throw some compile error about non implemented methods. I hope that helps – Leslie Dec 30 '19 at 14:26

1 Answers1

1

Thanks for the MCVE. But hey, you don't use Git in order to commit 7z or ZIP archives, you ought to commit source code. I forked your project and fixed that, restructured and simplified your POMs and also fixed the main problem.

See my pull request and the commits in it for further details.


Concerning your problem, I can confirm that it occurs if you use @DeclareParents the way you do in an aspect library.

Actually, according to AspectJ maintainer Andy Clement there are certain problems with @DeclareParents when using it to provide parent interfaces + implementations in annotation style. The native AspectJ syntax via declare parents is not affected by that, but for annotation-style syntax Andy provided an alternative called @DeclareMixin, see the AspectJ manual. There he mentions that he is even considering to deprecate the defaultImpl argument of @DeclareParents in favour of @DeclareMixin.

So my bugfix (or workaround) for your problems is to actually replace

@DeclareParents(value = "@de.example.aspect.SomeAnnotation *", defaultImpl = IAspectDefaultImpl.class)
private IAspect implementedInterface;

by

@DeclareMixin("@de.example.aspect.SomeAnnotation *")
public static IAspect createIAspectImplementation() {
    return new IAspectDefaultImpl();
}

This works with aspect libraries.

I will discuss with Andy about whether it makes sense to file a bug ticket for your problem or if he won't fix it anyway because there is a viable and recommended alternative.

kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • Thank you, that solved my problem. I just asked myself another question. When I declare a hashCode method within the IAspect interface. And implement that inside IaspectDefaultImpl. It is also not generated. I imagine that AspectJ somehow prohibits the implementation of non abstract Methods. Are there any resources on that? I could not find any. – Leslie Jan 02 '20 at 08:30
  • Please ask a new question with sample code, ideally an [MCVE](https://stackoverflow.com/help/mcve). I will be glad to take a look. – kriegaex Jan 02 '20 at 13:19