Skip to content

NullPointerException while refactoring a field name in a Java class #672

@mauromol

Description

@mauromol

I was renaming a field name in a Java class, requesting to update its getter method name as well. This caused a NPE by Greclipse in a test method of a test class that is using the refactored class. Here is the stack trace:

Bundle: org.eclipse.jdt.groovy.core 3.1.0.xx-201808130148-e48
Message: Groovy-Eclipse Type Inferencing: Error visiting method testPopulateAttestazioneDiAvvenutaTrasmissioneMessageFull in class DefaultFatturaElettronicaMessageFromJpaEntityConverterTest
Exception:
java.lang.NullPointerException: null
    at org.eclipse.jdt.groovy.search.FieldReferenceSearchRequestor.acceptASTNode(FieldReferenceSearchRequestor.java:82)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.handleRequestor(TypeInferencingVisitorWithRequestor.java:1867)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.handleSimpleExpression(TypeInferencingVisitorWithRequestor.java:1856)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.visitConstantExpression(TypeInferencingVisitorWithRequestor.java:989)
    at org.codehaus.groovy.ast.expr.ConstantExpression.visit(ConstantExpression.java:85)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.visitBinaryExpression(TypeInferencingVisitorWithRequestor.java:776)
    at org.codehaus.groovy.ast.expr.BinaryExpression.visit(BinaryExpression.java:51)
    at org.codehaus.groovy.ast.CodeVisitorSupport.visitReturnStatement(CodeVisitorSupport.java:127)
    at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitReturnStatement(ClassCodeVisitorSupport.java:283)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.visitReturnStatement(TypeInferencingVisitorWithRequestor.java:1574)
    at org.codehaus.groovy.ast.stmt.ReturnStatement.visit(ReturnStatement.java:49)
    at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:89)
    at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:238)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.visitBlockStatement(TypeInferencingVisitorWithRequestor.java:848)
    at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
    at org.codehaus.groovy.ast.CodeVisitorSupport.visitClosureExpression(CodeVisitorSupport.java:228)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.visitClosureExpression(TypeInferencingVisitorWithRequestor.java:970)
    at org.codehaus.groovy.ast.expr.ClosureExpression.visit(ClosureExpression.java:49)
    at org.codehaus.groovy.ast.CodeVisitorSupport.visitListOfExpressions(CodeVisitorSupport.java:328)
    at org.codehaus.groovy.ast.CodeVisitorSupport.visitTupleExpression(CodeVisitorSupport.java:232)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.visitTupleExpression(TypeInferencingVisitorWithRequestor.java:1698)
    at org.codehaus.groovy.ast.CodeVisitorSupport.visitArgumentlistExpression(CodeVisitorSupport.java:339)
    at org.codehaus.groovy.ast.expr.ArgumentListExpression.visit(ArgumentListExpression.java:76)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.visitMethodCallExpression(TypeInferencingVisitorWithRequestor.java:1420)
    at org.codehaus.groovy.ast.expr.MethodCallExpression.visit(MethodCallExpression.java:70)
    at org.codehaus.groovy.ast.CodeVisitorSupport.visitExpressionStatement(CodeVisitorSupport.java:123)
    at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitExpressionStatement(ClassCodeVisitorSupport.java:268)
    at org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:42)
    at org.codehaus.groovy.ast.CodeVisitorSupport.visitBlockStatement(CodeVisitorSupport.java:89)
    at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitBlockStatement(ClassCodeVisitorSupport.java:238)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.visitBlockStatement(TypeInferencingVisitorWithRequestor.java:848)
    at org.codehaus.groovy.ast.stmt.BlockStatement.visit(BlockStatement.java:71)
    at org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:145)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.visitConstructorOrMethod(TypeInferencingVisitorWithRequestor.java:1081)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.visitJDT(TypeInferencingVisitorWithRequestor.java:408)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.visitJDT(TypeInferencingVisitorWithRequestor.java:282)
    at org.eclipse.jdt.groovy.search.TypeInferencingVisitorWithRequestor.visitCompilationUnit(TypeInferencingVisitorWithRequestor.java:244)
    at org.codehaus.jdt.groovy.integration.internal.GroovyLanguageSupport.maybePerformDelegatedSearch(GroovyLanguageSupport.java:293)
    at org.codehaus.jdt.groovy.integration.LanguageSupportFactory.maybePerformDelegatedSearch(LanguageSupportFactory.java:118)
    at org.eclipse.jdt.internal.core.search.matching.MatchLocator.locateMatches(MatchLocator.java:1275)
    at org.eclipse.jdt.internal.core.search.matching.MatchLocator.locateMatches(MatchLocator.java:1397)
    at org.eclipse.jdt.internal.core.search.matching.MatchLocator.locateMatches(MatchLocator.java:1539)
    at org.eclipse.jdt.internal.core.search.JavaSearchParticipant.locateMatches(JavaSearchParticipant.java:109)
    at org.eclipse.jdt.internal.core.search.BasicSearchEngine.findMatches(BasicSearchEngine.java:247)
    at org.eclipse.jdt.internal.core.search.BasicSearchEngine.search(BasicSearchEngine.java:592)
    at org.eclipse.jdt.core.search.SearchEngine.search(SearchEngine.java:674)
    at org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine.internalSearch(RefactoringSearchEngine.java:143)
    at org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine.search(RefactoringSearchEngine.java:130)
    at org.eclipse.jdt.internal.corext.refactoring.rename.RenameFieldProcessor.getReferences(RenameFieldProcessor.java:608)
    at org.eclipse.jdt.internal.corext.refactoring.rename.RenameFieldProcessor.doCheckFinalConditions(RenameFieldProcessor.java:462)
    at org.eclipse.jdt.internal.corext.refactoring.rename.JavaRenameProcessor.checkFinalConditions(JavaRenameProcessor.java:48)
    at org.eclipse.ltk.core.refactoring.participants.ProcessorBasedRefactoring.checkFinalConditions(ProcessorBasedRefactoring.java:222)
    at org.eclipse.ltk.core.refactoring.CheckConditionsOperation.run(CheckConditionsOperation.java:83)
    at org.eclipse.ltk.core.refactoring.CreateChangeOperation.run(CreateChangeOperation.java:119)
    at org.eclipse.ltk.core.refactoring.PerformChangeOperation.run(PerformChangeOperation.java:207)
    at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2289)
    at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2316)
    at org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:86)
    at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:119)

This is the body of the mentioned test method:

	@Test
	public final void testPopulateAttestazioneDiAvvenutaTrasmissioneMessageFull() {
		def entity = new AttestazioneDiAvvenutaTrasmissioneEntity()
		entity.with {
			identificativoSdi = '123'
			nomeFile = 'nomeFile'
			dataOraRicezione = Date.parse('yyyy-MM-dd HH:mm:ss', '2014-10-17 15:46:01')
			riferimentoArchivio = new RiferimentoArchivioEmbeddable()
			codiceDestinatario = 'codiceDestinatario'
			descrizioneDestinatario = 'descrizioneDestinatario'
			messageId = 'messageId'
			pecMessageId = 'pecMessageId'
			note = 'note'
			hashFileOriginale = 'hashFileOriginale'
		}
		def model = new AttestazioneDiAvvenutaTrasmissioneMessage()
		assertSame(model, c.populateAttestazioneDiAvvenutaTrasmissioneMessage(entity, model))
		assertEquals('123', model.identificativoSdi)
		assertEquals('nomeFile', model.nomeFile)
		assertEquals('2014-10-17 15:46:01', model.dataOraRicezione.format('yyyy-MM-dd HH:mm:ss'))
		assertNotNull(model.riferimentoArchivio)
		assertEquals('codiceDestinatario', model.codiceDestinatario)
		assertEquals('descrizioneDestinatario', model.descrizioneDestinatario)
		assertEquals('messageId', model.messageId)
		assertEquals('pecMessageId', model.pecMessageId)
		assertEquals('note', model.note)
		assertEquals('hashFileOriginale', model.hashFileOriginale)
	}

Please note, the reference that should have been updated is on the last line: it was model.hashFileOriginale and should have been updated to model.hashFile (because I changed the field name from hashFileOriginale to hashFile and the corresponding getter method from getHashFileOriginale() to getHashFile()). However, it was changed in a wrong way to: model.getHashFile (which is neither a property-style access, nor a getter method access).

Please note that there's just a particular thing: the Java bean is something like that:

public class MyBean() {
  private Wrapper<String> hashFileOriginale = new Wrapper<>();

  public String getHashFileOriginale() { return hashFileOriginale.get(); }
  public void setHashOriginale(String v) { hashFileOrignale.set(v); }
}

In other words, the renamed field is not a classic Java Bean field but it's wrapped (and the getter and the setter perform the unwrapping).

I tried to isolate in a small test case but I was unsuccessful. I could get the exact same exception (NPE at org.eclipse.jdt.groovy.search.FieldReferenceSearchRequestor.acceptASTNode(FieldReferenceSearchRequestor.java:82)) but on a Groovy file that has nothing to do with the refactoring I'm performing (it contains a "foo" reference but for a field of a totally different class). If I just put the above Java bean and Groovy classes on the classpath, I don't get the exception.

Hope this information is enough to drive you to the right direction, otherwise let me know.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions