Community
Participate
Working Groups
Separate compilation of the following program breaks on 1.5.2rc1 because of the recent change to marking aspect methods as synthetic: public aspect Asp { } public class Client { public static void main(String argz[]) { System.out.println("Can call aspectOf? "+Asp.aspectOf()); } } C:\devel\scratch\synthetic>ajc -classpath asp.jar;%CLASSPATH% Client.java C:\devel\scratch\synthetic\Client.java:3 [error] The method aspectOf() is undefi ned for the type Asp System.out.println("Can call aspectOf? "+Asp.aspectOf()); 1 error C:\devel\scratch\synthetic>javac -classpath asp.jar;%CLASSPATH% Client.java Client.java:3: cannot find symbol symbol : method aspectOf() location: class Asp System.out.println("Can call aspectOf? "+Asp.aspectOf()); ^ 1 error Clearly it's vital that external users of a library be able to call API methods like aspectOf on library aspects. This works: C:\devel\scratch\synthetic>ajc *.aj Client.java C:\devel\scratch\synthetic>java Client Can call aspectOf? Asp@b89838 Patch with test integrated into CVS tree to follow...
I think the best fix for this problem would be to enhance the iajc compiler to allow calls to the synthetic aspectOf and hasAspect methods. It's reasonable to require the use of an AspectJ-aware compiler to call these methods. For users who only use javac, they should already be using @AspectJ (i.e., it seems appropriate to fix this with the AspectJ compiler and not require the methods to be visible to javac).
Created attachment 45335 [details] 2 added test cases: integrated compilation works, separate compilation breaks.
thanks for the test programs. Enabling ajc to allow calls to synthetic methods isn't trivial, it requires compiler changes and the changes may have unexpected side effects. Currently the compiler deliberately filters out synthetic methods (and <clinit>s) from types it loads, meaning they are not available when resolving program statements (ofc they still exist in the bytecode). And if we do choose to expose any synthetic methods at all, I'm not sure what impact that has on the rest of the JDT compiler. options appear to be: - go back to the old days of these two methods being AjSynthetic and not 'really' synthetic but ensuring they have a dummy line number table to keep other tools happy (straightforward) - expose all synthetic methods in the compiler as callable (no!) - expose just hasAspect/aspectOf in the compiler as callable (doable, but not something I'd prefer to do in an RC, I'm not sure we can tell that we're loading an aspect at that point either, so may have to make these available for all types - not that they are likely to occur in classes of course. And requires a careful extension to the compiler rather than hacking 'aspectOf/hasAspect' directly into JDT)
Doh. It's obvious in hindsight that this would happen. I think the best solution for 1.5.2 is: "- go back to the old days of these two methods being AjSynthetic and not 'really' synthetic but ensuring they have a dummy line number table to keep other tools happy (straightforward)" it's only two methods, and they are part of the programming model so I guess in this case it's ok to have them not be fully synthetic. We could possibly look at making them truly synthetic and allowing calls to them from in the compiler, but that's a further out thing (and possibly doesn't add much value over the approach above). Note that generating the line number table will be needed if we make them non-synthetic otherwise Emma et al. will break again (but JAXB and ORM tools will be happy).
I've just committed the code to go back to the old way for aspectOf()/hasAspect() - had to modify the existing testcode and I've committed Rons test program too. I've manually inspected that the (fake) line number table was there for the two methods but haven't written a test for it.
fix looks good, thanks Andy. Enjoyed the droids ;)
fix available.