oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀
https://www.graalvm.org
Other
20.26k stars 1.62k forks source link

[GR-42095] Track object instantiation presenting stacktraces that are not possible #5267

Open galderz opened 1 year ago

galderz commented 1 year ago

Trace object instantiation can at times show stacktraces that will never be invoked by the application. You can find an example in Quarkus's Native Reference guide.

In there, a class that is build time initialized, initializes a cryptographic key pair in a static block:

public class EncryptDecryptResource {

    static final KeyPairGenerator KEY_PAIR_GEN;

    static {
        try {
            KEY_PAIR_GEN = KeyPairGenerator.getInstance("RSA");
            KEY_PAIR_GEN.initialize(1024);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new RuntimeException(e);
        }
    }

This causes an error because it would lead to a SecureRandom ending up in the build time heap:

Error: Unsupported features in 2 methods
Detailed message:
Error: Detected an instance of Random/SplittableRandom class in the image heap. Instances created during image generation have cached seed values and don't behave as expected.  To see how this object got instantiated use --trace-object-instantiation=java.security.SecureRandom. The object was probably created by a class initializer and is reachable from a static field. You can request class initialization at image runtime by using the option --initialize-at-run-time=<class-name>. Or you can write your own initialization methods and call them explicitly from your main entry point.
Trace: Object was reached by
    reading field java.security.KeyPairGenerator$Delegate.initRandom of
        constant java.security.KeyPairGenerator$Delegate@58b0fe1b reached by
    reading field org.acme.EncryptDecryptResource.KEY_PAIR_GEN
Error: Detected an instance of Random/SplittableRandom class in the image heap. Instances created during image generation have cached seed values and don't behave as expected.  To see how this object got instantiated use --trace-object-instantiation=java.security.SecureRandom. The object was probably created by a class initializer and is reachable from a static field. You can request class initialization at image runtime by using the option --initialize-at-run-time=<class-name>. Or you can write your own initialization methods and call them explicitly from your main entry point.
Trace: Object was reached by
    reading field sun.security.rsa.RSAKeyPairGenerator.random of
        constant sun.security.rsa.RSAKeyPairGenerator$Legacy@3248a092 reached by
    reading field java.security.KeyPairGenerator$Delegate.spi of
        constant java.security.KeyPairGenerator$Delegate@58b0fe1b reached by
    reading field org.acme.EncryptDecryptResource.KEY_PAIR_GEN

If you then pass in --trace-object-instantiation=java.security.SecureRandom to track object instantiation, it shows the following stacktrace, which is not something the application will call:

Error: Detected an instance of Random/SplittableRandom class in the image heap. Instances created during image generation have cached seed values and don't behave as expected.  Object has been initialized by the com.sun.jndi.dns.DnsClient class initializer with a trace:
    at java.security.SecureRandom.<init>(SecureRandom.java:218)
    at sun.security.jca.JCAUtil$CachedSecureRandomHolder.<clinit>(JCAUtil.java:59)
    at sun.security.jca.JCAUtil.getSecureRandom(JCAUtil.java:69)
    at com.sun.jndi.dns.DnsClient.<clinit>(DnsClient.java:82)

Sure, the DnsClient caches a SecureRandom statically, but the application doesn't call this. This kind of error reporting can be very confusing for the end user.

oubidar-Abderrahim commented 1 year ago

Hi, Thank you for reporting this. this is tracked internally GR 42095