Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 359478 - NullPointerException occurs in CompilationUnit instances returned from ASTParser.createASTs()
Summary: NullPointerException occurs in CompilationUnit instances returned from ASTPar...
Status: RESOLVED DUPLICATE of bug 189782
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.7.1   Edit
Hardware: PC Windows 7
: P3 minor (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-09-29 16:19 EDT by Byron Hawkins CLA
Modified: 2012-03-14 03:12 EDT (History)
7 users (show)

See Also:


Attachments
Sample plugin which causes the problem (19.39 KB, application/octet-stream)
2011-09-30 05:43 EDT, Byron Hawkins CLA
no flags Details
proposed fix (675 bytes, patch)
2012-03-05 12:43 EST, Ayushman Jain CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Byron Hawkins CLA 2011-09-29 16:19:59 EDT
Build Identifier: 20110916-0149

I am working on a plugin that requires parsing large numbers of source files, so I am hoping to use the batch method ASTParser.createASTs(). The parsing executes without errors, but within the CompilationUnit instances it produces, many of the org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding instances have had their "scope" field set to null. This setting to null is occurring in the CompilationUnitDeclaration.cleanUp() methods, which are invoked on a worker thread that is unrelated to my plugin's code (i.e., my plugin's classes do not appear on the cleanUp() method call stack). My parsing code looks like this (all "rawSources" are within the same project): 

	ASTParser parser = ASTParser.newParser(AST.JLS3);

	parser.setResolveBindings(true);
	parser.setStatementsRecovery(true);
	parser.setBindingsRecovery(true);
	parser.setIgnoreMethodBodies(false);
	parser.setProject(project);
	parser.createASTs(rawSources.values().toArray(new ICompilationUnit[0]), new String[0], this, deltaAnalyzer.progressMonitor);

Alternatively, I can execute the parsing this way, and no such problems occur:

	for (ICompilationUnit source : rawSources.values())
	{
		parser.setResolveBindings(true);
		parser.setStatementsRecovery(true);
		parser.setBindingsRecovery(true);
		parser.setIgnoreMethodBodies(false);
		parser.setProject(project);
		parser.setSource(source);
		CompilationUnit ast = (CompilationUnit)parser.createAST(deltaAnalyzer.progressMonitor);
		parsedSources.add(deltaAnalyzer.createParsedSource(source, ast));
	}

It's very difficult for me to see if I'm using the API in some problematic way, so please let me know if there is a usage problem on my side. Or if there is another way to parse large numbers of sources with bindings resolved, that would be fine for me. Thanks for your help.

Reproducible: Always

Steps to Reproduce:
1. Install my plugin in an Eclipse IDE of the specified build.
2. Touch a file having annotations related to my plugin's source processing.
3. Execute a build.
Comment 1 Olivier Thomann CLA 2011-09-29 16:57:54 EDT
Could you please provide steps to reproduce with the required binaries in order to install the plugin ?
It would also be good to get the stack trace.
Comment 2 Byron Hawkins CLA 2011-09-30 05:38:06 EDT
There are two stack traces:

============= First Stack Trace =============

java.lang.NullPointerException
	at org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.methods(SourceTypeBinding.java:1186)
	at org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding.availableMethods(ReferenceBinding.java:173)
	at org.eclipse.jdt.core.dom.TypeBinding.getDeclaredMethods(TypeBinding.java:267)
	at org.hs.rns.analysis.compile.publication.PublicationMethodConstraintCollector.findDeclaredMethod(PublicationMethodConstraintCollector.java:180)
	at org.hs.rns.analysis.compile.publication.PublicationMethodConstraintCollector.collectMethodConstraints(PublicationMethodConstraintCollector.java:71)
	at org.hs.rns.analysis.compile.publication.PublicationConstraintChecker.analyzeMethodInvocations(PublicationConstraintChecker.java:97)
	at org.hs.rns.analysis.compile.publication.PublicationConstraintChecker.start(PublicationConstraintChecker.java:47)
	at org.hs.rns.analysis.compile.RNSAnnotationChecker.analyzeCompilationUnit(RNSAnnotationChecker.java:20)
	at org.hs.rns.analysis.compile.RNSDeltaAnalyzer$ParsedSource.analyze(RNSDeltaAnalyzer.java:53)
	at org.hs.rns.analysis.compile.RNSProjectAnalyzer.analyze(RNSProjectAnalyzer.java:80)
	at org.hs.rns.analysis.compile.RNSDeltaAnalyzer.analyzeDeltas(RNSDeltaAnalyzer.java:91)
	at org.hs.rns.analysis.compile.RNSBuildAnalyzer.analyzeProject(RNSBuildAnalyzer.java:45)
	at org.hs.rns.analysis.compile.RNSBuildAnalyzer.build(RNSBuildAnalyzer.java:23)
	at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:728)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:199)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:239)
	at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:292)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:295)
	at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:351)
	at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:374)
	at org.eclipse.core.internal.resources.Workspace.buildInternal(Workspace.java:513)
	at org.eclipse.core.internal.resources.Workspace.build(Workspace.java:422)
	at org.eclipse.ui.actions.GlobalBuildAction$1.run(GlobalBuildAction.java:180)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)

============= Second Stack Trace =============

java.lang.NullPointerException
	at org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.resolveTypesFor(SourceTypeBinding.java:1409)
	at org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.methods(SourceTypeBinding.java:1175)
	at org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding.availableMethods(ReferenceBinding.java:173)
	at org.eclipse.jdt.core.dom.TypeBinding.getDeclaredMethods(TypeBinding.java:267)
	at org.hs.rns.analysis.compile.publication.PublicationMethodConstraintCollector.findDeclaredMethod(PublicationMethodConstraintCollector.java:180)
	at org.hs.rns.analysis.compile.publication.PublicationMethodConstraintCollector.collectMethodConstraints(PublicationMethodConstraintCollector.java:71)
	at org.hs.rns.analysis.compile.publication.PublicationConstraintChecker.analyzeMethodInvocations(PublicationConstraintChecker.java:97)
	at org.hs.rns.analysis.compile.publication.PublicationConstraintChecker.start(PublicationConstraintChecker.java:47)
	at org.hs.rns.analysis.compile.RNSAnnotationChecker.analyzeCompilationUnit(RNSAnnotationChecker.java:20)
	at org.hs.rns.analysis.compile.RNSDeltaAnalyzer$ParsedSource.analyze(RNSDeltaAnalyzer.java:53)
	at org.hs.rns.analysis.compile.RNSProjectAnalyzer.analyze(RNSProjectAnalyzer.java:80)
	at org.hs.rns.analysis.compile.RNSDeltaAnalyzer.analyzeDeltas(RNSDeltaAnalyzer.java:91)
	at org.hs.rns.analysis.compile.RNSBuildAnalyzer.analyzeProject(RNSBuildAnalyzer.java:45)
	at org.hs.rns.analysis.compile.RNSBuildAnalyzer.build(RNSBuildAnalyzer.java:23)
	at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:728)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:199)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:239)
	at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:292)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:295)
	at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:351)
	at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:374)
	at org.eclipse.core.internal.resources.Workspace.buildInternal(Workspace.java:513)
	at org.eclipse.core.internal.resources.Workspace.build(Workspace.java:422)
	at org.eclipse.ui.actions.GlobalBuildAction$1.run(GlobalBuildAction.java:180)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Comment 3 Byron Hawkins CLA 2011-09-30 05:43:17 EDT
Created attachment 204361 [details]
Sample plugin which causes the problem

1. Install the plugin
2. Right-click on a Java Project in the Package Explorer
3. Choose Add/Remove Hierarchy Analyzer Nature
4. Make some code changes and build

Exceptions will appear in the console, incorrect method counts will be returned to the caller on HierarchyAnalyzer.java:44.
Comment 4 Byron Hawkins CLA 2011-09-30 05:45:47 EDT
The attached plugin provides a reduced version of my plugin, which does cause the same error. Just install the plugin, right-click on a Java project, and choose "Add/Remove Hierarchy Analyzer Nature". The errors only occur on large projects with lots of complicated class relationships. I don't see anything consistent about the particular types for which the errors occur. It is always the call to ITypeBinding.getDeclaredMethods() that triggers the exceptions (which are caught internally, logged, and the 0 methods are incorrectly returned).
Comment 5 Satyam Kandula CLA 2011-09-30 07:10:39 EDT
(In reply to comment #4)
This happens if getDeclaredMethods is called on a type whose createAST is not requested.

*** This bug has been marked as a duplicate of bug 189782 ***
Comment 6 Byron Hawkins CLA 2011-09-30 09:15:39 EDT
Could you please add mention of this to the API Javadoc? I am reading the latest Javadoc for Indigo, and I can't see any way that the information there would lead me to any such conclusion. Having spent more than a full day of work trying to deal with this issue, it does seem like the situation warrants mention in the Javadoc. How else can a developer know what is wrong in this case?
Comment 7 Byron Hawkins CLA 2011-09-30 09:19:27 EDT
Also, your resolution does not explain why my plugin works correctly when I request AST parsing on a file-by-file basis, rather than by batch. The set of AST requests is identical, and the set of getDeclaredMethods() requests is identical, but one path to acquiring the ASTs results in this error, while the other does not. 

I have included the source code with my plugin, and the alternate version is commented out in file HierarchyProjectAnalyzer. Please try it and see that the behavior of the JDT API is entirely inconsistent--working correctly when ASTs are requested one way, and failing when ASTs are requested another way. Thanks.
Comment 8 Stephan Herrmann CLA 2011-10-01 08:44:24 EDT
(In reply to comment #6)
> Could you please add mention of this to the API Javadoc? I am reading the
> latest Javadoc for Indigo, and I can't see any way that the information there
> would lead me to any such conclusion. Having spent more than a full day of
> work trying to deal with this issue,

Yes, the current situation is not satisfactory.

> it does seem like the situation warrants mention in the Javadoc.

That would mean the current behavior is contracted in the API and 
can no longer be changed.

> How else can a developer know what is wrong in this case?

From my understanding the wrong is: JDT has a bug.

(In reply to comment #5)
> *** This bug has been marked as a duplicate of bug 189782 ***

Please see that bug 189782 is still open. 
Work / discussion will continue there.
Comment 9 Byron Hawkins CLA 2011-10-01 08:49:07 EDT
Ah, I missed that 189782 is still open, because the comment sounded conclusory. The bug is actually not difficult to workaround, now that I get what the issue is. Thanks!
Comment 10 Srikanth Sankaran CLA 2011-10-25 06:39:10 EDT
Comment# 2 mentions two different stack traces producing NPE while bug
189782 mentions only one of them. I think it is a better idea to leave
this open till we have a resolution. At that point after having verified
the fix fully, we can close this as duplicate if this indeed gets addressed
by the same fix.
Comment 11 Ayushman Jain CLA 2012-03-05 12:43:40 EST
Created attachment 212087 [details]
proposed fix

I'm not sure, but I think the problem happened while fixing bug 114935. Prior to that fix, we used to process all CU's, so scope for all could safely be discarded. However, post that we began to process only requested CU's, and while it was ok to skip processing of other CU's, we even discarded their scopes. I think this is overkill and is causing this current NPE issue.

Satyam, what do you think about the patch?
Comment 12 Ayushman Jain CLA 2012-03-05 12:56:31 EST
(In reply to comment #11)
> Created attachment 212087 [details]
> proposed fix

Btw, org.eclipse.jdt.core.tests.dom.BatchASTCreationTests.test070() causes an NPE and the curiosity to find out the cause got me to dig up on this.
Comment 13 Olivier Thomann CLA 2012-03-05 13:07:47 EST
Keeping scopes around can cause a major issue on memory consumption.
Comment 14 Satyam Kandula CLA 2012-03-06 06:25:01 EST
Marking this duplicate again

*** This bug has been marked as a duplicate of bug 189782 ***