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.38k stars 1.64k forks source link

Compatibility with netty-tcnative-boringssl-static #4580

Closed ulinay closed 11 months ago

ulinay commented 2 years ago

Dependency description

dependencies {
    compileOnly "org.projectlombok:lombok:${versions.lombok}"

    annotationProcessor "org.projectlombok:lombok:${versions.lombok}"
    annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"

    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    implementation 'org.springframework.boot:spring-boot-starter-data-redis-reactive'
    implementation ('org.springframework.boot:spring-boot-starter-actuator'){
        exclude group: 'io.micrometer', module: 'micrometer-core'
    }
    implementation 'org.springframework.boot:spring-boot-starter-aop'
    implementation 'org.springframework.boot:spring-boot-starter-validation'

    implementation "software.amazon.awssdk:sdk-core:${versions.awssdk_v2}"
    implementation "software.amazon.awssdk:dynamodb:${versions.awssdk_v2}"
    implementation "software.amazon.awssdk:netty-nio-client:${versions.awssdk_v2}"
    implementation "software.amazon.awssdk:sts:${versions.awssdk_v2}"
    implementation "software.amazon.awssdk:kinesis:${versions.awssdk_v2}"
    implementation "com.amazonaws:amazon-kinesis-producer:0.14.11"
    implementation "io.github.resilience4j:resilience4j-spring-boot2:${versions.resilience4jVersion}"
    implementation "io.github.resilience4j:resilience4j-reactor:${versions.resilience4jVersion}"
    implementation 'com.googlecode.json-simple:json-simple:1.1.1'
    implementation 'com.maxmind.geoip2:geoip2:2.12.0'
    implementation "javax.xml.bind:jaxb-api:2.3.1"
    implementation "com.sun.xml.bind:jaxb-core:3.0.2"
    implementation "com.sun.xml.bind:jaxb-impl:3.0.2"
    implementation "javax.activation:activation:1.1.1"
    runtimeOnly "io.netty:netty-tcnative-boringssl-static:2.0.52.Final:linux-x86_64"
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'io.projectreactor:reactor-test'
    testImplementation 'org.springframework:spring-test'
    testImplementation 'org.springframework.restdocs:spring-restdocs-webtestclient'
    testImplementation 'org.testcontainers:testcontainers:1.16.3'
    asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor'
}

Plugins

plugins {
    id 'idea'
    id 'java'
    id 'scala'
    id 'org.springframework.boot'            version '2.5.12'
    id 'io.spring.dependency-management'     version '1.0.11.RELEASE'
    id "org.asciidoctor.jvm.convert"         version "3.3.2"
    id 'com.palantir.docker'                 version '0.32.0'
    id 'com.gorylenko.gradle-git-properties' version '2.3.2'
    id 'jacoco'
    id 'io.gatling.gradle'                   version '3.7.3'
    id 'checkstyle'
    id 'com.github.ben-manes.versions'       version '0.41.0'
    id 'org.owasp.dependencycheck'           version '6.5.3'
    id 'org.springframework.experimental.aot' version '0.10.6'
    id 'com.google.osdetector'               version '1.7.0'
}

Native-image builder task

bootBuildImage {
    builder = "paketobuildpacks/builder:tiny"
    environment = [
            "BP_NATIVE_IMAGE" : "true",
            //"BP_NATIVE_IMAGE_BUILD_ARGUMENTS" : "--initialize-at-run-time=io.netty.handler.ssl.OpenSsl,io.netty.handler.ssl.OpenSslPrivateKeyMethod,io.netty.internal.tcnative.CertificateVerifier,io.netty.internal.tcnative.SSL,io.netty.internal.tcnative.SSLPrivateKeyMethod"
    ]
    imageName = "gos/gos-api-4:latest"
}

Problem description

When I run task bootBuildImage I've got an error:

 Error: Classes that should be initialized at run time got initialized during image building:
    [creator]      io.netty.buffer.PooledSlicedByteBuf the class was requested to be initialized at run time (subtype of io.netty.buffer.AbstractReferenceCountedByteBuf). To see why io.netty.buffer.PooledSlicedByteBuf got initialized use --trace-class-initialization=io.netty.buffer.PooledSlicedByteBuf
    [creator]     io.netty.buffer.UnpooledHeapByteBuf the class was requested to be initialized at run time (subtype of io.netty.buffer.AbstractReferenceCountedByteBuf). To see why io.netty.buffer.UnpooledHeapByteBuf got initialized use --trace-class-initialization=io.netty.buffer.UnpooledHeapByteBuf
    [creator]     io.netty.util.AbstractReferenceCounted the class was requested to be initialized at run time (from 'META-INF/native-image/io.netty/common/native-image.properties' in 'file:///workspace/BOOT-INF/lib/netty-common-4.1.75.Final.jar' with 'io.netty.util.AbstractReferenceCounted'). To see why io.netty.util.AbstractReferenceCounted got initialized use --trace-class-initialization=io.netty.util.AbstractReferenceCounted
    [creator]     io.netty.buffer.ByteBufAllocator the class was requested to be initialized at run time (from 'META-INF/native-image/io.netty/buffer/native-image.properties' in 'file:///workspace/BOOT-INF/lib/netty-buffer-4.1.75.Final.jar' with 'io.netty.buffer.ByteBufAllocator'). To see why io.netty.buffer.ByteBufAllocator got initialized use --trace-class-initialization=io.netty.buffer.ByteBufAllocator
    [creator]     io.netty.handler.ssl.PemValue the class was requested to be initialized at run time (subtype of io.netty.util.AbstractReferenceCounted). To see why io.netty.handler.ssl.PemValue got initialized use --trace-class-initialization=io.netty.handler.ssl.PemValue
    [creator]     io.netty.buffer.UnpooledUnsafeNoCleanerDirectByteBuf the class was requested to be initialized at run time (subtype of io.netty.buffer.AbstractReferenceCountedByteBuf). To see why io.netty.buffer.UnpooledUnsafeNoCleanerDirectByteBuf got initialized use --trace-class-initialization=io.netty.buffer.UnpooledUnsafeNoCleanerDirectByteBuf
    [creator]     io.netty.handler.ssl.PemPrivateKey the class was requested to be initialized at run time (subtype of io.netty.util.AbstractReferenceCounted). To see why io.netty.handler.ssl.PemPrivateKey got initialized use --trace-class-initialization=io.netty.handler.ssl.PemPrivateKey
    [creator]     io.netty.buffer.UnpooledDirectByteBuf the class was requested to be initialized at run time (subtype of io.netty.buffer.AbstractReferenceCountedByteBuf). To see why io.netty.buffer.UnpooledDirectByteBuf got initialized use --trace-class-initialization=io.netty.buffer.UnpooledDirectByteBuf
    [creator]     io.netty.buffer.AbstractPooledDerivedByteBuf the class was requested to be initialized at run time (subtype of io.netty.buffer.AbstractReferenceCountedByteBuf). To see why io.netty.buffer.AbstractPooledDerivedByteBuf got initialized use --trace-class-initialization=io.netty.buffer.AbstractPooledDerivedByteBuf
    [creator]     io.netty.buffer.PooledUnsafeDirectByteBuf the class was requested to be initialized at run time (subtype of io.netty.buffer.AbstractReferenceCountedByteBuf). To see why io.netty.buffer.PooledUnsafeDirectByteBuf got initialized use --trace-class-initialization=io.netty.buffer.PooledUnsafeDirectByteBuf
    [creator]     io.netty.internal.tcnative.SSL the class was requested to be initialized at run time (from 'META-INF/native-image/software.amazon.awssdk/netty-nio-client/native-image.properties' in 'file:///workspace/BOOT-INF/lib/netty-nio-client-2.17.162.jar' with 'io.netty.internal.tcnative.SSL'). To see why io.netty.internal.tcnative.SSL got initialized use --trace-class-initialization=io.netty.internal.tcnative.SSL
    [creator]     io.netty.buffer.ByteBufUtil the class was requested to be initialized at run time (from 'META-INF/native-image/io.netty/buffer/native-image.properties' in 'file:///workspace/BOOT-INF/lib/netty-buffer-4.1.75.Final.jar' with 'io.netty.buffer.ByteBufUtil'). To see why io.netty.buffer.ByteBufUtil got initialized use --trace-class-initialization=io.netty.buffer.ByteBufUtil
    [creator]     io.netty.buffer.PooledByteBufAllocator the class was requested to be initialized at run time (from 'META-INF/native-image/io.netty/buffer/native-image.properties' in 'file:///workspace/BOOT-INF/lib/netty-buffer-4.1.75.Final.jar' with 'io.netty.buffer.PooledByteBufAllocator'). To see why io.netty.buffer.PooledByteBufAllocator got initialized use --trace-class-initialization=io.netty.buffer.PooledByteBufAllocator
    [creator]     io.netty.buffer.UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeNoCleanerDirectByteBuf the class was requested to be initialized at run time (subtype of io.netty.buffer.AbstractReferenceCountedByteBuf). To see why io.netty.buffer.UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeNoCleanerDirectByteBuf got initialized use --trace-class-initialization=io.netty.buffer.UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeNoCleanerDirectByteBuf
    [creator]     io.netty.buffer.AbstractReferenceCountedByteBuf the class was requested to be initialized at run time (from 'META-INF/native-image/io.netty/buffer/native-image.properties' in 'file:///workspace/BOOT-INF/lib/netty-buffer-4.1.75.Final.jar' with 'io.netty.buffer.AbstractReferenceCountedByteBuf'). To see why io.netty.buffer.AbstractReferenceCountedByteBuf got initialized use --trace-class-initialization=io.netty.buffer.AbstractReferenceCountedByteBuf
    [creator]     io.netty.buffer.PooledByteBuf the class was requested to be initialized at run time (subtype of io.netty.buffer.AbstractReferenceCountedByteBuf). To see why io.netty.buffer.PooledByteBuf got initialized use --trace-class-initialization=io.netty.buffer.PooledByteBuf
    [creator]     io.netty.buffer.UnpooledUnsafeDirectByteBuf the class was requested to be initialized at run time (subtype of io.netty.buffer.AbstractReferenceCountedByteBuf). To see why io.netty.buffer.UnpooledUnsafeDirectByteBuf got initialized use --trace-class-initialization=io.netty.buffer.UnpooledUnsafeDirectByteBuf

I know how to fix it, just add this argument to bootBuildImage: --initialize-at-run-time=io.netty.handler.ssl.OpenSsl,io.netty.handler.ssl.OpenSslPrivateKeyMethod,io.netty.internal.tcnative.CertificateVerifier,io.netty.internal.tcnative.SSL,io.netty.internal.tcnative.SSLPrivateKeyMethod

In this case application is build successfully and I've got docker image. But when I run my docker image I've got this error, because OpenSsl class was added as run time initialization. How can I fix it ?

software.amazon.awssdk.core.exception.SdkClientException: Unable to execute HTTP request: failed to load the required native library
Caused by: java.lang.IllegalArgumentException: Failed to load any of the given libraries: [netty_tcnative_linux_x86_64, netty_tcnative_linux_x86_64_fedora, netty_tcnative_x86_64, netty_tcnative]
oubidar-Abderrahim commented 2 years ago

Hi, Thank you for reporting this. Which version of GraalVM you're using? did you generate config files before building the native image

ulinay commented 2 years ago
  1. Version info: 'GraalVM 22.1.0 Java 11 CE'
  2. Yes, I have some configurations in /META-INT/native-image/ folder:

proxy-config.json

[
  { "interfaces": [ "org.apache.http.conn.HttpClientConnectionManager", "org.apache.http.pool.ConnPoolControl", "com.amazonaws.http.conn.Wrapped"] },
  { "interfaces" : [ "org.springframework.boot.jackson.JsonComponent", "org.springframework.core.annotation.SynthesizedAnnotation"]}
]

reflect-config.json

[
  {
    "name" : "com.amazonaws.partitions.model.Partitions",
    "allPublicMethods" : true,
    "allDeclaredConstructors" : true
  }, {
  "name" : "com.amazonaws.partitions.model.Partition",
  "allPublicMethods" : true,
  "allDeclaredConstructors" : true
}, {
  "name" : "com.amazonaws.partitions.model.Endpoint",
  "allPublicMethods" : true,
  "allDeclaredConstructors" : true
}, {
  "name" : "com.amazonaws.partitions.model.Region",
  "allPublicMethods" : true,
  "allDeclaredConstructors" : true
}, {
  "name" : "com.amazonaws.partitions.model.Service",
  "allPublicMethods" : true,
  "allDeclaredConstructors" : true
}, {
  "name" : "com.amazonaws.partitions.model.CredentialScope",
  "allPublicMethods" : true,
  "allDeclaredConstructors" : true
}, {
  "name" : "java.util.HashSet",
  "allPublicMethods" : true,
  "allDeclaredConstructors" : true
},
  {
  "name": "io.netty.channel.socket.nio.NioDatagramChannel",
    "allPublicMethods" : true,
    "allDeclaredConstructors" : true
},
  {
  "name": "org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean",
    "allPublicMethods" : true,
    "allDeclaredConstructors" : true
  },
  {
    "name": "org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer",
    "allPublicMethods" : true,
    "allDeclaredConstructors" : true,
    "allDeclaredClasses": true,
    "allPublicClasses" : true
  }
]

resource-config.json

{
  "resources": [
    {
      "pattern": ".*\\.yml$"
    },
    {
      "pattern": ".*\\.json$"
    },
    {
      "pattern": ".*\\.properties$"
    },
    {
      "pattern": ".*\\.env$"
    }
  ]
}
oubidar-Abderrahim commented 2 years ago

Is it possible to share a reproducer for this?

oubidar-Abderrahim commented 11 months ago

Closing for inactivity