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

Some Collection and Map fallbacks don't work in GraalVM native image #4299

Closed
edudar opened this issue Jan 3, 2024 · 7 comments
Closed

Some Collection and Map fallbacks don't work in GraalVM native image #4299

edudar opened this issue Jan 3, 2024 · 7 comments
Labels
to-evaluate Issue that has been received but not yet evaluated

Comments

@edudar
Copy link
Contributor

edudar commented Jan 3, 2024

Is your feature request related to a problem? Please describe.

I'm trying to run a service compiled with GraalVM into a native image. The service does not reference or create HashSet explicitly and uses Set in all DTOs instead. Upon deserialization, an exception happens that says that "java.util.HashSet can't be created because no creator, like default constructor, exists". Those are removed by dead code elimination as none are registered for reflection or used explicitly, and ContainerDefaultMappings provides just a class reference that is used later to create a given set via newInstance.

Describe the solution you'd like

My current solution using Spring Boot is to simply register these classes for reflection:

hints.reflection()
        .registerTypes(TypeReference.listOf(
                        ArrayList.class,
                        LinkedList.class,
                        HashSet.class,
                        TreeSet.class,
                        ConcurrentHashMap.class,
                        LinkedHashMap.class,
                        TreeMap.class),
                TypeHint.builtWith(INVOKE_PUBLIC_CONSTRUCTORS, INVOKE_PUBLIC_METHODS));

This is not perfect, though.

Another approach might be to create appropriate value instantiators in JDKValueInstantiators for every fallback collection as they specifically tell what constructor will be used.

Usage example

No response

Additional context

No response

@edudar edudar added the to-evaluate Issue that has been received but not yet evaluated label Jan 3, 2024
@cowtowncoder
Copy link
Member

Interesting. I would have thought dependency via JDKValueInstantiators would be enough to pull in dependencies....
I wonder if a small change would force GraalVM compiler to add dependencies?

I am open to suggestions for solution here.

@edudar
Copy link
Contributor Author

edudar commented Jan 3, 2024

It helps with classes it creates, but these are only ArrayList and LinkedHashMap/HashMap. Other lists, sets, and maps get nuked. Expanding JDKValueInstantiators to cover more common creators would probably help.

@cowtowncoder
Copy link
Member

Ok. So those types are found at least. And due to defaulting, I guess adding support for others seems sensible too.

@edudar
Copy link
Contributor Author

edudar commented Jan 4, 2024

BTW, I added a simple but close-to-real reproducer for this issue at https://github.com/edudar/feign-native. It fails with the default Jackson version (2.15.3) and succeeds with a locally built 2.17.0 snapshot.

@cowtowncoder
Copy link
Member

cowtowncoder commented Jan 4, 2024

Thanks @edudar that is a good validation; important to know fix actually works for intended problem.

Aside from CLA for PR, the only thing I really was hoping to clarify was whether eager construction of ValueInstantiators was required for fix to work. Ideally it'd be nice to only eager instantiate ones that are very likely to be used (which is for types that are default mappings), and defer others to as-needed basis.
It may seem silly but I have tried to limit default set of eager static initializations to try to reduce startup overhead (granted these are very small portion of everything).

@edudar
Copy link
Contributor Author

edudar commented Jan 4, 2024

Eager instantiation is not required for the fix. The main difference is explicit instantiation vs. reflection via default constructor.

@cowtowncoder cowtowncoder changed the title Collection and Map fallbacks in GraalVM native image Some Collection and Map fallbacks don't work in GraalVM native image Jan 16, 2024
@edudar edudar closed this as completed Jan 25, 2024
@cowtowncoder
Copy link
Member

Thank you @edudar ! If possible, could you check that the resulting version (2.17.0-SNAPSHOT) works as expected? (if you haven't already done so). I assume it does, just want to make sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
to-evaluate Issue that has been received but not yet evaluated
Projects
None yet
Development

No branches or pull requests

2 participants