diff --git a/README.md b/README.md
index 22520135..c07230cf 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ This Java client helps to connect to an ACME server, and performing all necessar
* Supports [draft-ietf-acme-ari-07](https://www.ietf.org/archive/id/draft-ietf-acme-ari-07.html) for renewal information (experimental)
* Supports [draft-aaron-acme-profiles-00](https://www.ietf.org/archive/id/draft-aaron-acme-profiles-00.html) for certificate profiles (experimental)
* Easy to use Java API
-* Requires JRE 11 or higher
+* Requires JRE 17 or higher
* Supports [Buypass](https://buypass.com/), [Google Trust Services](https://pki.goog/), [Let's Encrypt](https://letsencrypt.org/), [SSL.com](https://www.ssl.com/), [ZeroSSL](https://zerossl.com/), and all other CAs that comply with the ACME protocol (RFC 8555). Note that _acme4j_ is an independent project that is not supported or endorsed by any of the CAs.
* Built with maven, packages available at [Maven Central](http://search.maven.org/#search|ga|1|g%3A%22org.shredzone.acme4j%22)
* Extensive unit and integration tests
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Account.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Account.java
index d63b467e..7b02723c 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/Account.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Account.java
@@ -13,8 +13,7 @@
*/
package org.shredzone.acme4j;
-import static java.util.stream.Collectors.toUnmodifiableList;
-
+import java.io.Serial;
import java.net.URI;
import java.security.KeyPair;
import java.util.ArrayList;
@@ -42,6 +41,7 @@ import org.slf4j.LoggerFactory;
* A representation of an account at the ACME server.
*/
public class Account extends AcmeJsonResource {
+ @Serial
private static final long serialVersionUID = 7042863483428051319L;
private static final Logger LOG = LoggerFactory.getLogger(Account.class);
@@ -76,7 +76,7 @@ public class Account extends AcmeJsonResource {
.asArray()
.stream()
.map(Value::asURI)
- .collect(toUnmodifiableList());
+ .toList();
}
/**
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Identifier.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Identifier.java
index f973f0d6..fc62bd61 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/Identifier.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Identifier.java
@@ -243,11 +243,9 @@ public class Identifier implements Serializable {
@Override
public boolean equals(Object obj) {
- if (!(obj instanceof Identifier)) {
+ if (!(obj instanceof Identifier i)) {
return false;
}
-
- var i = (Identifier) obj;
return content.equals(i.content);
}
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Order.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Order.java
index 214411c9..347ee517 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/Order.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Order.java
@@ -15,9 +15,9 @@ package org.shredzone.acme4j;
import static java.util.Collections.unmodifiableList;
import static java.util.stream.Collectors.toList;
-import static java.util.stream.Collectors.toUnmodifiableList;
import java.io.IOException;
+import java.io.Serial;
import java.net.URL;
import java.security.KeyPair;
import java.time.Duration;
@@ -43,6 +43,7 @@ import org.slf4j.LoggerFactory;
* A representation of a certificate order at the CA.
*/
public class Order extends AcmeJsonResource implements PollableResource {
+ @Serial
private static final long serialVersionUID = 5435808648658292177L;
private static final Logger LOG = LoggerFactory.getLogger(Order.class);
@@ -90,7 +91,7 @@ public class Order extends AcmeJsonResource implements PollableResource {
.asArray()
.stream()
.map(Value::asIdentifier)
- .collect(toUnmodifiableList());
+ .toList();
}
/**
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Problem.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Problem.java
index cf5f50f3..e20b252b 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/Problem.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Problem.java
@@ -13,8 +13,7 @@
*/
package org.shredzone.acme4j;
-import static java.util.stream.Collectors.toUnmodifiableList;
-
+import java.io.Serial;
import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
@@ -33,6 +32,7 @@ import org.shredzone.acme4j.toolbox.JSON.Value;
* @see RFC 7807
*/
public class Problem implements Serializable {
+ @Serial
private static final long serialVersionUID = -8418248862966754214L;
private final URL baseUrl;
@@ -122,7 +122,7 @@ public class Problem implements Serializable {
.asArray()
.stream()
.map(o -> o.asProblem(baseUrl))
- .collect(toUnmodifiableList());
+ .toList();
}
/**
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/Status.java b/acme4j-client/src/main/java/org/shredzone/acme4j/Status.java
index 1af60e07..868f77d8 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/Status.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/Status.java
@@ -33,7 +33,7 @@ public enum Status {
/**
* The server is processing the resource. The client should invoke
- * {@link AcmeJsonResource#update()} and re-check the status.
+ * {@link AcmeJsonResource#fetch()} and re-check the status.
*/
PROCESSING,
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Challenge.java b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Challenge.java
index a05640ef..2b5511ed 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Challenge.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Challenge.java
@@ -13,6 +13,7 @@
*/
package org.shredzone.acme4j.challenge;
+import java.io.Serial;
import java.time.Duration;
import java.time.Instant;
import java.util.EnumSet;
@@ -41,6 +42,7 @@ import org.slf4j.LoggerFactory;
* required data to the challenge response.
*/
public class Challenge extends AcmeJsonResource implements PollableResource {
+ @Serial
private static final long serialVersionUID = 2338794776848388099L;
private static final Logger LOG = LoggerFactory.getLogger(Challenge.class);
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Dns01Challenge.java b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Dns01Challenge.java
index 06ef297c..e76faf08 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Dns01Challenge.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Dns01Challenge.java
@@ -16,6 +16,8 @@ package org.shredzone.acme4j.challenge;
import static org.shredzone.acme4j.toolbox.AcmeUtils.base64UrlEncode;
import static org.shredzone.acme4j.toolbox.AcmeUtils.sha256hash;
+import java.io.Serial;
+
import org.shredzone.acme4j.Identifier;
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.toolbox.JSON;
@@ -25,6 +27,7 @@ import org.shredzone.acme4j.toolbox.JSON;
* validation. See the acme4j documentation for a detailed explanation.
*/
public class Dns01Challenge extends TokenChallenge {
+ @Serial
private static final long serialVersionUID = 6964687027713533075L;
/**
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Http01Challenge.java b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Http01Challenge.java
index b2d2faf6..b7ccb1ac 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Http01Challenge.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/Http01Challenge.java
@@ -13,6 +13,8 @@
*/
package org.shredzone.acme4j.challenge;
+import java.io.Serial;
+
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.toolbox.JSON;
@@ -22,6 +24,7 @@ import org.shredzone.acme4j.toolbox.JSON;
* detailed explanation.
*/
public class Http01Challenge extends TokenChallenge {
+ @Serial
private static final long serialVersionUID = 3322211185872544605L;
/**
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/TlsAlpn01Challenge.java b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/TlsAlpn01Challenge.java
index 1b88f920..c964f087 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/TlsAlpn01Challenge.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/TlsAlpn01Challenge.java
@@ -16,6 +16,7 @@ package org.shredzone.acme4j.challenge;
import static org.shredzone.acme4j.toolbox.AcmeUtils.sha256hash;
import java.io.IOException;
+import java.io.Serial;
import java.security.KeyPair;
import java.security.cert.X509Certificate;
@@ -32,6 +33,7 @@ import org.shredzone.acme4j.util.CertificateUtils;
* @since 2.1
*/
public class TlsAlpn01Challenge extends TokenChallenge {
+ @Serial
private static final long serialVersionUID = -5590351078176091228L;
/**
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/TokenChallenge.java b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/TokenChallenge.java
index 6e66f54b..61407f5f 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/TokenChallenge.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/challenge/TokenChallenge.java
@@ -15,6 +15,8 @@ package org.shredzone.acme4j.challenge;
import static org.shredzone.acme4j.toolbox.AcmeUtils.base64UrlEncode;
+import java.io.Serial;
+
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.exception.AcmeProtocolException;
import org.shredzone.acme4j.toolbox.AcmeUtils;
@@ -26,6 +28,7 @@ import org.shredzone.acme4j.toolbox.JoseUtils;
* and {@code keyAuthorization}.
*/
public class TokenChallenge extends Challenge {
+ @Serial
private static final long serialVersionUID = 1634133407432681800L;
protected static final String KEY_TOKEN = "token";
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/connector/DefaultConnection.java b/acme4j-client/src/main/java/org/shredzone/acme4j/connector/DefaultConnection.java
index aad0869b..87c410f4 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/connector/DefaultConnection.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/connector/DefaultConnection.java
@@ -15,7 +15,6 @@ package org.shredzone.acme4j.connector;
import static java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME;
import static java.util.function.Predicate.not;
-import static java.util.stream.Collectors.toUnmodifiableList;
import java.io.IOException;
import java.io.InputStream;
@@ -137,7 +136,7 @@ public class DefaultConnection implements Connection {
var retryAfterInstant = getRetryAfter();
if (retryAfterInstant.isPresent()) {
throw new AcmeRetryAfterException(message, retryAfterInstant.get());
- };
+ }
throw new AcmeException(message);
}
@@ -228,7 +227,7 @@ public class DefaultConnection implements Connection {
var cf = CertificateFactory.getInstance("X.509");
return cf.generateCertificates(in).stream()
.map(X509Certificate.class::cast)
- .collect(toUnmodifiableList());
+ .toList();
} catch (IOException ex) {
throw new AcmeNetworkException(ex);
} catch (CertificateException ex) {
@@ -311,7 +310,7 @@ public class DefaultConnection implements Connection {
public Collection getLinks(String relation) {
return collectLinks(relation).stream()
.map(this::resolveRelative)
- .collect(toUnmodifiableList());
+ .toList();
}
@Override
@@ -620,7 +619,7 @@ public class DefaultConnection implements Connection {
.filter(Matcher::matches)
.map(m -> m.group(1))
.peek(location -> LOG.debug("Link: {} -> {}", relation, location))
- .collect(toUnmodifiableList());
+ .toList();
}
/**
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeException.java b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeException.java
index a3334b06..bcc7dc55 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeException.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeException.java
@@ -13,10 +13,13 @@
*/
package org.shredzone.acme4j.exception;
+import java.io.Serial;
+
/**
* The root class of all checked acme4j exceptions.
*/
public class AcmeException extends Exception {
+ @Serial
private static final long serialVersionUID = -2935088954705632025L;
/**
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeLazyLoadingException.java b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeLazyLoadingException.java
index 71e7cb87..b7980654 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeLazyLoadingException.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeLazyLoadingException.java
@@ -15,6 +15,7 @@ package org.shredzone.acme4j.exception;
import static java.util.Objects.requireNonNull;
+import java.io.Serial;
import java.net.URL;
import org.shredzone.acme4j.AcmeResource;
@@ -26,6 +27,7 @@ import org.shredzone.acme4j.AcmeResource;
* thrown by getter methods, so the API is not polluted with checked exceptions.
*/
public class AcmeLazyLoadingException extends RuntimeException {
+ @Serial
private static final long serialVersionUID = 1000353433913721901L;
private final Class extends AcmeResource> type;
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeNetworkException.java b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeNetworkException.java
index bad5ffdc..1fe75856 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeNetworkException.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeNetworkException.java
@@ -14,12 +14,14 @@
package org.shredzone.acme4j.exception;
import java.io.IOException;
+import java.io.Serial;
/**
* A general network error has occured while communicating with the server (e.g. network
* timeout).
*/
public class AcmeNetworkException extends AcmeException {
+ @Serial
private static final long serialVersionUID = 2054398693543329179L;
/**
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeNotSupportedException.java b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeNotSupportedException.java
index f8356cd4..043a8c90 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeNotSupportedException.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeNotSupportedException.java
@@ -13,12 +13,15 @@
*/
package org.shredzone.acme4j.exception;
+import java.io.Serial;
+
/**
* A runtime exception that is thrown if the ACME server does not support a certain
* feature. It might be either because that feature is optional, or because the server
* is not fully RFC compliant.
*/
public class AcmeNotSupportedException extends AcmeProtocolException {
+ @Serial
private static final long serialVersionUID = 3434074002226584731L;
/**
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeProtocolException.java b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeProtocolException.java
index c507767d..7100ce7f 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeProtocolException.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeProtocolException.java
@@ -13,12 +13,15 @@
*/
package org.shredzone.acme4j.exception;
+import java.io.Serial;
+
/**
* A runtime exception that is thrown when the response of the server is violating the
* RFC, and could not be handled or parsed for that reason. It is an indicator that the CA
* does not fully comply with the RFC, and is usually not expected to be thrown.
*/
public class AcmeProtocolException extends RuntimeException {
+ @Serial
private static final long serialVersionUID = 2031203835755725193L;
/**
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeRateLimitedException.java b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeRateLimitedException.java
index b1c279de..c9f59c11 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeRateLimitedException.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeRateLimitedException.java
@@ -13,6 +13,7 @@
*/
package org.shredzone.acme4j.exception;
+import java.io.Serial;
import java.net.URL;
import java.time.Instant;
import java.util.Collection;
@@ -28,6 +29,7 @@ import org.shredzone.acme4j.Problem;
* further explains the rate limit that was exceeded.
*/
public class AcmeRateLimitedException extends AcmeServerException {
+ @Serial
private static final long serialVersionUID = 4150484059796413069L;
private final @Nullable Instant retryAfter;
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeServerException.java b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeServerException.java
index b5589d66..344df941 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeServerException.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeServerException.java
@@ -13,6 +13,7 @@
*/
package org.shredzone.acme4j.exception;
+import java.io.Serial;
import java.net.URI;
import java.util.Objects;
@@ -26,6 +27,7 @@ import org.shredzone.acme4j.Problem;
* individually.
*/
public class AcmeServerException extends AcmeException {
+ @Serial
private static final long serialVersionUID = 5971622508467042792L;
private final Problem problem;
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeUnauthorizedException.java b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeUnauthorizedException.java
index 9221d538..574670b0 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeUnauthorizedException.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeUnauthorizedException.java
@@ -13,6 +13,8 @@
*/
package org.shredzone.acme4j.exception;
+import java.io.Serial;
+
import org.shredzone.acme4j.Problem;
/**
@@ -20,6 +22,7 @@ import org.shredzone.acme4j.Problem;
* will give further details (e.g. "client IP is blocked").
*/
public class AcmeUnauthorizedException extends AcmeServerException {
+ @Serial
private static final long serialVersionUID = 9064697508262919366L;
/**
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeUserActionRequiredException.java b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeUserActionRequiredException.java
index 457e6efd..ed2403b1 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeUserActionRequiredException.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/exception/AcmeUserActionRequiredException.java
@@ -13,6 +13,7 @@
*/
package org.shredzone.acme4j.exception;
+import java.io.Serial;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
@@ -28,6 +29,7 @@ import org.shredzone.acme4j.Problem;
* requires an agreement to the new terms before proceeding.
*/
public class AcmeUserActionRequiredException extends AcmeServerException {
+ @Serial
private static final long serialVersionUID = 7719055447283858352L;
private final @Nullable URI tosUri;
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSON.java b/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSON.java
index f52abfbc..d35bf6bf 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSON.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JSON.java
@@ -21,6 +21,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.Serial;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URI;
@@ -54,6 +55,7 @@ import org.shredzone.acme4j.exception.AcmeProtocolException;
* A model containing a JSON result. The content is immutable.
*/
public final class JSON implements Serializable {
+ @Serial
private static final long serialVersionUID = 418332625174149030L;
private static final JSON EMPTY_JSON = new JSON(new HashMap<>());
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JoseUtils.java b/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JoseUtils.java
index 23056774..39952cfb 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JoseUtils.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/toolbox/JoseUtils.java
@@ -203,23 +203,13 @@ public final class JoseUtils {
* there is no corresponding algorithm identifier for the key
*/
public static String keyAlgorithm(JsonWebKey jwk) {
- if (jwk instanceof EllipticCurveJsonWebKey) {
- var ecjwk = (EllipticCurveJsonWebKey) jwk;
-
- switch (ecjwk.getCurveName()) {
- case "P-256":
- return AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256;
-
- case "P-384":
- return AlgorithmIdentifiers.ECDSA_USING_P384_CURVE_AND_SHA384;
-
- case "P-521":
- return AlgorithmIdentifiers.ECDSA_USING_P521_CURVE_AND_SHA512;
-
- default:
- throw new IllegalArgumentException("Unknown EC name "
- + ecjwk.getCurveName());
- }
+ if (jwk instanceof EllipticCurveJsonWebKey ecjwk) {
+ return switch (ecjwk.getCurveName()) {
+ case "P-256" -> AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256;
+ case "P-384" -> AlgorithmIdentifiers.ECDSA_USING_P384_CURVE_AND_SHA384;
+ case "P-521" -> AlgorithmIdentifiers.ECDSA_USING_P521_CURVE_AND_SHA512;
+ default -> throw new IllegalArgumentException("Unknown EC name " + ecjwk.getCurveName());
+ };
} else if (jwk instanceof RsaJsonWebKey) {
return AlgorithmIdentifiers.RSA_USING_SHA256;
diff --git a/acme4j-client/src/main/java/org/shredzone/acme4j/util/CertificateUtils.java b/acme4j-client/src/main/java/org/shredzone/acme4j/util/CertificateUtils.java
index c269c01b..5d642c56 100644
--- a/acme4j-client/src/main/java/org/shredzone/acme4j/util/CertificateUtils.java
+++ b/acme4j-client/src/main/java/org/shredzone/acme4j/util/CertificateUtils.java
@@ -126,18 +126,11 @@ public final class CertificateUtils {
var gns = new GeneralName[1];
- switch (id.getType()) {
- case Identifier.TYPE_DNS:
- gns[0] = new GeneralName(GeneralName.dNSName, id.getDomain());
- break;
-
- case Identifier.TYPE_IP:
- gns[0] = new GeneralName(GeneralName.iPAddress, id.getIP().getHostAddress());
- break;
-
- default:
- throw new IllegalArgumentException("Unsupported Identifier type " + id.getType());
- }
+ gns[0] = switch (id.getType()) {
+ case Identifier.TYPE_DNS -> new GeneralName(GeneralName.dNSName, id.getDomain());
+ case Identifier.TYPE_IP -> new GeneralName(GeneralName.iPAddress, id.getIP().getHostAddress());
+ default -> throw new IllegalArgumentException("Unsupported Identifier type " + id.getType());
+ };
certBuilder.addExtension(Extension.subjectAlternativeName, false, new GeneralNames(gns));
certBuilder.addExtension(ACME_VALIDATION, true, new DEROctetString(acmeValidation));
@@ -268,8 +261,8 @@ public final class CertificateUtils {
var attr = csr.getAttributes(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest);
if (attr.length > 0) {
var extensions = attr[0].getAttrValues().toArray();
- if (extensions.length > 0 && extensions[0] instanceof Extensions) {
- var san = GeneralNames.fromExtensions((Extensions) extensions[0], Extension.subjectAlternativeName);
+ if (extensions.length > 0 && extensions[0] instanceof Extensions extension0) {
+ var san = GeneralNames.fromExtensions(extension0, Extension.subjectAlternativeName);
var critical = csr.getSubject().getRDNs().length == 0;
certBuilder.addExtension(Extension.subjectAlternativeName, critical, san);
}
diff --git a/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java b/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java
index 9858967e..45dacdc4 100644
--- a/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java
+++ b/acme4j-client/src/test/java/org/shredzone/acme4j/AccountTest.java
@@ -146,10 +146,10 @@ public class AccountTest {
@Override
public Collection getLinks(String relation) {
- switch(relation) {
- case "termsOfService": return singletonList(agreementUrl);
- default: return emptyList();
- }
+ return switch (relation) {
+ case "termsOfService" -> singletonList(agreementUrl);
+ default -> emptyList();
+ };
}
};
diff --git a/acme4j-example/src/main/java/org/shredzone/acme4j/example/ClientTest.java b/acme4j-example/src/main/java/org/shredzone/acme4j/example/ClientTest.java
index 1168d1ee..c65d1a0d 100644
--- a/acme4j-example/src/main/java/org/shredzone/acme4j/example/ClientTest.java
+++ b/acme4j-example/src/main/java/org/shredzone/acme4j/example/ClientTest.java
@@ -81,10 +81,10 @@ public class ClientTest {
private static final String EAB_HMAC = null;
// A supplier for a new account KeyPair. The default creates a new EC key pair.
- private static Supplier ACCOUNT_KEY_SUPPLIER = () -> KeyPairUtils.createKeyPair();
+ private static final Supplier ACCOUNT_KEY_SUPPLIER = KeyPairUtils::createKeyPair;
// A supplier for a new domain KeyPair. The default creates a RSA key pair.
- private static Supplier DOMAIN_KEY_SUPPLIER = () -> KeyPairUtils.createKeyPair(4096);
+ private static final Supplier DOMAIN_KEY_SUPPLIER = () -> KeyPairUtils.createKeyPair(4096);
// File name of the User Key Pair
private static final File USER_KEY_FILE = new File("user.key");
@@ -267,16 +267,10 @@ public class ClientTest {
}
// Find the desired challenge and prepare it.
- Challenge challenge = null;
- switch (CHALLENGE_TYPE) {
- case HTTP:
- challenge = httpChallenge(auth);
- break;
-
- case DNS:
- challenge = dnsChallenge(auth);
- break;
- }
+ Challenge challenge = switch (CHALLENGE_TYPE) {
+ case HTTP -> httpChallenge(auth);
+ case DNS -> dnsChallenge(auth);
+ };
if (challenge == null) {
throw new AcmeException("No challenge found");
diff --git a/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/EmailIdentifier.java b/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/EmailIdentifier.java
index 170791a0..bba42747 100644
--- a/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/EmailIdentifier.java
+++ b/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/EmailIdentifier.java
@@ -13,6 +13,8 @@
*/
package org.shredzone.acme4j.smime;
+import java.io.Serial;
+
import jakarta.mail.internet.AddressException;
import jakarta.mail.internet.InternetAddress;
import org.shredzone.acme4j.Identifier;
@@ -24,6 +26,7 @@ import org.shredzone.acme4j.exception.AcmeProtocolException;
* @since 2.12
*/
public class EmailIdentifier extends Identifier {
+ @Serial
private static final long serialVersionUID = -1473014167038845395L;
/**
diff --git a/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/challenge/EmailReply00Challenge.java b/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/challenge/EmailReply00Challenge.java
index 3d58c644..b12e3d28 100644
--- a/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/challenge/EmailReply00Challenge.java
+++ b/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/challenge/EmailReply00Challenge.java
@@ -16,6 +16,8 @@ package org.shredzone.acme4j.smime.challenge;
import static org.shredzone.acme4j.toolbox.AcmeUtils.base64UrlEncode;
import static org.shredzone.acme4j.toolbox.AcmeUtils.sha256hash;
+import java.io.Serial;
+
import jakarta.mail.internet.AddressException;
import jakarta.mail.internet.InternetAddress;
import org.shredzone.acme4j.Login;
@@ -30,6 +32,7 @@ import org.shredzone.acme4j.toolbox.JSON;
* @since 2.12
*/
public class EmailReply00Challenge extends TokenChallenge {
+ @Serial
private static final long serialVersionUID = 2502329538019544794L;
/**
diff --git a/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/exception/AcmeInvalidMessageException.java b/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/exception/AcmeInvalidMessageException.java
index a2aeddaf..bdcf28d4 100644
--- a/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/exception/AcmeInvalidMessageException.java
+++ b/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/exception/AcmeInvalidMessageException.java
@@ -15,6 +15,7 @@ package org.shredzone.acme4j.smime.exception;
import static java.util.Collections.unmodifiableList;
+import java.io.Serial;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -40,6 +41,7 @@ import org.shredzone.acme4j.exception.AcmeException;
* @since 2.15
*/
public class AcmeInvalidMessageException extends AcmeException {
+ @Serial
private static final long serialVersionUID = 5607857024718309330L;
private final List errors;
diff --git a/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/wrapper/SignedMail.java b/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/wrapper/SignedMail.java
index d26beda6..17001dee 100644
--- a/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/wrapper/SignedMail.java
+++ b/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/wrapper/SignedMail.java
@@ -149,24 +149,19 @@ public class SignedMail implements Mail {
var relaxed = false;
for (var element : (ASN1Set) attr.getAttributeValues()[0]) {
- if (element instanceof ASN1Enumerated) {
- var algorithm = ((ASN1Enumerated) element).intValueExact();
- switch (algorithm) {
- case 0:
- relaxed = false;
- break;
- case 1:
- relaxed = true;
- break;
- default:
- throw new AcmeInvalidMessageException("Unknown algorithm: " + algorithm);
- }
+ if (element instanceof ASN1Enumerated asn1element) {
+ var algorithm = asn1element.intValueExact();
+ relaxed = switch (algorithm) {
+ case 0 -> false;
+ case 1 -> true;
+ default -> throw new AcmeInvalidMessageException("Unknown algorithm: " + algorithm);
+ };
}
}
for (var element : (ASN1Set) attr.getAttributeValues()[0]) {
- if (element instanceof ASN1Sequence) {
- for (var sequenceElement : (ASN1Sequence) element) {
+ if (element instanceof ASN1Sequence asn1sequence) {
+ for (var sequenceElement : asn1sequence) {
var headerField = (ASN1Sequence) sequenceElement;
var fieldName = ((ASN1String) headerField.getObjectAt(0)).getString();
var fieldValue = ((ASN1String) headerField.getObjectAt(1)).getString();
diff --git a/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/wrapper/SignedMailBuilder.java b/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/wrapper/SignedMailBuilder.java
index 6c379139..c1172ef0 100644
--- a/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/wrapper/SignedMailBuilder.java
+++ b/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/wrapper/SignedMailBuilder.java
@@ -163,12 +163,11 @@ public class SignedMailBuilder {
requireNonNull(message, "message");
try {
// Check all parameters
- if (!(message instanceof MimeMessage)) {
+ if (!(message instanceof MimeMessage mimeMessage)) {
throw new IllegalArgumentException("Message must be a MimeMessage");
}
- MimeMessage mimeMessage = (MimeMessage) message;
- if (!(mimeMessage.getContent() instanceof MimeMultipart)) {
+ if (!(mimeMessage.getContent() instanceof MimeMultipart contentMultipart)) {
throw new AcmeProtocolException("S/MIME signed message must contain MimeMultipart");
}
@@ -177,7 +176,7 @@ public class SignedMailBuilder {
}
// Get the signed message
- SMIMESigned signed = new SMIMESigned((MimeMultipart) mimeMessage.getContent());
+ SMIMESigned signed = new SMIMESigned(contentMultipart);
// Validate the signature
SignerInformation si = validateSignature(mimeMessage, pkixParameters);
diff --git a/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/wrapper/SimpleMail.java b/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/wrapper/SimpleMail.java
index 7461c885..3142d846 100644
--- a/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/wrapper/SimpleMail.java
+++ b/acme4j-smime/src/main/java/org/shredzone/acme4j/smime/wrapper/SimpleMail.java
@@ -55,10 +55,10 @@ public class SimpleMail implements Mail {
if (from.length != 1) {
throw new AcmeInvalidMessageException("Message must have exactly one sender, but has " + from.length);
}
- if (!(from[0] instanceof InternetAddress)) {
+ if (!(from[0] instanceof InternetAddress from0)) {
throw new AcmeInvalidMessageException("Invalid sender message type: " + from[0].getClass().getName());
}
- return (InternetAddress) from[0];
+ return from0;
} catch (MessagingException ex) {
throw new AcmeInvalidMessageException("Could not read 'From' header", ex);
}
@@ -74,10 +74,10 @@ public class SimpleMail implements Mail {
if (to.length != 1) {
throw new AcmeInvalidMessageException("Message must have exactly one recipient, but has " + to.length);
}
- if (!(to[0] instanceof InternetAddress)) {
+ if (!(to[0] instanceof InternetAddress to0)) {
throw new AcmeInvalidMessageException("Invalid recipient message type: " + to[0].getClass().getName());
}
- return (InternetAddress) to[0];
+ return to0;
} catch (MessagingException ex) {
throw new AcmeInvalidMessageException("Could not read 'To' header", ex);
}
diff --git a/acme4j-smime/src/test/java/org/shredzone/acme4j/smime/EmailIdentifierTest.java b/acme4j-smime/src/test/java/org/shredzone/acme4j/smime/EmailIdentifierTest.java
index 3e1514d7..4a282ce6 100644
--- a/acme4j-smime/src/test/java/org/shredzone/acme4j/smime/EmailIdentifierTest.java
+++ b/acme4j-smime/src/test/java/org/shredzone/acme4j/smime/EmailIdentifierTest.java
@@ -37,8 +37,8 @@ public class EmailIdentifierTest {
@ParameterizedTest
@MethodSource("provideTestEmails")
public void testEmail(Object input, String expected) {
- var id = input instanceof InternetAddress
- ? EmailIdentifier.email((InternetAddress) input)
+ var id = input instanceof InternetAddress internetAddress
+ ? EmailIdentifier.email(internetAddress)
: EmailIdentifier.email(input.toString());
assertThat(id.getType()).isEqualTo(EmailIdentifier.TYPE_EMAIL);
diff --git a/pom.xml b/pom.xml
index 237f1f87..5877748a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -75,7 +75,7 @@
maven-compiler-plugin
3.8.1
- 11
+ 17
diff --git a/src/doc/docs/index.md b/src/doc/docs/index.md
index 78e2fa83..4ee0fca9 100644
--- a/src/doc/docs/index.md
+++ b/src/doc/docs/index.md
@@ -22,7 +22,7 @@ Latest version:  for renewal information (experimental)
* Supports [draft-aaron-acme-profiles-00](https://www.ietf.org/archive/id/draft-aaron-acme-profiles-00.html) for certificate profiles (experimental)
* Easy to use Java API
-* Requires JRE 11 or higher
+* Requires JRE 17 or higher
* Supports [Buypass](https://buypass.com/), [Google Trust Services](https://pki.goog/), [Let's Encrypt](https://letsencrypt.org/), [SSL.com](https://www.ssl.com/), [ZeroSSL](https://zerossl.com/), and all other CAs that comply with the ACME protocol (RFC 8555). Note that _acme4j_ is an independent project that is not supported or endorsed by any of the CAs.
* Built with maven, packages available at [Maven Central](http://search.maven.org/#search|ga|1|g%3A%22org.shredzone.acme4j%22)
* Extensive unit and integration tests
diff --git a/src/doc/docs/migration.md b/src/doc/docs/migration.md
index 7e031cac..2bbda282 100644
--- a/src/doc/docs/migration.md
+++ b/src/doc/docs/migration.md
@@ -2,6 +2,10 @@
This document will help you migrate your code to the latest _acme4j_ version.
+## Migration to Version 3.6.0
+
+- _acme4j_ requires JRE 17 or higher now.
+
## Migration to Version 3.5.0
- If you use STAR auto-renewal certificates, you can now use `Order.getCertificate()` instead of `Order.getAutoRenewalCertificate()` to retrieve the STAR certificate. `Order.getAutoRenewalCertificate()` is marked as deprecated, but still functional. The new method `Order.isAutoRenewalCertificate()` can be used to check if the order resulted in a standard or auto-renewing certificate.