Bug 76374 - Problem with declare parents when using non-public classes
Summary: Problem with declare parents when using non-public classes
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.2   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 1.5.0 M4   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-10-15 13:23 EDT by Keven Ring CLA
Modified: 2005-09-21 12:50 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Keven Ring CLA 2004-10-15 13:23:09 EDT
Non-public classes, when explicitly named, do not get woven.

The test case below exhibits this problem when the package declaration is
uncommented.

If the package declaration is commented out, the class is woven correctly.
If the package declaration is uncommented, a compilation failure occurs with
AspectJ 1.2.  According to Andrew Clement, AspectJ 1.2.1 compiles, but does not
weave.
If the "MyInnerClass" is changed to be public [regardless of the package
declaration status], the class is woven correctly.

Also:
When the "MyInnerClass" is moved out of "MyClass", but kept in the MyClass.java
file, then the following behavior is exhibited:
If the package declaration is commented out, the class is woven correctly.
If the package declaration is uncommented out, a compilation failure occurs with
AspectJ 1.2.
Note, in this case, MyInnerClass cannot be declared as public.

It also appears that if the RunnableAspect is placed in the same package as
"MyClass", weaving occurs correctly, regardless of any class access modifiers

<MyClass.java>

// package mypackage;

public class MyClass {
 public MyClass() {
   MyInnerClass mic = new MyInnerClass();
   if (mic instanceof Runnable)
     mic.run();
 }

 class MyInnerClass {
   public void run() {
     System.out.println("In MyInnerClass.run()!!");
   }
 }

 public static void main(String args[]) {
   new MyClass();
 }
}

</MyClass.java>

<RunnableAspect.aj>

public aspect RunnableAspect {
 declare parents: MyClass$MyInnerClass implements Runnable;
 // declare parents: mypackage.MyClass$MyInnerClass implements Runnable;
}

</RunnableAspect.aj>
Comment 1 Andrew Clement CLA 2004-10-21 12:47:03 EDT
There is a bug here, but its not what I expected it to be.

When referring to inner classes in type patterns like this, you should use the
'.' notation rather than the $ notation.  So to refer to MyInnerClass, either:

// this works if you import mypackage.*
declare parents: MyClass.MyInnerClass implements Runnable;

// this just works
//declare parents: mypackage.MyClass.MyInnerClass implements Runnable;


What actually causes the confusion is that this works:

declare parents: MyClass$MyInnerClass implements Runnable;

when MyClass is not in a package.  It makes you think that:

declare parents: mypackage.MyClass$MyInnerClass implements Runnable;

should work when you put MyClass into a package.

Actually 'MyClass$MyInnerClass' doesn't refer to an inner class, it refers to a
class called 'MyClass$MyInnerClass' as $ is valid in a class name.  So the bug
is that we should have put out an error indicating no type match for:

declare parents: MyClass$MyInnerClass implements Runnable;

which would have led you to try MyClass.MyInnerClass which is correct.
Comment 2 Adrian Colyer CLA 2005-03-23 08:50:40 EST
scheduled for aj5m4
Comment 3 Adrian Colyer CLA 2005-09-21 12:50:48 EDT
Correctly produces xlint message "no type match for: blah blah" with the latest
compiler builds.