Bug 61946 - AST: NPE in IVariableBinding.getConstantValue
Summary: AST: NPE in IVariableBinding.getConstantValue
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.0   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.2 M4   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 117018 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-05-12 12:45 EDT by Martin Aeschlimann CLA
Modified: 2006-01-10 10:35 EST (History)
1 user (show)

See Also:


Attachments
Patch against R3_1_maintenance branch (36.21 KB, patch)
2006-01-10 06:51 EST, Jerome Lanneluc CLA
no flags Details | Diff
Updated tests (1.63 KB, patch)
2006-01-10 10:35 EST, Jerome Lanneluc CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Aeschlimann CLA 2004-05-12 12:45:51 EDT
20040512

for the following code get the var binding of BUNDLE_NAME and do
'getContantValue'

public class Accessor {
	private static final String BUNDLE_NAME = "test.test";//$NON-NLS-1$
	public static String getString(String s) {
		return "";
	}
}

java.lang.NullPointerException
	at java.lang.Throwable.<init>(Throwable.java)
	at java.lang.Throwable.<init>(Throwable.java)
	at java.lang.NullPointerException.<init>(NullPointerException.java:60)
	at
org.eclipse.jdt.core.dom.VariableBinding.getConstantValue(VariableBinding.java:196)
	at
org.eclipse.jdt.internal.corext.refactoring.nls.NLSInfo.getResourceBundle(NLSInfo.java:95)
	at
org.eclipse.jdt.internal.corext.refactoring.nls.NLSInfo.getAccessorClassInfo(NLSInfo.java:73)
	at
org.eclipse.jdt.internal.corext.refactoring.nls.NLSHolder.create(NLSHolder.java:48)
	at
org.eclipse.jdt.ui.tests.nls.NLSSourceModifierTest.testFromTranslatedToNotTranslated(NLSSourceModifierTest.java:202)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
	at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:41)
	at java.lang.reflect.Method.invoke(Method.java:386)
	at junit.framework.TestCase.runTest(TestCase.java:154)
	at junit.framework.TestCase.runBare(TestCase.java:127)
	at junit.framework.TestResult$1.protect(TestResult.java:106)
	at junit.framework.TestResult.runProtected(TestResult.java:124)
	at junit.framework.TestResult.run(TestResult.java:109)
	at junit.framework.TestCase.run(TestCase.java:118)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at junit.extensions.TestDecorator.basicRun(TestDecorator.java:22)
	at junit.extensions.TestSetup$1.protect(TestSetup.java:19)
	at junit.framework.TestResult.runProtected(TestResult.java:124)
	at junit.extensions.TestSetup.run(TestSetup.java:23)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:422)
	at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:306)
	at
org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:30)
	at
org.eclipse.pde.internal.junit.runtime.UITestApplication$1.run(UITestApplication.java:90)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:106)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:2702)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2394)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:1353)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1324)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:243)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:141)
	at org.eclipse.ui.internal.ide.IDEApplication.run(IDEApplication.java:90)
	at
org.eclipse.pde.internal.junit.runtime.UITestApplication.run(UITestApplication.java:33)
	at
org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:298)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:249)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:126)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
	at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:41)
	at java.lang.reflect.Method.invoke(Method.java:386)
	at org.eclipse.core.launcher.Main.basicRun(Main.java:269)
	at org.eclipse.core.launcher.Main.run(Main.java:722)
	at org.eclipse.core.launcher.Main.main(Main.java:706)
Comment 1 Olivier Thomann CLA 2004-05-12 13:03:07 EDT
I will investigate.
Comment 2 Olivier Thomann CLA 2004-05-12 13:12:40 EDT
I cannot reproduce.
Comment 3 Olivier Thomann CLA 2004-05-12 14:08:37 EDT
The right test case is:
package test0554;

public class A {
	private static final String BUNDLE_NAME = "test.test";//$NON-NLS-1$
	public static String getString(String s) {
		return "";
	}
}

package test0554;

import test0554.A;

public class B {
	public static String foo() {
		return A.getString("xx");
	}
}

In B, get the variable binding for BUNDLE_NAME through the type binding of A
using the getDeclaringFields() method.
In this case, the constant for the field BUNDLE_NAME is not initialized and it
is null.
I will add a null check.

Philippe, do we have a way to initialize this field binding?
Comment 4 Olivier Thomann CLA 2004-05-12 14:09:44 EDT
The test cases I added need to update in case we can get the constant value.
Comment 5 Olivier Thomann CLA 2004-05-12 14:39:58 EDT
In case B is like this:
public class B {
	public static String foo() {
		return A.BUNDLE_NAME;
	}
}

And BUNDLE_NAME is changed to be public then you can get the constant value
using the same call. So it is inconsistent when the constant is available and
when it is not.
Comment 6 Olivier Thomann CLA 2004-05-13 11:06:20 EDT
This is a kind of lazy initialization for us. In the case in comment 3, the
field is not directly referenced in B. Therefore its constant is not
initialized. The workaround is to get the declaration for A and get the field
binding from there. Then it will be resolved and the constant won't be null anymore.

Jim, this kind of behavior should be clarified in the specs. If we want to be
able to get such field at any time, then we have to keep the scopes around and
this would increase the footprint.

Once the specs are updated, this bug can be closed. I already added the null check.
Comment 7 Jim des Rivieres CLA 2004-05-13 16:22:27 EDT
The notion of bindings that the AST API provides are supposed to be accurate 
at the time the compilation unit was anaylzed. Whether a variable binding has 
a constant value or not should be independent of whether the field is public 
or private. So I believe this should be considered a bug in the 
implementation. Olivier, you mention that the implementation currently does 
this lazily and that fixing it would require keeping around scope objects. 
Bindings, by their nature, already have a significant footprint (as the spec 
points out). How much bigger would these scope objects make it? Can you see 
any alternatives, such as computing the value of constant fields eagerly?
Comment 8 Olivier Thomann CLA 2004-05-14 15:11:54 EDT
I don't know exactly how much bigger it would be, but keeping the whole scope
and name environment around might be expensive.
I don't see any other way to fix this, because right now we cannot create scopes
on demand and once they are removed, no further resolution can be performed.
Comment 9 Olivier Thomann CLA 2004-05-19 15:38:49 EDT
Reconsider post 3.0.
Comment 10 Philipe Mulet CLA 2005-11-18 11:41:23 EST
reopening
Comment 11 Philipe Mulet CLA 2005-11-18 11:44:34 EST
Reconsidering for 3.2. Will release changes to move the reference lazy
resolution directly into the binding. So as long as the scope is alive, the
constant may be computed lazily.

Fixed.
Tuned affected tests: 
  ASTConverterTest2#test0554
  ASTConverterTestAST3_2#test0554
Comment 12 Philipe Mulet CLA 2005-11-18 11:48:24 EST
*** Bug 117018 has been marked as a duplicate of this bug. ***
Comment 13 Frederic Fusier CLA 2005-12-12 09:54:50 EST
Verified for 3.2 M4 using build I20051212-0010
Comment 14 Jerome Lanneluc CLA 2006-01-10 06:51:49 EST
Created attachment 32755 [details]
Patch against R3_1_maintenance branch

just in case we want to backport the fix to the R3_1_maintenance branch ...
Comment 15 Jerome Lanneluc CLA 2006-01-10 10:35:15 EST
Created attachment 32762 [details]
Updated tests

against R3_1_maintenance branch