mirror of
https://github.com/jlengrand/quarkus.git
synced 2026-03-10 08:41:22 +00:00
Stop dealing with the SunEC library during the native image generation
This commit is contained in:
@@ -1,13 +1,11 @@
|
||||
package io.quarkus.deployment.steps;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.graalvm.nativeimage.ImageInfo;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import io.quarkus.deployment.annotations.BuildProducer;
|
||||
@@ -36,8 +34,6 @@ class NativeImageConfigBuildStep {
|
||||
|
||||
private static final Logger log = Logger.getLogger(NativeImageConfigBuildStep.class);
|
||||
|
||||
private static final String LIB_SUN_EC = "libsunec.so";
|
||||
|
||||
@BuildStep
|
||||
@Record(ExecutionTime.STATIC_INIT)
|
||||
void build(SslContextConfigurationRecorder sslContextConfigurationRecorder,
|
||||
@@ -74,50 +70,18 @@ class NativeImageConfigBuildStep {
|
||||
}
|
||||
}
|
||||
|
||||
Boolean sslNativeEnabled = isSslNativeEnabled(sslNativeConfig, extensionSslNativeSupport);
|
||||
|
||||
// For now, we enable SSL native if it hasn't been explicitly disabled
|
||||
// it's probably overly conservative but it's a first step in the right direction
|
||||
sslContextConfigurationRecorder.setSslNativeEnabled(!sslNativeConfig.isExplicitlyDisabled());
|
||||
|
||||
Boolean sslNativeEnabled = isSslNativeEnabled(sslNativeConfig, extensionSslNativeSupport);
|
||||
if (sslNativeEnabled) {
|
||||
// This is an ugly hack but for now it's the only way to make the SunEC library
|
||||
// available to the native image.
|
||||
// This makes the native image dependent on the local path used to build it.
|
||||
// If you want to push your native image to a different environment, you will
|
||||
// need to put libsunec.so aside the native image or override java.library.path.
|
||||
|
||||
String graalVmHome = System.getenv("GRAALVM_HOME");
|
||||
|
||||
if (graalVmHome != null) {
|
||||
Path graalVmLibDirectory = Paths.get(graalVmHome, "jre", "lib");
|
||||
Path linuxLibDirectory = graalVmLibDirectory.resolve("amd64");
|
||||
Path linuxPath = linuxLibDirectory.resolve(LIB_SUN_EC);
|
||||
|
||||
// We add . as it might be useful in a containerized world
|
||||
javaLibraryPathAdditionalPath.produce(new JavaLibraryPathAdditionalPathBuildItem("."));
|
||||
if (Files.exists(linuxPath)) {
|
||||
// On Linux, the SunEC library is in jre/lib/amd64/
|
||||
// This is useful for testing or if you have a similar environment in production
|
||||
javaLibraryPathAdditionalPath
|
||||
.produce(new JavaLibraryPathAdditionalPathBuildItem(linuxLibDirectory.toString()));
|
||||
} else {
|
||||
// On MacOS, the SunEC library is directly in jre/lib/
|
||||
// This is useful for testing or if you have a similar environment in production
|
||||
javaLibraryPathAdditionalPath
|
||||
.produce(new JavaLibraryPathAdditionalPathBuildItem(graalVmLibDirectory.toString()));
|
||||
}
|
||||
|
||||
Path graalVmCacertsPath = Paths.get(graalVmHome, "jre", "lib", "security", "cacerts");
|
||||
// This is useful for testing but the user will have to override it.
|
||||
sslTrustStoreSystemProperty.produce(
|
||||
new SslTrustStoreSystemPropertyBuildItem(
|
||||
graalVmLibDirectory.resolve(Paths.get("security", "cacerts")).toString()));
|
||||
} else {
|
||||
// only warn if we're building a native image
|
||||
if (ImageInfo.inImageBuildtimeCode()) {
|
||||
log.warn(
|
||||
"SSL is enabled but the GRAALVM_HOME environment variable is not set. The java.library.path property has not been set and will need to be set manually.");
|
||||
}
|
||||
sslTrustStoreSystemProperty.produce(new SslTrustStoreSystemPropertyBuildItem(graalVmCacertsPath.toString()));
|
||||
}
|
||||
}
|
||||
nativeImage.produce(new NativeImageSystemPropertyBuildItem("quarkus.ssl.native", sslNativeEnabled.toString()));
|
||||
|
||||
@@ -158,15 +158,13 @@ And let's build the native executable again:
|
||||
./mvnw clean install -Pnative
|
||||
```
|
||||
|
||||
== The SunEC library and friends
|
||||
== The TrustStore path
|
||||
|
||||
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.
|
||||
Quarkus has automatically set `javax.net.ssl.trustStore` to point to the `cacerts` file bundled in the GraalVM distribution.
|
||||
This file contains the root certificates.
|
||||
|
||||
This is useful when running tests but, obviously, it is not portable as these paths are hardcoded.
|
||||
This is useful when running tests but, obviously, it is not portable as this path is hardcoded.
|
||||
|
||||
You can check that pretty easily:
|
||||
|
||||
@@ -174,13 +172,12 @@ You can check that pretty easily:
|
||||
* run the native executable `./target/rest-client-1.0-SNAPSHOT-runner`
|
||||
* in a browser, go to `http://localhost:8080/country/name/greece`
|
||||
* you will have an Internal Server Error
|
||||
* in your terminal, you should have a warning `WARNING: The sunec native library, required by the SunEC provider, could not be loaded.`
|
||||
and an exception too: `java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty`
|
||||
* in your terminal, you should have an exception: `java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty`
|
||||
* hit `Ctrl+C` to stop the application
|
||||
|
||||
To make it work, you need to manually set `java.library.path` and `javax.net.ssl.trustStore` to point to the new GraalVM home:
|
||||
To make it work, you need to manually set `javax.net.ssl.trustStore` to point to the new GraalVM home:
|
||||
```
|
||||
./target/rest-client-1.0-SNAPSHOT-runner -Djava.library.path=<new-graalvm-home>/jre/lib/amd64 -Djavax.net.ssl.trustStore=<new-graalvm-home>/jre/lib/security/cacerts
|
||||
./target/rest-client-1.0-SNAPSHOT-runner -Djavax.net.ssl.trustStore=<new-graalvm-home>/jre/lib/security/cacerts
|
||||
```
|
||||
|
||||
Now, the application should work as expected:
|
||||
|
||||
@@ -3,11 +3,6 @@ package io.quarkus.it.vertx;
|
||||
import static io.restassured.RestAssured.given;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import io.quarkus.test.junit.NativeImageTest;
|
||||
@@ -17,20 +12,6 @@ import io.restassured.specification.RequestSpecification;
|
||||
@NativeImageTest
|
||||
public class VertxProducerResourceIT extends VertxProducerResourceTest {
|
||||
|
||||
private static Provider sunECProvider;
|
||||
|
||||
@BeforeAll
|
||||
public static void setupSecProvider() {
|
||||
//Remove SunEC provider for the test as it's not being provided for tests.
|
||||
sunECProvider = Security.getProvider("SunEC");
|
||||
Security.removeProvider("SunEC");
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void restoreSecProvider() {
|
||||
Security.addProvider(sunECProvider);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testRouteRegistrationMTLS() {
|
||||
|
||||
Reference in New Issue
Block a user