Search code examples
quarkusquarkus-native

DnsClient Incompatible change


I've added some DNS activities (mostly TXT lookups) to my micro-service. After adding these I'm unable to package as per normal issuing ./mvnw package -DskipTests --activate-profiles native --also-make

After adding the lookup routines the following is returned

Error: Incompatible change of initialization policy for com.sun.jndi.dns.DnsClient: trying to change RUN_TIME from command line with 'com.sun.jndi.dns.DnsClient' to RERUN Contains Random references, therefore can't be included in the image heap.
com.oracle.svm.core.util.UserError$UserException: Incompatible change of initialization policy for com.sun.jndi.dns.DnsClient: trying to change RUN_TIME from command line with 'com.sun.jndi.dns.DnsClient' to RERUN Contains Random references, therefore can't be included in the image heap.


the relevant part (I believe) of my applications.properties file is currently

quarkus.native.additional-build-args=\
  -H:+PrintClassInitialization,\
  --report-unsupported-elements-at-runtime,\
  --trace-class-initialization=java.security.SecureRandom,\
  --initialize-at-run-time=java.security.SecureRandom\\,sun.security.jca.JCAUtil\\,com.sun.jndi.dns.DnsClient

Before adding the DNS related methods I did not have quarkus.native.additional-build-args in my application.properties file. After adding the DNS routines there were errors related to java.security.SecureRandom about which there were some hints at Quarkus - TIPS FOR WRITING NATIVE APPLICATIONS and so I added

quarkus.native.additional-build-args=\
  -H:+PrintClassInitialization,\
  --report-unsupported-elements-at-runtime,\
  --initialize-at-run-time=java.security.SecureRandom

this got me a bit further but still returned

Error: Classes that should be initialized at run time got initialized during image building:
 java.security.SecureRandom the class was requested to be initialized at run time (from command line with 'java.security.SecureRandom'). To see why java.security.SecureRandom got initialized use --trace-class-initialization=java.security.SecureRandom
To see how the classes got initialized, use --trace-class-initialization=java.security.SecureRandom
com.oracle.svm.core.util.UserError$UserException: Classes that should be initialized at run time got initialized during image building:
 java.security.SecureRandom the class was requested to be initialized at run time (from command line with 'java.security.SecureRandom'). To see why java.security.SecureRandom got initialized use --trace-class-initialization=java.security.SecureRandom

so modified application.properties as with --trace-class-initialization=java.security.SecureRandom as directed in the error message to get the new error message

Error: Classes that should be initialized at run time got initialized during image building:
 java.security.SecureRandom the class was requested to be initialized at run time (from command line with 'java.security.SecureRandom'). com.sun.jndi.dns.DnsClient caused initialization of this class with the following trace: 
        at java.security.SecureRandom.<clinit>(SecureRandom.java:158)
        at sun.security.jca.JCAUtil$CachedSecureRandomHolder.<clinit>(JCAUtil.java:58)
        at sun.security.jca.JCAUtil.getSecureRandom(JCAUtil.java:70)
        at com.sun.jndi.dns.DnsClient.<clinit>(DnsClient.java:86)


com.oracle.svm.core.util.UserError$UserException: Classes that should be initialized at run time got initialized during image building:
 java.security.SecureRandom the class was requested to be initialized at run time (from command line with 'java.security.SecureRandom'). com.sun.jndi.dns.DnsClient caused initialization of this class with the following trace: 
        at java.security.SecureRandom.<clinit>(SecureRandom.java:158)
        at sun.security.jca.JCAUtil$CachedSecureRandomHolder.<clinit>(JCAUtil.java:58)
        at sun.security.jca.JCAUtil.getSecureRandom(JCAUtil.java:70)
        at com.sun.jndi.dns.DnsClient.<clinit>(DnsClient.java:86)

this is how I reached my current application.properties entry of quarkus.native.additional-build-args of

quarkus.native.additional-build-args=\
  -H:+PrintClassInitialization,\
  --report-unsupported-elements-at-runtime,\
  --trace-class-initialization=java.security.SecureRandom,\
  --initialize-at-run-time=java.security.SecureRandom\\,sun.security.jca.JCAUtil\\,com.sun.jndi.dns.DnsClient

I do have a local copy of graalvm with native installed that I have been using but have also tried with quarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-native-image:22.3-java17 and quay.io/quarkus/ubi-quarkus-mandrel-builder-image:22.3-java17 where I've set quarkus.native.container-build=true

I'm not sure what I can try next. Or, if that the use of the com.sun.jndi.dns.DnsClient means that a native package is out of the question. Any hints would be welcome.


Solution

  • It might not be the answer you are looking for, but I would not use JNDI to read a TXT record. You can use the Vert.x DNS client to achieve the same thing and that would work in native OOTB.

    So something like:

    @Inject Vertx vertx;
    
    // ...
    var dns = vertx.createDnsClient(...);
    

    See https://vertx.io/docs/vertx-core/java/#_dns_client.