Community
Participate
Working Groups
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
Appears to be related to bug #67578.
marked as target 1.2.1
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.
I might have spoken too soon about the fix for this also addressing 67578 ... investigating now ...
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
Fix released as part of AspectJ 1.2.1