Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JDT Core throws NPE: Cannot invoke "AnnotationBinding.getAnnotationType()" because "annotationBinding" is null #2400

Closed
r0texx opened this issue Apr 30, 2024 · 1 comment · Fixed by #2433
Assignees

Comments

@r0texx
Copy link

r0texx commented Apr 30, 2024

Hello,

I'm trying to build sources, but JDT Core throws an exception:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding.getAnnotationType()" because "annotationBinding" is null
	at org.eclipse.jdt.internal.compiler.problem.ProblemReporter.deprecatedSinceValue(ProblemReporter.java:2010)
	at org.eclipse.jdt.internal.compiler.problem.ProblemReporter.deprecatedType(ProblemReporter.java:1969)
	at org.eclipse.jdt.internal.compiler.ast.TypeReference.reportDeprecatedType(TypeReference.java:589)
	at org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference.getTypeBinding(QualifiedTypeReference.java:152)
	at org.eclipse.jdt.internal.compiler.ast.TypeReference.internalResolveType(TypeReference.java:526)
	at org.eclipse.jdt.internal.compiler.ast.TypeReference.resolveType(TypeReference.java:629)
	at org.eclipse.jdt.internal.compiler.ast.TypeReference.resolveType(TypeReference.java:625)
	at org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.resolveTypeFor(SourceTypeBinding.java:2676)
	at org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.fields(SourceTypeBinding.java:1551)
	at org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.internalFaultInTypeForFieldsAndMethods(SourceTypeBinding.java:1518)
	at org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding.faultInTypesForFieldsAndMethods(SourceTypeBinding.java:1114)
	at org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope.faultInTypes(CompilationUnitScope.java:608)
	at org.eclipse.jdt.internal.compiler.Compiler.process(Compiler.java:897)
	at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(CompilationUnitResolver.java:1122)
	at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(CompilationUnitResolver.java:739)
	at org.eclipse.jdt.core.dom.ASTParser.createASTs(ASTParser.java:1049)

For the following test sources (save it to a directory and change the ROOT variable):
1.

package test;

@com.Missing
@java.lang.Deprecated
public class TestClass {
}
package test;

public class com {
    test.TestClass value;
}

I use the following code to parse it using JDT Core:

package main;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.FileASTRequestor;

public class PoCMain {
    private static final File ROOT = new File("PATH_WHERE_YOU_UNPACK_two_files");
    
    public static void main(String[] args) throws Throwable {
        List<String> files = findSources(ROOT, ".java");
        getParser().createASTs(files.toArray(new String[files.size()]), null, new String[0], new FileASTRequestor() {}, null);
    }
    
    private static ASTParser getParser() {
        ASTParser astParser = ASTParser.newParser(AST.JLS21);
        astParser.setResolveBindings(true);
        astParser.setStatementsRecovery(true);
        astParser.setBindingsRecovery(true);
        astParser.setKind(ASTParser.K_COMPILATION_UNIT);
        astParser.setEnvironment(new String[0], new String[0], null, false);
        
        Map<String, String> options = JavaCore.getDefaultOptions();
        options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_21);
        options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_21);
        options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_21);
        astParser.setCompilerOptions(options);
        return astParser;
    }
    
    private static List<String> findSources(File dir, String ext) {
        List<String> paths = new ArrayList<>();
        for (File child : dir.listFiles()) {
            if (child.isFile()) {
                if (child.getName().endsWith(ext)) {
                    paths.add(child.getAbsolutePath());
                }
            } else {
                paths.addAll(findSources(child, ext));
            }
        }
        
        return paths;
    }
}
@jarthana jarthana self-assigned this May 9, 2024
@jarthana
Copy link
Member

Reproduced on master. This happens only when there's a @Deprecated and an unresolved annotation in the mix and the unresolved one precedes the @Deprecated. The unresolved annotation returns null when asked getCompilerAnnotation(). But I think it's okay, looking at ASTNode#copySE8AnnotationsToType(), line number 1160. The simplest fix would be to do a null check inside ProblemReporter.deprecatedSinceValue().

@jarthana jarthana changed the title JDT Core throws NullPointerException: Cannot invoke "org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding.getAnnotationType()" because "annotationBinding" is null JDT Core throws NPE: Cannot invoke "AnnotationBinding.getAnnotationType()" because "annotationBinding" is null May 10, 2024
jarthana added a commit to jarthana/eclipse.jdt.core that referenced this issue May 10, 2024
"AnnotationBinding.getAnnotationType()" because "annotationBinding" is
null
eclipse-jdt#2400
jarthana added a commit that referenced this issue May 14, 2024
…e() because annotationBinding is null (#2400)

Just as we are doing elsewhere, ignore annotation that have null bindings

#2433
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants