Skip to content

NullPointerException if passing an anonymous class to ReflectionsHint#registerType #29774

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

Closed
Artur- opened this issue Jan 5, 2023 · 5 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) theme: aot An issue related to Ahead-of-time processing type: bug A general bug
Milestone

Comments

@Artur-
Copy link
Contributor

Artur- commented Jan 5, 2023

If you (accidentally in this case) pass an anonymous class to registerType it fails with

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because the return value of "org.springframework.aot.hint.AbstractTypeReference.getCanonicalName()" is null
	at org.springframework.aot.hint.AbstractTypeReference.equals(AbstractTypeReference.java:93)
	at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1214)
	at org.springframework.aot.hint.ReflectionHints.registerType(ReflectionHints.java:85)
	at org.springframework.aot.hint.ReflectionHints.registerType(ReflectionHints.java:98)
	at org.springframework.aot.hint.ReflectionHints.registerType(ReflectionHints.java:120)

This happened to us when trying to use

for (var c : reflections.getSubTypesOf(Converter.class)) {
     reflection.registerType(c, memberCategories);
}

and so it happens that Converter contains

public interface Converter<PRESENTATION, MODEL> extends Serializable {
...
    static <P, M> Converter<P, M> from(
            SerializableFunction<P, Result<M>> toModel,
            SerializableFunction<M, P> toPresentation) {
        return new Converter<P, M>() {
...

Seems like the org.reflections library returns Converter$2 as one of the sub types, which then fails when passed to registerType.

@Artur-
Copy link
Contributor Author

Artur- commented Jan 5, 2023

Well for some reason it seems like adding com.vaadin.flow.data.converter.Converter$1 works fine but when it gets to com.vaadin.flow.data.converter.Converter$2 then it fails

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 5, 2023
Artur- added a commit to vaadin/flow that referenced this issue Jan 5, 2023
Artur- added a commit to vaadin/flow that referenced this issue Jan 5, 2023
Artur- added a commit to vaadin/flow that referenced this issue Jan 9, 2023
@sdeleuze sdeleuze self-assigned this Jan 9, 2023
@sdeleuze sdeleuze added the theme: aot An issue related to Ahead-of-time processing label Jan 9, 2023
@sbrannen sbrannen added the type: bug A general bug label Jan 31, 2023
@sdeleuze sdeleuze added this to the 6.0.6 milestone Feb 9, 2023
@sdeleuze sdeleuze removed the status: waiting-for-triage An issue we've not yet triaged or decided on label Feb 9, 2023
@sdeleuze sdeleuze changed the title NullPointerException if passing an anonymous class to ReflectionsHints.registerType NullPointerException if passing an anonymous class to ReflectionsHint#registerType Feb 24, 2023
@sdeleuze
Copy link
Contributor

For this one, I think I would assert that the class passed to ReflectionTypeReference#of is not null and has a non null canonical name, in order to have a more meaningful exception earlier. That would also be consistent with the kind of checks done in SimpleTypeReference. cc @bclozel

@Artur- That will not change the fact you need to avoid passing such class to ReflectionHints in your code, I don't think silently ignoring such class-based type reference would be a reasonable behavior.

@jhoeller jhoeller added the in: core Issues in core modules (aop, beans, core, context, expression) label Feb 28, 2023
@sdeleuze
Copy link
Contributor

sdeleuze commented Mar 1, 2023

@Artur- I implemented a solution that should fix the NullPointerException you see, keep a lenient behavior at ReflectionHints#registerType level, and assert that the class and related canonical name are not null at ReflectionTypeReference#of level.

We have a planned release tomorrow, so when the build is finished, would be great if you could test Spring Framework 6.0.6-SNAPSHOT to confirm it works as expected for you.

@Artur-
Copy link
Contributor Author

Artur- commented Mar 2, 2023

I tried 6.0.6-SNAPSHOT but run into something that is already in 6.0.5

Exception in thread "main" java.lang.IllegalArgumentException: Code generation is not supported for bean definitions declaring an instance supplier callback : Root bean: class [null]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodNames=null; destroyMethodNames=null

Need to figure that one out first..

@Artur-
Copy link
Contributor Author

Artur- commented Mar 2, 2023

Ok, Spring Boot vs Spring Framework conflict. With Spring Boot 3.0.3 + Spring Framework 6.0.6-SNAPSHOT everything works as expected, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) theme: aot An issue related to Ahead-of-time processing type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants