Bug 67579 - NPE on privileged aspect error
Summary: NPE on privileged aspect error
Status: RESOLVED FIXED
Alias: None
Product: AspectJ
Classification: Tools
Component: Compiler (show other bugs)
Version: 1.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 1.2.1   Edit
Assignee: Adrian Colyer CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-06-17 01:50 EDT by Ron Bodkin CLA
Modified: 2004-10-21 04:31 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 Ron Bodkin CLA 2004-06-17 01:50:05 EDT
package b;

import a.*;

privileged aspect B {
  void blah(ITD x) { x.returnNothing("y"); }
}

package a;

public class ITD {
    private void returnNothing(Object a) {
    }
}

Output:
C:\devel\test\priv>ajc a\ITD.aj b\B.aj
C:\devel\test\priv\b\B.aj error Internal compiler error
java.lang.NullPointerException
        at 
org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
.initializeMethodAccessor(SyntheticAccessMethodBinding.java:286)
        at 
org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
.<init>(SyntheticAccessMethodBinding.java:138)
        at 
org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.addSynthet
icMethod(SourceTypeBinding.java:342)
        at 
org.eclipse.jdt.internal.compiler.ast.MessageSend.manageSyntheticAcce
ssIfNecessary(MessageSend.java:140)
        at org.eclipse.jdt.internal.compiler.ast.MessageSend.analyseCode
(Message
Send.java:50)
        at org.eclipse.jdt.internal.compiler.ast.MethodDeclaration.analyseCode
(M
ethodDeclaration.java:70)
        at 
org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.internalAnalyse
Code(TypeDeclaration.java:706)
        at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.analyseCode
(Typ
eDeclaration.java:262)
        at 
org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.anal
yseCode(CompilationUnitDeclaration.java:77)
        at org.eclipse.jdt.internal.compiler.Compiler.process
(Compiler.java:554)

        at org.eclipse.jdt.internal.compiler.Compiler.compile
(Compiler.java:358)

        at 
org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilat
ion(AjBuildManager.java:601)
        at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild
(AjBuild
Manager.java:160)
        at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild
(AjBu
ildManager.java:94)
        at org.aspectj.ajdt.ajc.AjdtCommand.doCommand(AjdtCommand.java:102)
        at org.aspectj.ajdt.ajc.AjdtCommand.runCommand(AjdtCommand.java:53)
        at org.aspectj.tools.ajc.Main.run(Main.java:280)
        at org.aspectj.tools.ajc.Main.runMain(Main.java:217)
        at org.aspectj.tools.ajc.Main.main(Main.java:79)

(no source information available)
ABORT

Exception thrown from AspectJ 1.2

This might be logged as a bug already -- find current bugs at
  http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Compiler

Bugs for exceptions thrown have titles File:line from the top stack,
e.g., "SomeFile.java:243"

If you don't find the exception below in a bug, please add a new bug
at http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AspectJ
To make the bug a priority, please include a test program
that can reproduce this exception.
null
java.lang.NullPointerException
        at 
org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
.initializeMethodAccessor(SyntheticAccessMethodBinding.java:286)
        at 
org.eclipse.jdt.internal.compiler.lookup.SyntheticAccessMethodBinding
.<init>(SyntheticAccessMethodBinding.java:138)
        at 
org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.addSynthet
icMethod(SourceTypeBinding.java:342)
        at 
org.eclipse.jdt.internal.compiler.ast.MessageSend.manageSyntheticAcce
ssIfNecessary(MessageSend.java:140)
        at org.eclipse.jdt.internal.compiler.ast.MessageSend.analyseCode
(Message
Send.java:50)
        at org.eclipse.jdt.internal.compiler.ast.MethodDeclaration.analyseCode
(M
ethodDeclaration.java:70)
        at 
org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.internalAnalyse
Code(TypeDeclaration.java:706)
        at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.analyseCode
(Typ
eDeclaration.java:262)
        at 
org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.anal
yseCode(CompilationUnitDeclaration.java:77)
        at org.eclipse.jdt.internal.compiler.Compiler.process
(Compiler.java:554)

        at org.eclipse.jdt.internal.compiler.Compiler.compile
(Compiler.java:358)

        at 
org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilat
ion(AjBuildManager.java:601)
        at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild
(AjBuild
Manager.java:160)
        at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild
(AjBu
ildManager.java:94)
        at org.aspectj.ajdt.ajc.AjdtCommand.doCommand(AjdtCommand.java:102)
        at org.aspectj.ajdt.ajc.AjdtCommand.runCommand(AjdtCommand.java:53)
        at org.aspectj.tools.ajc.Main.run(Main.java:280)
        at org.aspectj.tools.ajc.Main.runMain(Main.java:217)
        at org.aspectj.tools.ajc.Main.main(Main.java:79)


1 fail|abort, 1 error
Comment 1 Ron Bodkin CLA 2004-06-17 01:50:52 EDT
Appears to be related to bug #67578.
Comment 2 Adrian Colyer CLA 2004-08-09 15:26:53 EDT
marked as target 1.2.1
Comment 3 Andrew Clement CLA 2004-08-16 06:00:28 EDT
Ok, after constantly getting confused on this bug because Ron called one of the
test classes ITD :), I have now worked it out.  It seems to me that using
privileged to enable the calling of private methods really can't be working very
well !

The code was getting in a real mess when working out the accessor method
required.  AspectJ wants to create an accessor for the returnNothing() method
with a name something like ajc$privMethod$<blahblah>.  Now there is accessor
method support for some method references built into the JDT compiler and the
generated accessors have names like access$0() (I think its for things like
calling private methods on a type from an inner type).  These JDT accessors are
not for making private methods globally accessible so they have default
(package) level visibility, unlike the AJC accessors which are declared public.

What is currently happening is that when we first try a visibility test to check
if the aspect can see the method in class ITD, we work out that we should be
able to even though it is private, because we are privileged.  The privileged
handler assigned to the aspect generates a new method accessor in class ITD:

public void ajc$privMethod$b_B$a_ITD$returnNothing(Object obj) {
  returnNothing(obj);
}

That is great.

Then, later on when we are processing the call to the private method in the
aspect (x.returnNothing("y")).  This drops us into
MessageSend.manageSyntheticAccessIfNecessary().  This method has an AspectJ
change in to cope with ITDs but not to cope with private accessors.  Without any
support for identifying calls that are allowed due to the privileged keyword we
actually generate a JDT accessor of the form access$0() in the ITD class.  This
accidentally works when the classes are in the same package because the JDT
generated accessor is default (package) visible.  When the two types are in
different packages the access$0() method can't be seen and we fail.  The NPE
actually reported in the bug is because we are getting much further on through
this processing than we should be.

If you javap what ajc currently produces for two types in the same package that
look like those below, you will see there are multiple accessors in the class,
when there should only be one and the aspect will contain calls to the wrong
accessor.

The fix is in two parts:

- Modify the manageSyntheticAccessIfNecessary() method to check for a privileged
accessor when the method being called is private.
- Modify MessageSend.generateCode() to allow for non-static accessors (i.e. the
AspectJ ones) and use invokevirtual in these cases.

This addresses both bugs on this issue (67578,67579) and is possibly the hardest
bug I've ever fixed.
Comment 4 Andrew Clement CLA 2004-08-16 06:32:26 EDT
I might have spoken too soon about the fix for this also addressing 67578 ...
investigating now ...
Comment 5 Andrew Clement CLA 2004-08-16 15:32:40 EDT
FIXED!

Fix available in:

BUILD COMPLETE -  build.342
Date of build: 08/16/2004 18:17:03
Time to build: 97 minutes 49 seconds
Last changed: 08/16/2004 17:44:55
Latest good AspectJ jar available at:
download.eclipse.org/technology/ajdt/dev/aspectj-DEVELOPMENT.jar
Comment 6 Adrian Colyer CLA 2004-10-21 04:31:50 EDT
Fix released as part of AspectJ 1.2.1