Skip to content

Native compilation fails due to SecureRandom being statically built in AbstractAaedAdapter #3027

@fabmars

Description

@fabmars

General Troubleshooting

  • I have checked for similar issues on the Issue-tracker.
  • I have checked for PRs that might already address this issue.

Version of JDA

6.3.1

Expected Behaviour

I have tried native compiling a discord bot with Mandrel (a GraalVM variant) on Quarkus.
Turns out it fails because of statically initialized Random/SecureRandom.
Which is the case in net.dv8tion.jda.internal.audio.AbstractAaedAdapter

Fatal error: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: 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. Try avoiding to initialize the class that caused initialization of the object.
The culprit object has been instantiated by the 'net.dv8tion.jda.internal.audio.CryptoAdapter$AbstractAaedAdapter' class initializer with the following trace:
        at java.security.SecureRandom.<init>(SecureRandom.java:225)
        at net.dv8tion.jda.internal.audio.CryptoAdapter$AbstractAaedAdapter.<clinit>(CryptoAdapter.java:73)
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.
Object was reached by
  scanning root java.security.SecureRandom@b1ecbd4: NativePRNG embedded in
    net.dv8tion.jda.internal.audio.CryptoAdapter$AbstractAaedAdapter.<init>(CryptoAdapter.java:86)
  parsing method net.dv8tion.jda.internal.audio.CryptoAdapter$AbstractAaedAdapter.<init>(CryptoAdapter.java:81) reachable via the parsing context
    at net.dv8tion.jda.internal.audio.CryptoAdapter.getAdapter(CryptoAdapter.java:63)
    at net.dv8tion.jda.internal.audio.AudioWebSocket.handleEvent(AudioWebSocket.java:554)
    at net.dv8tion.jda.internal.audio.AudioWebSocket.onTextMessage(AudioWebSocket.java:295)
    at com.neovisionaries.ws.client.ListenerManager.callOnTextMessage(ListenerManager.java:369)
    at com.neovisionaries.ws.client.ReadingThread.callOnTextMessage(ReadingThread.java:233)
    at com.neovisionaries.ws.client.ReadingThread.handleTextFrame(ReadingThread.java:969)
    at com.neovisionaries.ws.client.ReadingThread.handleFrame(ReadingThread.java:752)
    at com.neovisionaries.ws.client.ReadingThread.main(ReadingThread.java:108)
    at com.neovisionaries.ws.client.ReadingThread.runMain(ReadingThread.java:64)
    at com.neovisionaries.ws.client.WebSocketThread.run(WebSocketThread.java:45)
    at java.util.OptionalLong.ifPresentOrElse(OptionalLong.java:185)
    at root method.(Unknown Source)

This is a pretty classic issue with GraalVM. Once it's no longer a static instance, a couple of build args to graal will get the native compilation to work.

On a side note, there is the same issue on the neovisionaries WS lib you're using. But I also saw #2860 which may solve that part of the problem.

As native compilation is getting more common, fixing this could be appreacited by your users.
I will try to provide with a MR

Code Example for Reproduction Steps

quarkus build --native

Code for JDABuilder or DefaultShardManagerBuilder used

JDABuilder.createLight(token, EnumSet.of(GatewayIntent.GUILD_MESSAGES, GatewayIntent.MESSAGE_CONTENT, GatewayIntent.DIRECT_MESSAGES)).build();

Exception or Error


Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions