Bug 262953 - [model] NPE on AJCodeElement.getNameRange
Summary: [model] NPE on AJCodeElement.getNameRange
Status: RESOLVED FIXED
Alias: None
Product: AJDT
Classification: Tools
Component: Core (show other bugs)
Version: 1.6.3   Edit
Hardware: Macintosh Mac OS X - Carbon (unsup.)
: P3 major (vote)
Target Milestone: 1.6.4   Edit
Assignee: AJDT-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 264563
  Show dependency tree
 
Reported: 2009-01-29 14:15 EST by Johan Fabry CLA
Modified: 2009-03-13 13:21 EDT (History)
1 user (show)

See Also:


Attachments
Hierarchy printout (15.33 KB, text/plain)
2009-02-09 17:27 EST, Johan Fabry CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Johan Fabry CLA 2009-01-29 14:15:45 EST
Build ID: M20080911-1700 

Steps To Reproduce:
Get a ref to a AJProjectModelFacade for the project of the AJ SpaceWar example. (say "model")
AJRelationshipType[] relsTypes = {AJRelationshipManager.ADVISED_BY};
List<IRelationship> rels = (List<IRelationship>) model.getRelationshipsForProject(relsTypes);
for (IRelationship rel : rels) {
IJavaElement source = model.programElementToJavaElement(rel.getSourceHandle());
if(source instanceof AJCodeElement)
 ((AJCodeElement)source).getNameRange();
}
}
(NPE for all relationships in SpaceWar)


More information:
Problem is when AJProjectModelFacade.javaElementToProgramElement returns a IHierarchy.NO_STRUCTURE; 

Relevant stack trace:
java.lang.NullPointerException
	at org.eclipse.ajdt.core.javaelements.AJCodeElement.initializeLocations(AJCodeElement.java:74)
	at org.eclipse.ajdt.core.javaelements.AJCodeElement.getNameRange(AJCodeElement.java:52)
Comment 1 Andrew Eisenberg CLA 2009-01-29 14:20:46 EST
I should put a null check in there just in case, but the real problem seems to be that the handle isn't being created properly.  That is why you are getting IHierarchy.NO_STRUCTURE.

Surprised this has never been triggered before.
Comment 2 Johan Fabry CLA 2009-01-29 17:30:58 EST
(In reply to comment #1)

> Surprised this has never been triggered before.

I guess that's why it's called "research" ;-) 

Comment 3 Andrew Eisenberg CLA 2009-01-29 18:40:46 EST
Hmmm...trying to reproduce this right now and can't.

All of the AJCodeElements in the SpaceWar project seem to have valid handle identifiers and I can successfully call the getNameRange on them.

A couple of possibilities:
1. by the time you call this, the model that you are holding may no longer be valid (would be the case if a build occurs after you create the reference)
2. perhaps the model is not initialized yet (ie- no successful build of the project has occurred)
3. perhaps you are using a model for a different project.

If you can send me a handle that is not working for you, then I can explore further.



Could this have something to do with bug 262943 that you also raised?  I will find out.
Comment 4 Johan Fabry CLA 2009-01-30 09:26:39 EST
(In reply to comment #3)
> Hmmm...trying to reproduce this right now and can't.

:-( I got this NPE for all AJCodeElements that I iterated over. I simply added the project doing new->other->aspectj->aspectj examples->spacewar example. None of your possibilities seem to cover my case.

I tried again by making a new AJ project and then importing the files from spacewar. Now not all of the AJCodeElements throw a NPE. I guess eclipse is behaving randomly again.

> If you can send me a handle that is not working for you, then I can explore
> further.

Some offending identifiers: (obtained through calling getHandleIdentifier() on the offending AJCodeElements)
=Spacewar Example/src<spacewar{Robot.java[Robot~run?method-call(void spacewar.Ship.rotate(int))!0!0!0!0!I

=Spacewar Example/src<spacewar{Game.java[Game~Game~QString;?constructor-call(void spacewar.Timer.<init>(spacewar.Game))!0!0!0!0!I

=Spacewar Example/src<spacewar{Game.java[Game~newRobot~I?method-call(spacewar.Ship spacewar.Game.newShip(spacewar.Pilot))!0!0!0!0!I

=Spacewar Example/src<spacewar{Game.java[Game~newRobot~I?method-call(spacewar.Ship spacewar.Game.newShip(spacewar.Pilot))!0!0!0!0!I

=Spacewar Example/src<spacewar{Robot.java[Robot~run?method-call(void spacewar.Ship.thrust(boolean))!0!0!0!0!I

=Spacewar Example/src<spacewar{EnergyPacketProducer.java[EnergyPacketProducer~produceAPacket?constructor-call(void spacewar.EnergyPacket.<init>(spacewar.Game, double, double, double, double, double))!0!0!0!0!I

=Spacewar Example/src<spacewar{Robot.java[Robot~run?method-call(void spacewar.Ship.rotate(int))!0!0!0!0!I!2

=Spacewar Example/src<spacewar{Player.java[Player~keyPressed~QKeyEvent;?method-call(void spacewar.Ship.rotate(int))!0!0!0!0!I!2

=Spacewar Example/src<spacewar{Game.java[Game~Game~QString;?constructor-call(void spacewar.Registry.<init>(spacewar.Game))!0!0!0!0!I

There are about 30 more. If you really want them all tell me and I'll write some code that collects them.

> Could this have something to do with bug 262943 that you also raised?  I will
> find out.

Does it? Did you? ;-) 

Comment 5 Andrew Eisenberg CLA 2009-01-30 11:43:40 EST
There is a possibility that the two bugs are related, but probably not.  Since bug 262943 is fixed in head, you may want to upgrade to that and see if you are still getting the problem.

Here is what I am trying to do to recreate this bug.  

1. import Space War example into runtime workspace
2. full build
3. set breakpoint at AdviceActionDelegate.createMenuForRelationshipType()  around line 273.
4. in display view enter this code (or substitute some other handle for it):
			((org.eclipse.ajdt.core.javaelements.AJCodeElement) model.programElementToJavaElement("=Spacewar Example/src<spacewar{Game.java[Game~Game~QString;?constructor-call(void spacewar.Timer.<init>(spacewar.Game))!0!0!0!0!I")).getNameRange()
5. This returns the expected value.

Are you finding the same behavior?
			
Comment 6 Johan Fabry CLA 2009-01-30 14:31:32 EST
(In reply to comment #5)

Assuming the bugs are not related, I did not upgrade (I'd like to avoid an upgrade right now) and followed your instructions. NullPointerException as 'normal' for me. :-(

Comment 7 Andrew Eisenberg CLA 2009-02-09 12:06:02 EST
This appears to have been fixed in the latest dev build.  Please reopen if you notice any problems.
Comment 8 Johan Fabry CLA 2009-02-09 14:41:58 EST
The latest dev build does not solve the problem. The bug is still there, it's just that the symptom has changed: Now I get a name range with start 0 and length 3 :-(

I want to get to the bottom of this. Here's what happens for an offending AJCodeElement:

In AJProjectModelFacade.javaElementToProgramElement the line 289:
IProgramElement ipe = structureModel.findElementForHandleOrCreate(ajHandle, false) returns null.

So according to the comment on line 291 the handles are not working properly.

The reason for the return value being null is that in AspectJElementHierarchy.findeElementForHandleOrCreate(String handle, boolean create) (line 495) the call to findElementForHandle on line 502 returns null, and the create argument is false. 

In findElementForHandle the only node in parent.getChildren (line 513) is:

node	ProgramElement  (id=10020)	
	asm	AsmManager  (id=10010)	
	children	ArrayList<E>  (id=10021)	
	handle	"=Spacewar Example/src\\/" (id=10022)	
	kind	IProgramElement$Kind  (id=10023)	
	kvpairs	Collections$EmptyMap  (id=662)	
	modifiers	0	
	name	"src/" (id=10024)	
	parent	ProgramElement  (id=10009)	
	sourceLocation	null	

and the handle we're looking for is:
handle	"=Spacewar Example/src<spacewar{Robot.java[Robot~run?method-call(void spacewar.Ship.rotate(int))" (id=10063)	

Tell me if you need more info (and how to get it ;-) )
Comment 9 Andrew Eisenberg CLA 2009-02-09 16:28:53 EST
Unfortunately, still no luck in reproducing this on my end.  Somehow, the model in your project is not getting created properly, and I don't know why.

There is a debug method AJProjectModelFacade.printHierarchy

If you set a breakpoint somewhere in AJProjectModelFacade.javaElemmentToProgramElement (or really anywhere else in the class where the model has already been initialized), you can run and let the program stop there.  In the debug view, enter "printHierarchy(structureModel)" and execute it.

Paste or attach the results.  Unfortunately, one of the "features" of this method is that it only prints out the first 200 handles, but you can edit the value of MAX to be much higher by setting a breakpoint in the execution of this method and changing the value.

Maybe this will shed some light (ie- is it only certain handles that are non-existent or are all of them missing).
Comment 10 Johan Fabry CLA 2009-02-09 17:27:04 EST
Created attachment 125178 [details]
Hierarchy printout
Comment 11 Johan Fabry CLA 2009-02-09 17:27:54 EST
Comment on attachment 125178 [details]
Hierarchy printout

I cant change MAX: eclipse hangs if I try :-(
Comment 12 Andrew Eisenberg CLA 2009-02-10 00:25:11 EST
One thing that strikes me as odd about all the handles you send here is that they all start with 
=Spacewar Example/src\/

but the handles that I have seen on most other machines are like:
=Spacewar Example/src

It could mean that the AspectJ handles are getting created improperly, but the Java handles are not.  But this is surprising for many reasons.  One reason is that it seems that some of your handles are being properly generated (or else you would not be able to follow any references).  Or is this not true?

Can you follow any gutter markers at all?
Comment 13 Andrew Eisenberg CLA 2009-02-10 00:28:38 EST
One thing you can try to do is set a breakpoint at AJProjectModelFacade.javaElementToProgramElement (around line 240).  See if the je.getHandleIdentifier() starts with =Spacewar Example/src\/ or =Spacewar Example/src.

If the latter, then append '\/' to the end of it and see if the proper AJ IProgramElement is found.

If it is the former, then perhaps there is some odd setup to your project (eg- did you change the default source code location?).  This *should* work even under odd setups, but we need to know if it doesn't.
Comment 14 Johan Fabry CLA 2009-02-10 15:01:38 EST
(In reply to comment #13)
> One thing you can try to do is set a breakpoint at
> AJProjectModelFacade.javaElementToProgramElement (around line 240).  See if the
> je.getHandleIdentifier() starts with =Spacewar Example/src\/ or =Spacewar
> Example/src.
> 
> If the latter, then append '\/' to the end of it and see if the proper AJ
> IProgramElement is found.

Yes, this seems to be the solution to the problem! Many (did not check them all) of the offending cases ended in 'src' and when I added '\/' an IProgramElement was found. In fact, all of these cases are calls to getNameRange where initializeLocations is called, for all of the others the values have already been set somewhere else.

> If it is the former, then perhaps there is some odd setup to your project (eg-
> did you change the default source code location?).  This *should* work even
> under odd setups, but we need to know if it doesn't.

I did not do anything special in the project setup, just add the example project. For what it's worth I'm working with a colleage on this and he reports worse: he gets exceptions on everything when running the reporter. He simply adds the example project, like I'm doing. He's also on a mac, so maybe that's the source of the problem.

Comment 15 Johan Fabry CLA 2009-02-10 15:05:18 EST
(In reply to comment #12)

> Can you follow any gutter markers at all?

I dont see any gutter markers in Spacewar. In other projects I do see them. 

Comment 16 Andrew Eisenberg CLA 2009-02-10 15:21:41 EST
(In reply to comment #14)
> I did not do anything special in the project setup, just add the example
> project. 

Oh ho!  That's the problem.  Seems that importing using the aspectj examples forces the AspectJ handles to behave in this odd and incorrect way.  I'll explore this some more. 
Comment 17 Andrew Eisenberg CLA 2009-02-10 15:24:59 EST
Simple way around this problem:

1. open the .classpath file.
2. change the:
  <classpathentry excluding="spacewar/Debug.aj" kind="src" path="src/"/>
to:
  <classpathentry excluding="spacewar/Debug.aj" kind="src" path="src"/>

Now, there are two things that need to happen here on my end:

1. the example project should have the correct classpath
2. the creation of aspectj handles should strip off any '/' on the end of a path.

Thanks for your help and patience in figuring out what is happening here.
Comment 18 Johan Fabry CLA 2009-02-11 10:46:53 EST
(In reply to comment #17)
> Simple way around this problem:
> 
> 1. open the .classpath file.
> 2. change the:
>   <classpathentry excluding="spacewar/Debug.aj" kind="src" path="src/"/>
> to:
>   <classpathentry excluding="spacewar/Debug.aj" kind="src" path="src"/>

Done, no more problems. Yay!

> Thanks for your help and patience in figuring out what is happening here.

No problem, glad to have these issues resolved, so that the reporting plugin works :-)

Comment 19 Andrew Eisenberg CLA 2009-02-11 13:01:36 EST
The problem lies in BuildConfigUtils.applyBuildConfiguration.  This method was adding an extra '/' to the path.  It is now fixed.  The fix and ample tests have been committed to head and this problem should not occur again.
Comment 20 Andrew Eisenberg CLA 2009-02-11 13:12:57 EST
However, fixing this bug did show some more problems with reconciling.  These issues were showing up as spurious editor problems even though the compiler was OK with them:

1. pointcut expressions are allowed in Java classes (didn't know that!).  These expressions are now transformed into Java syntax in the AspectsConvertingParser.

2. ITD methods that are declared as abstract were causing problems in subclasses when the implementation of the abstract method is also an ITD.  This problem is now properly ignored in the AJCompilationUnitProblemFinder

3. ITD scoping was off.  Specifically, ITD methods declared as private are actually visible in the aspect that declares them (and invisible elsewhere).  I fixed this by declaring all ITDs as public, so uses of them will not cause problems.  This is not a perfect solution for several reasons.  a) ITDs will show in content assist as public even when they are not.  b) the problem finder will not show them as an error if they are out of scope (however the compiler will, but that is only after a save happens).  c) invalid ITDs will appear in content assist.  
This was the best I could do without performing complex analysis.

4. When identical ITDs are added by different aspects, the result was duplicate methods or fields in the target class---an error.  Now, when inserting ITDs, duplicates are searched for before adding the new ITD to the type.
Comment 21 Andrew Eisenberg CLA 2009-02-11 13:13:18 EST
This bug is fixed.