Bug 298637 - Could not retrieve declared methods (NPE in ParameterizedTypeBinding.resolve)
Summary: Could not retrieve declared methods (NPE in ParameterizedTypeBinding.resolve)
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.6   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.6 M6   Edit
Assignee: Srikanth Sankaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-12-30 04:40 EST by utilisateur_768 CLA
Modified: 2010-03-10 06:22 EST (History)
3 users (show)

See Also:


Attachments
Proposed patch (1.31 KB, patch)
2010-02-01 23:54 EST, Srikanth Sankaran CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description utilisateur_768 CLA 2009-12-30 04:40:39 EST
I have no idea how i got this exception.


-- Error Details --
Date: Tue Dec 29 16:37:15 CET 2009
Message: Could not retrieve declared methods
Severity: Error
Product: Eclipse SDK 3.6.0.v200910301201 (org.eclipse.sdk.ide)
Plugin: org.eclipse.jdt.core
Session Data:
eclipse.buildId=I20091030-1201
java.version=1.6.0_17
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=en_EN
Framework arguments:  -refresh
Command-line arguments:  -os win32 -ws win32 -arch x86 -clean -refresh -debug D:\User\Scripts\.options -consolelog


Exception Stack Trace:
java.lang.NullPointerException
	at org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding.resolve(ParameterizedTypeBinding.java:867)
	at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.resolveType(BinaryTypeBinding.java:100)
	at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.resolveTypesFor(BinaryTypeBinding.java:1040)
	at org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.availableMethods(BinaryTypeBinding.java:231)
	at org.eclipse.jdt.core.dom.TypeBinding.getDeclaredMethods(TypeBinding.java:261)
	at org.eclipse.jdt.internal.corext.dom.Bindings.findOverriddenMethodInType(Bindings.java:450)
	at org.eclipse.jdt.internal.corext.dom.Bindings.findOverriddenMethodInHierarchy(Bindings.java:467)
	at org.eclipse.jdt.internal.corext.dom.Bindings.findOverriddenMethod(Bindings.java:501)
	at org.eclipse.jdt.internal.ui.javaeditor.OverrideIndicatorManager$1.visit(OverrideIndicatorManager.java:182)
	at org.eclipse.jdt.core.dom.MethodDeclaration.accept0(MethodDeclaration.java:487)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2480)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2551)
	at org.eclipse.jdt.core.dom.AnonymousClassDeclaration.accept0(AnonymousClassDeclaration.java:143)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2480)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2528)
	at org.eclipse.jdt.core.dom.ClassInstanceCreation.accept0(ClassInstanceCreation.java:335)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2480)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2528)
	at org.eclipse.jdt.core.dom.Assignment.accept0(Assignment.java:312)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2480)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2528)
	at org.eclipse.jdt.core.dom.ExpressionStatement.accept0(ExpressionStatement.java:144)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2480)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2551)
	at org.eclipse.jdt.core.dom.Block.accept0(Block.java:136)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2480)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:2528)
	at org.eclipse.jdt.core.dom.MethodDeclaration.accept0(MethodDeclaration.java:502)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2480)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2551)
	at org.eclipse.jdt.core.dom.TypeDeclaration.accept0(TypeDeclaration.java:484)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2480)
	at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:2551)
	at org.eclipse.jdt.core.dom.CompilationUnit.accept0(CompilationUnit.java:219)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2480)
	at org.eclipse.jdt.internal.ui.javaeditor.OverrideIndicatorManager.updateAnnotations(OverrideIndicatorManager.java:175)
	at org.eclipse.jdt.internal.ui.javaeditor.OverrideIndicatorManager.reconciled(OverrideIndicatorManager.java:254)
	at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor.reconciled(CompilationUnitEditor.java:1632)
	at org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconciled(JavaReconcilingStrategy.java:212)
	at org.eclipse.jdt.internal.ui.text.JavaCompositeReconcilingStrategy.reconciled(JavaCompositeReconcilingStrategy.java:161)
	at org.eclipse.jdt.internal.ui.text.JavaCompositeReconcilingStrategy.initialReconcile(JavaCompositeReconcilingStrategy.java:141)
	at org.eclipse.jface.text.reconciler.MonoReconciler.initialProcess(MonoReconciler.java:105)
	at org.eclipse.jdt.internal.ui.text.JavaReconciler.initialProcess(JavaReconciler.java:398)
	at org.eclipse.jface.text.reconciler.AbstractReconciler$BackgroundThread.run(AbstractReconciler.java:173)
Comment 1 Frederic Fusier CLA 2009-12-30 11:11:55 EST
Did you get it several times or only once? Any idea of which file you were editing when this exception occurred?
Comment 2 utilisateur_768 CLA 2009-12-30 11:23:46 EST
i've got it a lot of time (about 100 times i would say)
i was editing some java file on another project (all my projects have a lot a file with same path and filename:Project_HEAD, Project_branch1, etc...)
Comment 3 utilisateur_768 CLA 2010-01-19 11:30:25 EST
i had another bug recently, whose cause was corrupted index. So maybe it's the same cause here.
Comment 4 Srikanth Sankaran CLA 2010-01-20 05:22:01 EST
(In reply to comment #2)
> i've got it a lot of time (about 100 times i would say)
> i was editing some java file on another project (all my projects have a lot a
> file with same path and filename:Project_HEAD, Project_branch1, etc...)

If you manage to reproduce it several times, perhaps you can post a (preferrably)
smallish test case that will help us ? Thanks.,
Comment 5 Srikanth Sankaran CLA 2010-02-01 22:40:29 EST
(In reply to comment #4)
> (In reply to comment #2)
> > i've got it a lot of time (about 100 times i would say)
> > i was editing some java file on another project (all my projects have a lot a
> > file with same path and filename:Project_HEAD, Project_branch1, etc...)
> 
> If you manage to reproduce it several times, perhaps you can post a
> (preferrably)
> smallish test case that will help us ? Thanks.,

Hello, Have you been able to look into this request ?

Alternately, can you test a nightly/weekly build to see
if the problem has been fixed ?
Comment 6 Srikanth Sankaran CLA 2010-02-01 23:47:11 EST
Last change to org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding
occurred in May 2009, well before the build id used by the submitter.

It appears at ParameterizedTypeBinding.java:861

    TypeVariableBinding[] refTypeVariables = resolvedType.typeVariables();

typeVariables() is returning null and this causes grief in ParameterizedTypeBinding.java:867.

} else if (argLength != refTypeVariables.length) { // check arity

The typeVariables() method invocation could possibly get bound to one of
org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.typeVariables()
org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding.typeVariables()
org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.typeVariables()

Of these by code inspection we can conclude that the first two cannot
return null. Turning attention to SourceTypeBinding.typeVariables()
it is clear that this method cannot return null once org.eclipse.jdt.internal.compiler.lookup.ClassScope.buildTypeVariables()
has been called. I'll post a patch shortly that will preclude null
references being doled out of SourceTypeBinding.typeVariables(), but
I don't know how to reproduce the crash yet.
Comment 7 Srikanth Sankaran CLA 2010-02-01 23:54:09 EST
Created attachment 157867 [details]
Proposed patch
Comment 8 Srikanth Sankaran CLA 2010-02-01 23:57:31 EST
Satyam, please review. Since I don't have a test
appreciate a close scrunity of the conclusions
in comment#6 would be appreciated -- thanks.
Comment 9 Satyam Kandula CLA 2010-02-03 02:09:04 EST
The changes look good.
Comment 10 Srikanth Sankaran CLA 2010-02-03 02:28:36 EST
Released in HEAD for 3.6M6. Use code inspection for verification.

Hello utilisateur_768@yahoo.fr,

If possible please download the nightly builds
after a day or two. If problem persists, please
REOPEN -- Thanks. (http://www.eclipse.org/downloads/)
Comment 11 Ayushman Jain CLA 2010-03-08 07:03:36 EST
I'm not really familiar with how this part of code works, but a first pass tells me that the field typeVariables being null itself has some significance with respect to the method SourceTypeBinding#isGenericType(). Returning Binding.NO_TYPE_VARIABLES when typeBindings is null, would return false for subsequent calls to isGenericType(), even though it could be otherwise. Other methods such as SourceTypeBinding#kind(), SourceTypeBinding#genericSignature() might also show similar results.

Further BinaryTypeBinding:153, which is
    this.typeVariables = typeSignature != null && typeSignature.length > 0 && typeSignature[0] == '<'
		? null // is initialized in cachePartsFrom (called from LookupEnvironment.createBinaryTypeFrom())... must set to null so isGenericType() answers true
		: Binding.NO_TYPE_VARIABLES;


kind of suggests a distinction between typeVariables being null and Binding.NO_TYPE_VARIABLES.

Won't it be a better idea if we change ParameterizedTypeBinding:867 to 

else if (refTypeVariables != null && argLength != refTypeVariables.length)

instead of modifying what typeVariables() returns. This is similar to what has already been done in 

ParameterizedTypeBinding#boundCheck():72. This check will also need to be introduced everywhere typeVariables() is being referenced.

Srikanth, can you please cross check? I may be wrong, but thought it better to confirm.
Comment 12 Srikanth Sankaran CLA 2010-03-10 00:57:50 EST
(In reply to comment #11)
> I'm not really familiar with how this part of code works, but a first pass
> tells me that the field typeVariables being null itself has some significance
> with respect to the method SourceTypeBinding#isGenericType(). Returning
> Binding.NO_TYPE_VARIABLES when typeBindings is null, would return false for
> subsequent calls to isGenericType(), even though it could be otherwise.

Only if org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.typeVariables
is modified by the patch and set to Binding.NO_TYPE_VARIABLES, which it
doesn't. All the methods you cite directly reference the unmodified
typeVariables instance variable of STB and they do not invoke the getter
method which is what the patch is fixing.

Actually some of the methods you cite are clear (if implicit) proof that
if STB#typeVariables were to hold any value other than Binding.NO_TYPE_VARIABLES, it *has* to be a non-null value.

For example, org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.genericSignature()
would fault with NPE if typeVariables were to be null.

> Other
> methods such as SourceTypeBinding#kind(), SourceTypeBinding#genericSignature()
> might also show similar results.

Not quite, since these directly access the (unmodified) instance
variable.

> Further BinaryTypeBinding:153, which is

[...]

> kind of suggests a distinction between typeVariables being null and
> Binding.NO_TYPE_VARIABLES.

Possibly, but per above nothing has changed since we don't modify
the instance variable anyways.

> Won't it be a better idea if we change ParameterizedTypeBinding:867 to 
> 
> else if (refTypeVariables != null && argLength != refTypeVariables.length)
> 
> instead of modifying what typeVariables() returns. This is similar to what has
> already been done in 
> 
> ParameterizedTypeBinding#boundCheck():72. This check will also need to be
> introduced everywhere typeVariables() is being referenced.

That is what I wanted to avoid. By perusing the code in
org.eclipse.jdt.internal.compiler.lookup.ClassScope.buildTypeVariables() which
is the only piece of code that ever assigns to
org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.typeVariables
we can conclude that typeVariables is never to be left to be null.
See also org.eclipse.jdt.internal.compiler.lookup.Scope.createTypeVariables(TypeParameter[], Binding) which deliberately folds null type variables into Binding.NO_TYPE_VARIABLES.

As comment#6 mentions, SourceTypeBinding.typeVariables()
cannot return null once org.eclipse.jdt.internal.compiler.lookup.ClassScope.buildTypeVariables().
There is something in the comment#0 scenario that calls typeVariables()
before org.eclipse.jdt.internal.compiler.lookup.ClassScope.buildTypeVariables()
is called. Given we don't know how to reproduce that the original fix
takes a conservative approach.
Comment 13 Ayushman Jain CLA 2010-03-10 06:13:24 EST
Sounds good.
Verified for 3.6M6 through code inspection.
Comment 14 Srikanth Sankaran CLA 2010-03-10 06:22:41 EST
Verified.