Upgrade to Java 17

This commit is contained in:
Richard Körber
2025-04-26 09:22:18 +02:00
parent 1069bcc2ce
commit 1ed293c5bb
36 changed files with 109 additions and 91 deletions

View File

@@ -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();
}
/**

View File

@@ -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);
}

View File

@@ -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();
}
/**

View File

@@ -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 <a href="https://tools.ietf.org/html/rfc7807">RFC 7807</a>
*/
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();
}
/**

View File

@@ -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,

View File

@@ -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);

View File

@@ -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;
/**

View File

@@ -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;
/**

View File

@@ -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;
/**

View File

@@ -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";

View File

@@ -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<URL> 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();
}
/**

View File

@@ -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;
/**

View File

@@ -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;

View File

@@ -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;
/**

View File

@@ -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;
/**

View File

@@ -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;
/**

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
/**

View File

@@ -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;

View File

@@ -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<>());

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -146,10 +146,10 @@ public class AccountTest {
@Override
public Collection<URL> getLinks(String relation) {
switch(relation) {
case "termsOfService": return singletonList(agreementUrl);
default: return emptyList();
}
return switch (relation) {
case "termsOfService" -> singletonList(agreementUrl);
default -> emptyList();
};
}
};