aspectj iajc fails when subclass inherits an intertyped method woven into its base class and defined in a separate jar
I am using aspectJ to inject an interface implementation. Eclipse compiles everything just fine. However the project has to be built with ant as well.
iajc task fails with: " type Foo must implement the inherited abstract method Bar.doThings() " where Bar is the interface that has an interty开发者_如何学Gope (ITD) implementation.
code looks like this (in their respective files):
class Foo extends BaseFoo {...}
abstract class BaseFoo implements Bar {...}
interface Bar{
void doThings{}
public static aspect Implementation {
void Bar.doThings() {
//whatever
}
}
}
weaving messages do show class BaseFoo having the method doThings()
intertyped
but Foo does not.
and consequently fails with "must implement ..." error.
I am pretty sure that I have similar situations working correctly within my common.jar.
This happens when I am compiling another module where Bar is defined and ITD/implemented within the common.jar. The common.jar is specified correctly in <iajc .... aspectPathRef..>
otherwise the BaseFoo
would not have gotten intertyped.
So it looks like the compiler is not seeing the implementation inherited from the base class where it was intertyped.
Here is what iajc looks like :
<iajc destdir="${build.dir}" sourceroots="${javasrc.dir}"` source="1.6" classpathref="classpath" Xlint="warnings" aspectPathRef="aspectlib" showWeaveInfo="true" />
where aspectlib is includes apsectjrt.jar and my common.jar
and one more thing: eclipse project that does compile and run is not divided into common and other modules - all the src dirs are just imported into a single aggregate project.
So please - what is wrong here ?
Here is a link to the bug I submitted to aspectj bugzilla https://bugs.eclipse.org/bugs/show_bug.cgi?id=354683
I distilled the problem down to this : Having aspects and interfaces defined in a jar - hierarchical interfaces and their hierarchical implementations do not get woven correctly in a target project in both eclipse and command line.
Here is all of the code in the "jar" project :
public interface CommonData {void getData();}
public interface CommonDataImpl extends CommonData {}
public aspect CommonDataImplementation {
public void CommonDataImpl.getData() {}
}
public interface DerivedCommonDataInterface extends CommonData {
void getDerivedData();
}
public interface DerivedCommonDataInterfaceImpl
extends DerivedCommonDataInterface, CommonDataImpl {}
public aspect DerivedCommonDataInterfaceImplementation {
public void DerivedCommonDataInterfaceImpl.getDerivedData() {}
}
Note that "derived" interface extends another and so does its implementation extends the "common" implementation.
Here is the whole of the target project:
public abstract class AbstractBaseClass <T extends Whatever>
implements DerivedCommonDataInterfaceImpl {}
public class DerivedClass extends AbstractBaseClass {}
The build.xml files would be a waste of space here - you can download the tar from the bug attachement(link above). So until somebody from aspectj project weighs in on it - this is the answer.
And even though this problem is a pretty serious issue and would make it a showstopper for many situations, I am going to aggregate all of my actual work into a single eclipse/ant project via symlinks or svnexternals or whatever because implementing interfaces via ITD is it - the amount of code I have deleted and have yet to delete thanks to ITD is hard to overestimate.
Big thumbs up to you aspectj people (bugs an' all :)
The way you are describing things, it sounds right. It may be a bug in AspectJ in that static inner aspects and ITDs don't mix across jar files.
I just tried the setup you described in Eclipse and AJDT (not with a jar file, but with separate projects) and it worked fine for me.
First, can you try making the aspect a top-level one?
If that doesn't work, can you distill the problem down to a project that you can attach to a bug report at eclipse.org? If so, I or someone else will take a look at it.
https://bugs.eclipse.org/bugs/
Try to put all your AspetJ related code under inpath tag, rather than aspectPathRef. I have quite complex Ant+AspectJ build. And don't experience such a problems as you.
Here is the structure of my AspectJ build task:
<iajc destDir="${aop.output}" Xlintwarnings="true" showWeaveInfo="true" target="1.6"
source="1.6"
bootclasspathref="android.target.classpath">
<sourceroots>
<path refid="${main.project.sources}" />
</sourceroots>
<inpath>
<path refid="all.your.AspetJ.related.code.from.other.projects "/>
</inpath>
<classpath>
<pathelement location="libs/httpmime-4.0.3.jar"/>
<pathelement location="libs/apache-mime4j-0.6.jar"/>
<pathelement location="libs/commons-io-2.0.1.jar"/>
....
<pathelement location="${aspectj.home}/aspectjrt.jar"/>
</classpath>
</iajc>
As you can see I don't use aspectPathRef at all.
精彩评论