Attempting to build AWS IoT Client with GraalVM native-image

Install with Brew (20.2.0):

brew cask install graalvm-ce-java11

Magic from https://github.com/graalvm/homebrew-tap:

export PATH=/Library/Java/JavaVirtualMachines/graalvm-ce-java11-20.3.0/Contents/Home/bin:"$PATH"
export JAVA_HOME=/Library/Java/JavaVirtualMachines/graalvm-ce-java11-20.3.0/Contents/Home

Then install native image with gu:

gu list
gu available
gu install native-image

It's a big bucket of fail but it looks like this:

./gradlew build
native-image -cp build/libs/aws-iot-client.jar com.awslabs.iot.client.applications.AwsIotClientConsole --no-fallback --allow-incomplete-classpath -H:+TraceClassInitialization --initialize-at-build-time

And it looks like it is working but bombs out like this:

Neglected Github issue here - https://github.com/oracle/graal/issues/2063

Removed Paho and it built something but it failed on Sun security stuff. Fixed that with this:

native-image -cp build/libs/aws-iot-client.jar com.awslabs.iot.client.applications.AwsIotClientConsole --no-fallback --allow-incomplete-classpath -H:+TraceClassInitialization --initialize-at-build-time --enable-http --enable-https --enable-url-protocols=http,https --enable-all-security-services

Then the logger failed. Created a reflection configuration file reflection-config.json:

[
    {
        "name": "java.lang.String"
    },
    {
        "name": "java.lang.Thread"
    },
    {
        "name": "org.apache.commons.logging.LogFactory"
    },
    {
        "name": "org.apache.commons.logging.impl.SimpleLog"
    }
]

And then used this command:

native-image -cp build/libs/aws-iot-client.jar com.awslabs.iot.client.applications.AwsIotClientConsole --no-fallback --allow-incomplete-classpath -H:+TraceClassInitialization --initialize-at-build-time --enable-http --enable-https --enable-url-protocols=http,https --enable-all-security-services -H:ReflectionConfigurationFiles=reflection-config.json

And it still fails. Cool. It says this:

Caused by: java.lang.InstantiationException: Type `org.apache.commons.logging.impl.LogFactoryImpl` can not be instantiated reflectively as it does not have a no-parameter constructor or the no-parameter constructor has not been added explicitly to the native image.

This other command at least gives a different HTTP error:

Which looks like this:

Exception in thread "main" software.amazon.awssdk.core.exception.SdkClientException: Unable to load an HTTP implementation from any provider in the chain. You must declare a dependency on an appropriate HTTP implementation or pass in an SdkHttpClient explicitly to the client builder.

New reflect config from https://stackoverflow.com/a/56947164/796579:

New command based on error message:

That failed Could not find dynamic proxy configuration resource "org.apache.http.conn.HttpClientConnectionManager"

Then created dynamic-proxies.json based on this https://github.com/oracle/graal/issues/1028:

dynamic-proxies.json

[
  ["org.apache.http.conn.HttpClientConnectionManager", "org.apache.http.pool.ConnPoolControl", "com.amazonaws.http.conn.Wrapped"]
]

New command:

That no longer works with 20.3.0:

Deprecation warning so I did this:

Generate list of every single AWS class for inclusion in reflection:

New new new command: