Open mertmr opened 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.
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"]
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.
@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
@soberich Having both of them set doesn't hurt :).
@mertmr did you get it to work?
You need to copy the
cacerts
file and the SunEC library inside your container (see theCOPY
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 alib/
directory).Then you need to add a
, "-Djava.library.path=./lib", -Djavax.net.ssl.trustStore=./cacerts"
to yourCMD
.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.
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.
@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.
Surprisingly it now works with adding only libsunec.so. Maybe because of upgrade to 0.16.1?
We haven’t changed anything regarding the SSL support for a while.
@anadollu can you check if it’s OK for you too?
@gsmet i am using master branch (999-SNAPSHOT) and not working with only libsunec.so file.
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?
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 !!
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.
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.
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"]
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.
@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"]
Ok my side I used almost that dockerfile. I just replaced the {graalvm-version}
with the version I was already using for the build.
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 😅
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.
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]
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.
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
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
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
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}
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
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"]
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.
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?
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.
Maybe let's try to properly document that one.
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
Any news ?
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
Thanks @jamesfalkner. Your dockerfile worked for me.
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!
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.
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.
It's already been 2 years and there is no fix have/has been provided for this issue.
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:
Any additional steps did I miss?