quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.68k stars 2.65k forks source link

Native Image SSL Problem #2125

Open mertmr opened 5 years ago

mertmr commented 5 years ago

Although I have followed all the directions in the documentations(https://quarkus.io/guides/native-and-ssl-guide) I am getting an annoying warning and error at the end of my microprofile rest client to the service with SSL(only in native image, not in development):

WARNING: The sunec native library, required by the SunEC provider, could not be loaded.

Caused by: java.lang.UnsatisfiedLinkError: sun.security.ec.ECKeyPairGenerator.generateECKeyPair(I[B[B)[Ljava/lang/Object; [symbol: Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair or Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair__I_3B_3B]

I had followed these steps to produce the native image:

mvn package -Pnative -Dnative-image.docker-build=true docker build -f src/main/docker/Dockerfile.native -t dockerrepo.company.com/appTodo docker run -i --rm -p 8080:8080 dockerrepo.company.com/appTodo

And I put all the SSL configuration that I can find from the documentations in the maven plugin:

                    <plugin>
                        <groupId>io.quarkus</groupId>
                        <artifactId>quarkus-maven-plugin</artifactId>
                        <version>${quarkus.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>native-image</goal>
                                </goals>
                                <configuration>
                                    <enableHttpUrlHandler>true</enableHttpUrlHandler>
                                    <enableJni>true</enableJni>
                                    <enableAllSecurityServices>true</enableAllSecurityServices>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>

Any additional steps did I miss?

gsmet commented 5 years ago

Hi Mert,

Did you see the section talking about the SunEC library? You need to include it in your Docker image and pass system properties.

Unfortunately, it's not yet automatized.

mertmr commented 5 years ago

Thanks for the quick response, can you elaborate your suggestions a little bit more? I am not really good at Docker and I don't know how to add the library do the image and properties. I am using the default Dockerfile.native

FROM registry.fedoraproject.org/fedora-minimal
ENV ENV dev
WORKDIR /work/
COPY target/*-runner /work/application
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
gsmet commented 5 years ago

You need to copy the cacerts file and the SunEC library inside your container (see the COPY above, the files should be $GRAALVM_HOME/jre/lib/security/cacerts for one and $GRAALVM_HOME/jre/lib/amd64/libsunec.so on Linux, it's a bit different on macOS). You can copy them in your VM (I would suggest to put the .so in a lib/ directory).

Then you need to add a , "-Djava.library.path=./lib", -Djavax.net.ssl.trustStore=./cacerts" to your CMD.

Please report back your findings. Once we get something working, it could probably be added to the documentation.

soberich commented 5 years ago

@gsmet Also, this line -H:EnableURLProtocols=http,https --enable-all-security-services contain redundant flags/args https://github.com/quarkusio/quarkus/blob/master/docs/src/main/asciidoc/native-and-ssl-guide.adoc --enable-all-security-services is automatically enabled when https protocol enabled. see

https://github.com/oracle/graal/blob/master/substratevm/JCA-SECURITY-SERVICES.md

https://github.com/oracle/graal/blob/master/substratevm/URL-PROTOCOLS.md

gsmet commented 5 years ago

@soberich Having both of them set doesn't hurt :).

@mertmr did you get it to work?

anadollu commented 5 years ago

You need to copy the cacerts file and the SunEC library inside your container (see the COPY above, the files should be $GRAALVM_HOME/jre/lib/security/cacerts for one and $GRAALVM_HOME/jre/lib/amd64/libsunec.so on Linux, it's a bit different on macOS). You can copy them in your VM (I would suggest to put the .so in a lib/ directory).

Then you need to add a , "-Djava.library.path=./lib", -Djavax.net.ssl.trustStore=./cacerts" to your CMD.

Please report back your findings. Once we get something working, it could probably be added to the documentation.

I follow the instructions you wrote, does not work.

mb010865 commented 5 years ago

Copying the libsunec.so was not enough for me. Copying the whole /jre/lib/amd64 directory works for me. But as its a lot maybe there is a subset of .so files that works too.

anadollu commented 5 years ago

@mb010865 Thank You Michael, It worked with whole /jre/lib/amd64 directory. @gsmet You are right, it should be added to doc. I spent two days on it. The only one thing left that, Michael already mentioned about, only adding libsunec.so dependencies would be enough.

mb010865 commented 5 years ago

Surprisingly it now works with adding only libsunec.so. Maybe because of upgrade to 0.16.1?

gsmet commented 5 years ago

We haven’t changed anything regarding the SSL support for a while.

@anadollu can you check if it’s OK for you too?

anadollu commented 5 years ago

@gsmet i am using master branch (999-SNAPSHOT) and not working with only libsunec.so file.

haroldjcastillo commented 5 years ago

Hi @gsmet @anadollu, I'm not sure why it does not work.

In my dockerfile I have:

FROM registry.access.redhat.com/ubi8/ubi-minimal
WORKDIR /work/
COPY target/*-runner /work/application
COPY ssl/cacerts /work/cacerts
COPY ssl/lib /work/lib
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0", "-Djava.library.path=./lib", "-Djavax.net.ssl.trustStore=./cacerts"]

docker build -f src/main/docker/Dockerfile.native -t test-image . docker run -i --rm -p 8080:8080 test-image

ssl and target folder contents is copied into the WORKDIR, ex:

drwxr-xr-x 4 root root     4096 Jun 27 05:25 lib
-rw-r--r-- 1 root root   102225 Feb  6 13:37 cacerts
-rwxr-xr-x 1 root root 57492336 Jun 27 04:06 application

In the container, I have a folder lib with the amd64

bash-4.4# ls -lr lib/
total 50568
drwxr-xr-x 2 root root     4096 Jun 27 03:47 server
-rwxr-xr-x 1 root root   131934 Feb  6 13:37 libzip.so
-rwxr-xr-x 1 root root    74267 Feb  6 13:37 libverify.so
-rwxr-xr-x 1 root root   168887 Feb  6 13:37 libunpack.so
-rwxr-xr-x 1 root root   254108 Apr 18 14:50 libtrufflenfi.so
-rwxr-xr-x 1 root root   259678 Feb  6 13:37 libsunec.so
-rwxr-xr-x 1 root root   453022 Feb  6 13:37 libsplashscreen.so
-rwxr-xr-x 1 root root    29911 Feb  6 13:37 libsctp.so
-rwxr-xr-x 1 root root    57712 Apr 17 08:39 libsaproc.so
-rwxr-xr-x 1 root root    17646 Feb  6 13:37 libnpt.so
-rwxr-xr-x 1 root root    95695 Feb  6 13:37 libnio.so
-rwxr-xr-x 1 root root   118593 Feb  6 13:37 libnet.so
-rwxr-xr-x 1 root root  9624286 Apr 18 15:29 libnative-image-agent.so
-rwxr-xr-x 1 root root   915504 Feb  6 13:37 libmlib_image.so
-rwxr-xr-x 1 root root    52842 Feb  6 13:37 libmanagement.so
-rwxr-xr-x 1 root root   430691 Feb  6 13:37 liblcms.so
-rwxr-xr-x 1 root root 33902194 Apr 18 15:30 libjvmcicompiler.so
-rwxr-xr-x 1 root root    84134 Feb  6 13:37 libjsoundalsa.so
-rwxr-xr-x 1 root root     8550 Feb  6 13:37 libjsound.so
-rwxr-xr-x 1 root root    11235 Apr 17 08:39 libjsig.so
-rwxr-xr-x 1 root root    13002 Feb  6 13:37 libjsdt.so
-rwxr-xr-x 1 root root   234994 Feb  6 13:37 libjpeg.so
-rwxr-xr-x 1 root root   274391 Feb  6 13:37 libjdwp.so
-rwxr-xr-x 1 root root     8333 Feb  6 13:37 libjawt.so
-rwxr-xr-x 1 root root    26178 Feb  6 13:37 libjava_crw_demo.so
-rwxr-xr-x 1 root root   228649 Feb  6 13:37 libjava.so
-rwxr-xr-x 1 root root     8368 Feb  6 13:37 libjaas_unix.so
-rwxr-xr-x 1 root root    80108 Feb  6 13:37 libj2pkcs11.so
-rwxr-xr-x 1 root root    18520 Feb  6 13:37 libj2pcsc.so
-rwxr-xr-x 1 root root    47917 Feb  6 13:37 libj2gss.so
-rwxr-xr-x 1 root root    52369 Feb  6 13:37 libinstrument.so
-rwxr-xr-x 1 root root   212150 Feb  6 13:37 libhprof.so
-rwxr-xr-x 1 root root  1900948 Feb  6 13:37 libfreetype.so.6
-rwxr-xr-x 1 root root   541107 Feb  6 13:37 libfontmanager.so
-rwxr-xr-x 1 root root    24714 Feb  6 13:37 libdt_socket.so
-rwxr-xr-x 1 root root   485983 Feb  6 13:37 libawt_xawt.so
-rwxr-xr-x 1 root root    40624 Feb  6 13:37 libawt_headless.so
-rwxr-xr-x 1 root root   775261 Feb  6 13:37 libawt.so
-rwxr-xr-x 1 root root    19279 Feb  6 13:37 libattach.so
-rw-r--r-- 1 root root     1624 Apr 17 08:39 jvm.cfg
drwxr-xr-x 2 root root     4096 Jun 27 03:47 jli

Do you know if I should do something else?

mmornati commented 5 years ago

Hey. Do not know if the problem is still actual... I going through it today and I fixed with a multi stage build of my Quarkus final native image (is to prevent the needs of copying GraalVM files from my laptop to the project folder).

FROM quay.io/quarkus/ubi-quarkus-native-image:19.0.2 as nativebuilder
RUN mkdir -p /tmp/ssl-libs/lib \
  && cp /opt/graalvm/jre/lib/security/cacerts /tmp/ssl-libs \
  && cp /opt/graalvm/jre/lib/amd64/libsunec.so /tmp/ssl-libs/lib/ 

FROM registry.fedoraproject.org/fedora-minimal
WORKDIR /work/
COPY target/*-runner /work/application
COPY --from=nativebuilder /tmp/ssl-libs/ /work/
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0", "-Djava.library.path=/work/lib", "-Djavax.net.ssl.trustStore=/work/cacerts"]

The first stage is simply extracting the files you talked about in this thread (thanks a lot guys... you saved me days !!). The second stage is recovering these files and configure the application startup.

Just tested in my application and it is working !!

herodes1991 commented 5 years ago

Hey, I'm following the guide that you update (https://github.com/Dufgui/quarkus/blob/master/docs/src/main/asciidoc/native-and-ssl-guide.adoc#the-sunec-library-and-friends) and i'm still having a warning: WARNING: The sunec native library, required by the SunEC provider, could not be loaded. This library is usually shipped as part of the JDK and can be found under <JAVA_HOME>/jre/lib/<platform>/libsunec.so. It is loaded at run time via System.loadLibrary("sunec"), the first time services from SunEC are accessed. To use this provider's services the java.library.path system property needs to be set accordingly to point to a location that contains libsunec.so. Note that if java.library.path is not set it defaults to the current working directory. And when i try to execute the request i get that exception: java.lang.UnsatisfiedLinkError: sun.security.ec.ECKeyPairGenerator.generateECKeyPair(I[B[B)[Ljava/lang/Object; [symbol: Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair or Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair__I_3B_3B]

I'm using java 8 with gradle.

mmornati commented 5 years ago

Hey @herodes1991, what is the base image you are using for your final Docker? It can be something related to this because reading the error you are receiving, it can be something related to a missing dependency to the SunEC files and not maybe to the files themself.

herodes1991 commented 5 years ago

I'm using exactly this dockerfile, the only change with the example in the readme is the maven target folder for the gradle build folder

FROM quay.io/quarkus/ubi-quarkus-native-image:19.1.1 as nativebuilder
RUN mkdir -p /tmp/ssl-libs/lib \
  && cp /opt/graalvm/jre/lib/security/cacerts /tmp/ssl-libs \
  && cp /opt/graalvm/jre/lib/amd64/libsunec.so /tmp/ssl-libs/lib/

FROM registry.access.redhat.com/ubi8/ubi-minimal
WORKDIR /work/
COPY build/*-runner /work/application
COPY --from=nativebuilder /tmp/ssl-libs/ /work/
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0", "-Djava.library.path=/work/lib", "-Djavax.net.ssl.trustStore=/work/cacerts"]
rverma-nikiai commented 5 years ago

Even with above docker file I am getting

io.vertx.core.VertxException: javax.net.ssl.SSLException: failed to initialize the client-side SSL contextError id 85861ad3-2b57-49d9-bd9e-ad5ed1750b4a-1

when running the native binary. When running with java-jar or maven its working fine though.

Tried docker image as well as /target/vertx-quickstart-1.0-SNAPSHOT-runner -Dquarkus.http.host=0.0.0.0 -Djava.library.path=$JAVA_HOME/jre/lib/ -Djavax.net.ssl.trustStore=$JAVA_HOME/jre/lib/security/cacerts and ./target/vertx-quickstart-1.0-SNAPSHOT-runner -Dquarkus.http.host=0.0.0.0 -Djava.library.path=$GRAALVM_HOME/jre/lib/ -Djavax.net.ssl.trustStore=$GRAALVM_HOME/jre/lib/security/cacerts

None of them are working.

mmornati commented 5 years ago

@herodes1991 when you say the dockerfile is exactly what you pasted you mean that is exactly that? Because there is a missing line in your first stage... But I think without it it won't build.

FROM quay.io/quarkus/ubi-quarkus-native-image:{graalvm-version} as nativebuilder
RUN mkdir -p /tmp/ssl-libs/lib \
  && cp /opt/graalvm/jre/lib/security/cacerts /tmp/ssl-libs \
  && cp /opt/graalvm/jre/lib/amd64/libsunec.so /tmp/ssl-libs/lib/

FROM registry.access.redhat.com/ubi8/ubi-minimal
WORKDIR /work/
COPY target/*-runner /work/application
COPY --from=nativebuilder /tmp/ssl-libs/ /work/
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0", "-Djava.library.path=/work/lib", "-Djavax.net.ssl.trustStore=/work/cacerts"]
mmornati commented 5 years ago

Ok my side I used almost that dockerfile. I just replaced the {graalvm-version} with the version I was already using for the build.

herodes1991 commented 5 years ago

Yes sorry, I put incorrectly comment and the line disappear, but yes. It was exactly that what i had and i am still having the same problems Also i check inside the docker container and the files are correctly copied 😅

mmornati commented 5 years ago

I'm going to retest on my side. With the 0.19.1 version of quarkus I had no problems at all (I'm still using the container today... But I didn't rebuild it yet :)). Tesring it again and get back to you.

herodes1991 commented 5 years ago

I am testing it again after re-installing the graalvm to the 19.0.2 version. I will inform you if it works 😄

Re-edited: Still the same response

 WARNING: The sunec native library, required by the SunEC provider, could not be loaded. This library is usually shipped as part of the JDK and can be found under <JAVA_HOME>/jre/lib/<platform>/libsunec.so. It is loaded at run time via System.loadLibrary("sunec"), the first time services from SunEC are accessed. To use this provider's services the java.library.path system property needs to be set accordingly to point to a location that contains libsunec.so. Note that if java.library.path is not set it defaults to the current working directory.

and

java.lang.UnsatisfiedLinkError: sun.security.ec.ECKeyPairGenerator.generateECKeyPair(I[B[B)[Ljava/lang/Object; [symbol: Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair or Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair__I_3B_3B]
mmornati commented 5 years ago

Ah wait: how do you build the native version? On my side I'm not using the locan graalvm. The build is completely done inside container (with the native Docker I proposed on the first stage). Maybe there is a difference in the native image which is coming out. The first stage of the build is copying the Graalvm file from the Docker imagine used for the build... If you are not using that Docker for the build you maybe need to copy these 2 files from your local graalvm instead.

herodes1991 commented 5 years ago

I build it using the gradle task ./gradlew clean build buildNative --docker-build=true And i check it and it's using the quay.io/quarkus/ubi-quarkus-native-image:19.0.2

rverma-nikiai commented 5 years ago

Same here. Still getting the exception, I build using quarkus 0.19.1 with ./mvnw package -Pnative -Dnative-image.docker-build=true, which used quay.io/quarkus/ubi-quarkus-native-image:19.0.2.

Dockerfile

FROM quay.io/quarkus/ubi-quarkus-native-image:19.0.2 as nativebuilder
RUN mkdir -p /tmp/ssl-libs/lib \
  && cp /opt/graalvm/jre/lib/security/cacerts /tmp/ssl-libs \
  && cp /opt/graalvm/jre/lib/amd64/libsunec.so /tmp/ssl-libs/lib/

FROM registry.access.redhat.com/ubi8/ubi-minimal
WORKDIR /work/
COPY target/*-runner /work/application
COPY --from=nativebuilder /tmp/ssl-libs/ /work/
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0", "-Djava.library.path=/work/lib", "-Djavax.net.ssl.trustStore=/work/cacerts"]

Adding complete stacktrace as well

2019-07-30 08:57:42,639 ERROR [io.und.req.io] (executor-thread-1) Exception handling request 0c9d8387-2880-4cd1-bd4d-91172338a598-2 to /swapi/1: org.jboss.resteasy.spi.UnhandledException: io.vertx.core.VertxException: javax.net.ssl.SSLException: failed to initialize the client-side SSL context
    at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:381)
    at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:209)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:502)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:252)
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:153)
    at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:363)
    at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:156)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:238)
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:249)
    at io.quarkus.resteasy.runtime.ResteasyFilter$ResteasyResponseWrapper.sendError(ResteasyFilter.java:57)
    at io.undertow.servlet.handlers.DefaultServlet.doGet(DefaultServlet.java:175)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:686)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
    at io.quarkus.resteasy.runtime.ResteasyFilter.doFilter(ResteasyFilter.java:28)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
    at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
    at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
    at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
    at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
    at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$8$1$1.call(UndertowDeploymentRecorder.java:483)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:364)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
    at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
    at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2011)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1538)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1429)
    at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
    at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:32)
    at java.lang.Thread.run(Thread.java:748)
    at org.jboss.threads.JBossThread.run(JBossThread.java:479)
    at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:473)
    at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
Caused by: io.vertx.core.VertxException: javax.net.ssl.SSLException: failed to initialize the client-side SSL context
    at io.vertx.core.net.impl.SSLHelper.createContext(SSLHelper.java:318)
    at io.vertx.core.net.impl.SSLHelper.getContext(SSLHelper.java:493)
    at io.vertx.core.net.impl.SSLHelper.validate(SSLHelper.java:518)
    at io.vertx.core.http.impl.HttpClientImpl.<init>(HttpClientImpl.java:133)
    at io.vertx.core.impl.VertxImpl.createHttpClient(VertxImpl.java:309)
    at io.vertx.ext.web.client.WebClient.create(WebClient.java:67)
    at io.vertx.reactivex.ext.web.client.WebClient.create(WebClient.java:100)
    at org.acme.ResourceUsingWebClient.initialize(ResourceUsingWebClient.java:29)
    at org.acme.ResourceUsingWebClient_Bean.create(ResourceUsingWebClient_Bean.zig:49)
    at org.acme.ResourceUsingWebClient_Bean.create(ResourceUsingWebClient_Bean.zig:65)
    at io.quarkus.arc.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:70)
    at io.quarkus.arc.AbstractSharedContext.lambda$new$0(AbstractSharedContext.java:17)
    at io.quarkus.arc.ComputingCache$CacheFunction.lambda$apply$0(ComputingCache.java:99)
    at io.quarkus.arc.LazyValue.get(LazyValue.java:26)
    at io.quarkus.arc.ComputingCache.getValue(ComputingCache.java:41)
    at io.quarkus.arc.AbstractSharedContext.get(AbstractSharedContext.java:23)
    at org.acme.ResourceUsingWebClient_Bean.get(ResourceUsingWebClient_Bean.zig:223)
    at org.acme.ResourceUsingWebClient_Bean.get(ResourceUsingWebClient_Bean.zig:239)
    at io.quarkus.arc.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:317)
    at io.quarkus.arc.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:329)
    at io.quarkus.arc.ArcContainerImpl$1.get(ArcContainerImpl.java:194)
    at io.quarkus.arc.ArcContainerImpl$1.get(ArcContainerImpl.java:191)
    at io.quarkus.arc.runtime.ArcRecorder$2$1.create(ArcRecorder.java:70)
    at io.quarkus.resteasy.server.common.runtime.QuarkusConstructorInjector.construct(QuarkusConstructorInjector.java:56)
    at org.jboss.resteasy.plugins.server.resourcefactory.POJOResourceFactory.createResource(POJOResourceFactory.java:69)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:352)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:477)
    ... 51 more
Caused by: javax.net.ssl.SSLException: failed to initialize the client-side SSL context
    at io.netty.handler.ssl.JdkSslClientContext.newSSLContext(JdkSslClientContext.java:305)
    at io.netty.handler.ssl.JdkSslClientContext.<init>(JdkSslClientContext.java:270)
    at io.netty.handler.ssl.SslContext.newClientContextInternal(SslContext.java:168)
    at io.netty.handler.ssl.SslContextBuilder.build(SslContextBuilder.java:452)
    at io.vertx.core.net.impl.SSLHelper.createContext(SSLHelper.java:309)
    ... 77 more
Caused by: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: TLS, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$TLSContext)
    at java.security.Provider$Service.newInstance(Provider.java:1621)
    at sun.security.jca.GetInstance.getInstance(GetInstance.java:236)
    at sun.security.jca.GetInstance.getInstance(GetInstance.java:164)
    at javax.net.ssl.SSLContext.getInstance(SSLContext.java:156)
    at io.netty.handler.ssl.JdkSslClientContext.newSSLContext(JdkSslClientContext.java:287)
    ... 81 more
Caused by: java.lang.NoSuchMethodException: sun.security.ssl.SSLContextImpl$TLSContext.<init>
    at java.lang.Class.getConstructor0(DynamicHub.java:3082)
    at java.lang.Class.getConstructor(DynamicHub.java:1825)
    at java.security.Provider$Service.newInstance(Provider.java:1594)
    ... 85 more
herodes1991 commented 5 years ago

I copied exactly the example of the quarkus-quickstarts/rest-client with ssl. With maven I have no issues and works like a charm. But with gradle i'm not able to make it works, I receive the error java.lang.UnsatisfiedLinkError: sun.security.ec.ECDSASignature.verifySignedDigest([B[B[B[B)Z [symbol: Java_sun_security_ec_ECDSASignature_verifySignedDigest or Java_sun_security_ec_ECDSASignature_verifySignedDigest___3B_3B_3B_3B]

Here is the code => https://github.com/herodes1991/quarkus-quickstarts Undeer the folder rest-client I execute ./gradlew clean buildNative --docker-build=true before doing the build of the Dockerfile-gradle.native

If i forget something, please tell me

mmornati commented 5 years ago

Here mine working Dockerfile:

####
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode
#
# Before building the docker image run:
#
# mvn package -Pnative -Dnative-image.docker-build=true
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.native -t quarkus/credit-simulator .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/credit-simulator
#
###
FROM quay.io/quarkus/ubi-quarkus-native-image:19.0.2 as nativebuilder
RUN mkdir -p /tmp/ssl-libs/lib \
  && cp /opt/graalvm/jre/lib/security/cacerts /tmp/ssl-libs \
  && cp /opt/graalvm/jre/lib/amd64/libsunec.so /tmp/ssl-libs/lib/

FROM registry.access.redhat.com/ubi8/ubi-minimal

ENV APP_TIMEZONE=UTC
ENV TZ=UTC

ENV JAVA_OPTS=${JAVA_OPTS:-""}

WORKDIR /work/
COPY target/*-runner /work/application
COPY --from=nativebuilder /tmp/ssl-libs/ /work/
RUN chmod 775 /work
EXPOSE 8080
CMD ./application -Dquarkus.http.host=0.0.0.0 -Djava.library.path=/work/lib -Djavax.net.ssl.trustStore=/work/cacerts ${JAVA_OPTS}
herodes1991 commented 5 years ago

For me, the docker image it works when i compile using maven plugin, but it doesn't when i compile using gradle plugin 😅 If you prefer I can open a new issue, because I understand that it is a different error

jamesfalkner commented 5 years ago

FWIW this also failed for me even when using Maven.

From my experiments, it seems -Djava.library.path no longer has any effect - if all the *.so files are in the same directory as the app, it works. So here's the Dockerfile I am using:

FROM quay.io/quarkus/ubi-quarkus-native-image:19.1.1 as nativebuilder
RUN mkdir -p /tmp/ssl-libs \
  && cp /opt/graalvm/jre/lib/security/cacerts /tmp/ssl-libs \
  && cp /opt/graalvm/jre/lib/amd64/libsunec.so /tmp/ssl-libs

FROM registry.access.redhat.com/ubi8/ubi-minimal
WORKDIR /work/
COPY target/*-runner /work/application
COPY --from=nativebuilder /tmp/ssl-libs /work
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0", "-Djavax.net.ssl.trustStore=/work/cacerts"]
jamesfalkner commented 5 years ago

Also https://github.com/oracle/graal/pull/1604/commits/3bd21e06641e4b4e6f09b38af7176bea7202edd0 says that the java.library.path needs to be set to the actual path to the .so file, not the directory in which it is in.

But when I tried that, it failed with the same "can't load EC library" error.

rmh78 commented 5 years ago

I was not able to get it working. I tried to copy the libsunec.so next to the native executable but still get the "can't load EC library" error.

@gsmet Is this whole SSL issue a Quarkus or a Graal issue?? Is anyone trying to fix this?

stale[bot] commented 4 years ago

This issue/pullrequest has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

gsmet commented 4 years ago

Maybe let's try to properly document that one.

miron4dev commented 4 years ago

It doesn't work for the maven plugin as well. In the documentation https://quarkus.io/guides/native-and-ssl I see

You haven’t noticed anything but, while building the image, Quarkus has automatically set java.library.path to point to the GraalVM library folder (the one containing the SunEC library).

It has also set javax.net.ssl.trustStore to point to the cacerts file bundled in the GraalVM distribution. This file contains the root certificates.

So, I expect to get a native app with included SunEC library.

However, when I execute my app I receive

Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
miron4dev commented 4 years ago

Any news ?

kdnakt commented 4 years ago

I'm using quarkus-amazon-lambda extension and quarkus-amazon-dynamodb extension to access DynamoDB from AWS Lambda with custom runtime (I mean, native-image), and getting the same error:

.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
        at software.amazon.awssdk.http.apache.internal.impl.ApacheSdkHttpClient.execute(ApacheSdkHttpClient.java:72)
        at software.amazon.awssdk.http.apache.ApacheHttpClient.execute(ApacheHttpClient.java:240)
        at software.amazon.awssdk.http.apache.ApacheHttpClient.access$500(ApacheHttpClient.java:106)
        at software.amazon.awssdk.http.apache.ApacheHttpClient$1.call(ApacheHttpClient.java:221)
        at software.amazon.awssdk.core.internal.http.pipeline.stages.MakeHttpRequestStage.executeHttpRequest(MakeHttpRequestStage.java:66)
        at software.amazon.awssdk.core.internal.http.pipeline.stages.MakeHttpRequestStage.execute(MakeHttpRequestStage.java:51)
        at software.amazon.awssdk.core.internal.http.pipeline.stages.MakeHttpRequestStage.execute(MakeHttpRequestStage.java:35)
        at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
        at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
        at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
        at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
        at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptTimeoutTrackingStage.execute(ApiCallAttemptTimeoutTrackingStage.java:73)
        at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptTimeoutTrackingStage.execute(ApiCallAttemptTimeoutTrackingStage.java:42)
        at software.amazon.awssdk.core.internal.http.pipeline.stages.TimeoutExceptionHandlingStage.execute(TimeoutExceptionHandlingStage.java:77)
        at software.amazon.awssdk.core.internal.http.pipeline.stages.TimeoutExceptionHandlingStage.execute(TimeoutExceptionHandlingStage.java:39)
        at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage$RetryExecutor.doExecute(RetryableStage.java:113)
        at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage$RetryExecutor.execute(RetryableStage.java:86)
        ... 28 more
Caused by: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
        at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:91)
        at sun.security.validator.Validator.getInstance(Validator.java:181)
        at sun.security.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:318)
        at sun.security.ssl.X509TrustManagerImpl.checkTrustedInit(X509TrustManagerImpl.java:179)
        at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:193)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
        ... 60 more
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
        at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200)
        at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:120)
        at java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:104)
        at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:89)
        ... 72 more

https://github.com/kdnakt/quarkus-sandbox/tree/master/quarkus-lambda-dynamodb

ArjanKranenburg commented 4 years ago

Thanks @jamesfalkner. Your dockerfile worked for me.

bragadanilo commented 4 years ago

I've followed @jamesfalkner dockerfile, I was able to generate the image, but I kind a newbie in the AWS lambdas, but after doing the change in docker file, how do I generate the function.zip to upload to AWS?? When I was using the mvn package -Pnative it generated the zip file to me. Thanks!

marcinczeczko commented 4 years ago

I don't know if it helps but now (starting from graalvm 19.3 as far as I remember) you don't need to do anything special in regards of ssl stuff. You can check my example project in here: https://github.com/marcinczeczko/quarkus-lambda-native that has a simple lambdas talking to dynamodb in jvm and native modes. @bragadanilo you can find there how serverless framework can be used to deploy everything to aws.

spawn08 commented 3 years ago

I built a quarkus app native image and when I run the docker file, it throws me this error:

java.lang.InternalError: java.security.NoSuchAlgorithmException: class configured for SSLContext (provider: SunJSSE) cannot be found. at jdk.internal.net.http.HttpClientImpl.(HttpClientImpl.java:268) at jdk.internal.net.http.HttpClientImpl.create(HttpClientImpl.java:253) at jdk.internal.net.http.HttpClientBuilderImpl.build(HttpClientBuilderImpl.java:135) at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:96) at io.quarkus.arc.impl.AbstractSharedContext.access$000(AbstractSharedContext.java:14) at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:29) at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:26) at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26) at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69) at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:26) at io.quarkus.arc.impl.ClientProxies.getApplicationScopedDelegate(ClientProxies.java:17)

It's already been 2 years and there is no fix have/has been provided for this issue.