Bug 59440 - NPE when binary weaving a ctor ITD.
Summary: NPE when binary weaving a ctor ITD.
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: ---   Edit
Assignee: Jim Hugunin CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-04-21 10:53 EDT by Andrew Clement CLA
Modified: 2004-04-23 09:27 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 Andrew Clement CLA 2004-04-21 10:53:17 EDT
We need to determine if this needs fixing for final 1.2 - I think it does ...

Here is a simple pair of files:
A.java:
  package P1;
  import P2.B;
  public class A {
    public A() {}
  }

B.java:
package P2;
public interface B {}

Compile them:
ajc -d bin A.java B.java
(Don't use outjar, it affects the result).

Now here is an aspect, Aspect.java:
import P1.*;
aspect Aspect {
  private A.new(B b) {
  }
}

Compile that via binary weaving:

ajc -inpath bin Aspect.java

and you get:

java.lang.NullPointerException
        at 
org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.resolveTypesFor
(SourceTypeBinding.java:837)
        at 
org.aspectj.ajdt.internal.compiler.ast.InterTypeConstructorDeclaration.build
(InterTypeConstructorDeclaration.
java:190)
        at 
org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration.buildInterTypeAndPerCl
ause(AspectDeclaration.java:76
3)
        at 
org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment.buildInterTypeAnd
PerClause(AjLookupEnvironment.
java:214)
        at 
org.aspectj.ajdt.internal.compiler.lookup.AjLookupEnvironment.completeTypeBindi
ngs(AjLookupEnvironment.java:95)
        at org.eclipse.jdt.internal.compiler.Compiler.beginToCompile 
Compiler.java:324)
        at org.eclipse.jdt.internal.compiler.Compiler.compile
(Compiler.java:341)
        at 
org.aspectj.ajdt.internal.core.builder.AjBuildManager.performCompilation
(AjBuildManager.java:600)
        at org.aspectj.ajdt.internal.core.builder.AjBuildManager.doBuild
(AjBuildManager.java:160)
        at org.aspectj.ajdt.internal.core.builder.AjBuildManager.batchBuild
(AjBuildManager.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)

There is actually a problem in the code, the type 'B' referred to in the ctor 
ITD is not imported into the Aspect.  Add a line 'import P2.*;' to Aspect.java 
and the binary weave will go through fine.  So what is going wrong?

=== the fix is as follows:

In InterTypeConstructorDeclaration, we have this piece of code:

public EclipseTypeMunger build(ClassScope classScope) {
  EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(classScope);
  binding = classScope.referenceContext.binding.resolveTypesFor(binding);
  resolveOnType(classScope);
  if (ignoreFurtherInvestigation) return null;
  ...

The resolveTypesFor() call is being made *even though* 
ignoreFurtherInvestigation is false.  If we compare this with the code in the 
other flavor of method ITD (InterTypeMethodDeclaration):

public EclipseTypeMunger build(ClassScope classScope) {
  EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(classScope);
  resolveOnType(classScope);
  if (ignoreFurtherInvestigation) return null;		
  binding = classScope.referenceContext.binding.resolveTypesFor(binding);
  ...

We can see in this second case we check the ignoreFurtherXXX flag before 
attempting to resolve types.  If we fix the build() for the Constructor 
variant of build() to look the same:

public EclipseTypeMunger build(ClassScope classScope) {
  EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(classScope);
  resolveOnType(classScope);
  if (ignoreFurtherInvestigation) return null;		
  binding = classScope.referenceContext.binding.resolveTypesFor(binding);
  ...

Then the test above no longer NPEs and we get the message:

C:\mmo\Aspect.java:4 error B cannot be resolved (or is not a valid type) for 
the argument b of the method A_new2b
private A.new(B b) {
          
1 error, 1 warning


This change passes all the tests in junitModules.xml
		
===
Comment 1 Andrew Clement CLA 2004-04-23 09:27:58 EDT
Whilst integrating the testcase I found an even smaller version:

aspect CtorITD {
  private A.new(B b) {}
}

Just compile that on its own.  NPEs in the same way !

I've added the testcase and the fix.