JVM build used for this article eclipse-temurin:21-jdk
:
openjdk 21.0.2 2024-01-16 LTS
OpenJDK Runtime Environment Temurin-21.0.2+13 (build 21.0.2+13-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.2+13 (build 21.0.2+13-LTS, mixed mode, sharing)
We must differentiate JVM Security properties and System properties.
- Security properties:
- can not be affected directly by the command line
- accessed with class
java.security.Security
- can be modified through the file
-Djava.security.properties=/java-additional.security
- System properties
- can be affected directly by the command line
- accessed with class
java.lang.System
Important to know:
Default value of the property is 30 (seconds) and can be found in
sun.net.InetAddressCachePolicy#DEFAULT_POSITIVE
This class reads the property once during the class initialization in the static method - this is important for further conclusions
How to debug: open
java.net.InetAddress
line ~1141cachePolicy = InetAddressCachePolicy.get();
and call the codeInetAddressCachePolicy.get()
through the debug execution
Initial options to set the value:
- Security property
networkaddress.cache.ttl
(through the file) - System property
sun.net.inetaddr.ttl
(through JVM command line)
Technical in JVM it's possible to set a value in runtime (e.g. System.setProperty
or Security.setProperty
but this is misleading here's why:
You don't know when a property will be accessed by any code. You must either determine that you set it before other code accesses it or there is a risk that it will be not applied.
Therefore, to mediate the risk and the checks we should set the value as JVM startup parameters (not runtime).
Let's consider 3 typical build setups:
- fat jar
- Spring Boot docker build
- Goole jib
Fat jar
There are plenty of options on how to set a JVM property, one example
Security properties with Gradle example
# gradle.properties
org.gradle.org.gradle.jvmargs="-Djava.security.properties=/your/path/java-additional.security"
Security properties with Googe Jib plugin
# build.gradle.kts
jib {
extraDirectories {
paths {
path {
setFrom("java-additional.security")
into = "/etc/java-additional.security"
}
}
}
container {
jvmFlags = listOf("-Djava.security.properties=/etc/java-additional.security/java.security")
}
from {
image = "eclipse-temurin:21-jre"
}
}
You can reproduce the same code with other build tools and with the Dockerfile too.
Event this is not enough
Spring uses Apache HTTP client underneath and by default connection TTL there is infinite. You can change it to (see):
@Bean
fun poolingHttpClientConnectionManager(): PoolingHttpClientConnectionManager =
PoolingHttpClientConnectionManagerBuilder
.create()
.apply {
setDefaultConnectionConfig(ConnectionConfig
.custom()
.setTimeToLive(TimeValue.ofMinutes(30))
.build()
)
}
.build()
// which you set to
HttpClients.custom().setConnectionManager(poolingHttpClientConnectionManager)
Top comments (0)