Replace JSR305 null-safe annotations by SpotBugs annotations

Reason is that JSR305 annotations cannot be used in a modular environment due to split package issues.
pull/91/head
Richard Körber 2020-06-02 12:42:49 +02:00
parent c5e85f0101
commit b32f03b23a
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
63 changed files with 350 additions and 318 deletions

View File

@ -26,9 +26,7 @@ import java.util.List;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.ParametersAreNonnullByDefault;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.connector.Connection;
import org.shredzone.acme4j.connector.Resource;
import org.shredzone.acme4j.connector.ResourceIterator;
@ -46,7 +44,6 @@ import org.slf4j.LoggerFactory;
/**
* Represents an account at the ACME server.
*/
@ParametersAreNonnullByDefault
public class Account extends AcmeJsonResource {
private static final long serialVersionUID = 7042863483428051319L;
private static final Logger LOG = LoggerFactory.getLogger(Account.class);
@ -67,7 +64,7 @@ public class Account extends AcmeJsonResource {
* @return {@code true} if the user agreed to the terms of service. May be
* {@code null} if the server did not provide such an information.
*/
@CheckForNull
@Nullable
public Boolean getTermsOfServiceAgreed() {
return getJSON().get(KEY_TOS_AGREED).map(Value::asBoolean).orElse(null);
}
@ -108,7 +105,7 @@ public class Account extends AcmeJsonResource {
*
* @since 2.8
*/
@CheckForNull
@Nullable
public String getKeyIdentifier() {
return getJSON().get(KEY_EXTERNAL_ACCOUNT_BINDING)
.optional().map(Value::asObject)
@ -277,7 +274,6 @@ public class Account extends AcmeJsonResource {
/**
* Editable {@link Account}.
*/
@ParametersAreNonnullByDefault
public class EditableAccount {
private final List<URI> editContacts = new ArrayList<>();

View File

@ -21,10 +21,10 @@ import java.security.KeyPair;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.connector.Connection;
import org.shredzone.acme4j.connector.Resource;
import org.shredzone.acme4j.exception.AcmeException;
@ -38,16 +38,15 @@ import org.slf4j.LoggerFactory;
/**
* A builder for registering a new account.
*/
@ParametersAreNonnullByDefault
public class AccountBuilder {
private static final Logger LOG = LoggerFactory.getLogger(AccountBuilder.class);
private List<URI> contacts = new ArrayList<>();
private Boolean termsOfServiceAgreed;
private Boolean onlyExisting;
private String keyIdentifier;
private KeyPair keyPair;
private SecretKey macKey;
private final List<URI> contacts = new ArrayList<>();
private @Nullable Boolean termsOfServiceAgreed;
private @Nullable Boolean onlyExisting;
private @Nullable String keyIdentifier;
private @Nullable KeyPair keyPair;
private @Nullable SecretKey macKey;
/**
* Add a contact URI to the list of contacts.

View File

@ -16,8 +16,7 @@ package org.shredzone.acme4j;
import java.net.URL;
import java.util.Objects;
import javax.annotation.ParametersAreNonnullByDefault;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.connector.Connection;
import org.shredzone.acme4j.exception.AcmeException;
import org.shredzone.acme4j.exception.AcmeLazyLoadingException;
@ -29,12 +28,11 @@ import org.slf4j.LoggerFactory;
/**
* An ACME resource that stores its state in a JSON structure.
*/
@ParametersAreNonnullByDefault
public abstract class AcmeJsonResource extends AcmeResource {
private static final long serialVersionUID = -5060364275766082345L;
private static final Logger LOG = LoggerFactory.getLogger(AcmeJsonResource.class);
private JSON data = null;
private @Nullable JSON data = null;
/**
* Create a new {@link AcmeJsonResource}.

View File

@ -17,16 +17,15 @@ import java.io.Serializable;
import java.net.URL;
import java.util.Objects;
import javax.annotation.ParametersAreNonnullByDefault;
import edu.umd.cs.findbugs.annotations.Nullable;
/**
* A generic ACME resource.
*/
@ParametersAreNonnullByDefault
public abstract class AcmeResource implements Serializable {
private static final long serialVersionUID = -7930580802257379731L;
private transient Login login;
private transient @Nullable Login login;
private final URL location;
/**

View File

@ -20,9 +20,7 @@ import java.time.Instant;
import java.util.Collections;
import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.ParametersAreNonnullByDefault;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.challenge.Challenge;
import org.shredzone.acme4j.connector.Connection;
import org.shredzone.acme4j.exception.AcmeException;
@ -36,7 +34,6 @@ import org.slf4j.LoggerFactory;
/**
* Represents an authorization request at the ACME server.
*/
@ParametersAreNonnullByDefault
public class Authorization extends AcmeJsonResource {
private static final long serialVersionUID = -3116928998379417741L;
private static final Logger LOG = LoggerFactory.getLogger(Authorization.class);
@ -72,7 +69,7 @@ public class Authorization extends AcmeJsonResource {
/**
* Gets the expiry date of the authorization, if set by the server.
*/
@CheckForNull
@Nullable
public Instant getExpires() {
return getJSON().get("expires")
.map(Value::asString)
@ -118,7 +115,7 @@ public class Authorization extends AcmeJsonResource {
* @throws ClassCastException
* if the type does not match the expected Challenge class type
*/
@CheckForNull
@Nullable
public <T extends Challenge> T findChallenge(final String type) {
return (T) getChallenges().stream()
.filter(ch -> type.equals(ch.getType()))
@ -136,7 +133,7 @@ public class Authorization extends AcmeJsonResource {
* challenge, or if the challenge alone is not sufficient for authorization.
* @since 2.8
*/
@CheckForNull
@Nullable
public <T extends Challenge> T findChallenge(Class<T> type) {
return getChallenges().stream()
.filter(type::isInstance)

View File

@ -25,10 +25,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.WillNotClose;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.connector.Connection;
import org.shredzone.acme4j.connector.Resource;
import org.shredzone.acme4j.exception.AcmeException;
@ -45,13 +42,12 @@ import org.slf4j.LoggerFactory;
* Note that a certificate is immutable once it is issued. For renewal, a new certificate
* must be ordered.
*/
@ParametersAreNonnullByDefault
public class Certificate extends AcmeResource {
private static final long serialVersionUID = 7381527770159084201L;
private static final Logger LOG = LoggerFactory.getLogger(Certificate.class);
private ArrayList<X509Certificate> certChain;
private ArrayList<URL> alternates;
private @Nullable ArrayList<X509Certificate> certChain;
private @Nullable ArrayList<URL> alternates;
protected Certificate(Login login, URL certUrl) {
super(login, certUrl);
@ -121,7 +117,7 @@ public class Certificate extends AcmeResource {
* @param out
* {@link Writer} to write to. The writer is not closed after use.
*/
public void writeCertificate(@WillNotClose Writer out) throws IOException {
public void writeCertificate(Writer out) throws IOException {
try {
for (X509Certificate cert : getCertificateChain()) {
AcmeUtils.writeToPem(cert.getEncoded(), AcmeUtils.PemLabel.CERTIFICATE, out);

View File

@ -21,9 +21,6 @@ import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Map;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
import org.shredzone.acme4j.exception.AcmeProtocolException;
import org.shredzone.acme4j.toolbox.JSON;
import org.shredzone.acme4j.toolbox.JSONBuilder;
@ -38,8 +35,6 @@ import org.shredzone.acme4j.toolbox.JSONBuilder;
*
* @since 2.3
*/
@ParametersAreNonnullByDefault
@Immutable
public class Identifier implements Serializable {
private static final long serialVersionUID = -7777851842076362412L;

View File

@ -19,9 +19,6 @@ import java.net.URL;
import java.security.KeyPair;
import java.util.Objects;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.ThreadSafe;
import org.shredzone.acme4j.challenge.Challenge;
import org.shredzone.acme4j.connector.Connection;
import org.shredzone.acme4j.exception.AcmeException;
@ -37,8 +34,6 @@ import org.shredzone.acme4j.toolbox.JSON;
* Note that {@link Login} objects are not serializable, as they contain a keypair and
* volatile data.
*/
@ParametersAreNonnullByDefault
@ThreadSafe
public class Login {
private final Session session;

View File

@ -21,18 +21,13 @@ import java.time.Duration;
import java.util.Collection;
import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.toolbox.JSON;
import org.shredzone.acme4j.toolbox.JSON.Value;
/**
* Contains metadata related to the provider.
*/
@ParametersAreNonnullByDefault
@Immutable
public class Metadata {
private final JSON meta;
@ -51,7 +46,7 @@ public class Metadata {
* Returns an {@link URI} to the current terms of service, or {@code null} if not
* available.
*/
@CheckForNull
@Nullable
public URI getTermsOfService() {
return meta.get("termsOfService").map(Value::asURI).orElse(null);
}
@ -60,7 +55,7 @@ public class Metadata {
* Returns an {@link URL} to a website providing more information about the ACME
* server. {@code null} if not available.
*/
@CheckForNull
@Nullable
public URL getWebsite() {
return meta.get("website").map(Value::asURL).orElse(null);
}
@ -100,6 +95,7 @@ public class Metadata {
*
* @since 2.3
*/
@Nullable
public Duration getAutoRenewalMinLifetime() {
Optional<JSON> ar = meta.get("auto-renewal").optional().map(Value::asObject);
if (!ar.isPresent()) {
@ -114,6 +110,7 @@ public class Metadata {
*
* @since 2.3
*/
@Nullable
public Duration getAutoRenewalMaxDuration() {
Optional<JSON> ar = meta.get("auto-renewal").optional().map(Value::asObject);
if (!ar.isPresent()) {

View File

@ -21,9 +21,7 @@ import java.time.Instant;
import java.util.Collections;
import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.ParametersAreNonnullByDefault;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.connector.Connection;
import org.shredzone.acme4j.exception.AcmeException;
import org.shredzone.acme4j.toolbox.JSON;
@ -35,7 +33,6 @@ import org.slf4j.LoggerFactory;
/**
* Represents a certificate order.
*/
@ParametersAreNonnullByDefault
public class Order extends AcmeJsonResource {
private static final long serialVersionUID = 5435808648658292177L;
private static final Logger LOG = LoggerFactory.getLogger(Order.class);
@ -57,7 +54,7 @@ public class Order extends AcmeJsonResource {
/**
* Returns a {@link Problem} document if the order failed.
*/
@CheckForNull
@Nullable
public Problem getError() {
return getJSON().get("error").map(v -> v.asProblem(getLocation())).orElse(null);
}
@ -65,7 +62,7 @@ public class Order extends AcmeJsonResource {
/**
* Gets the expiry date of the authorization, if set by the server.
*/
@CheckForNull
@Nullable
public Instant getExpires() {
return getJSON().get("expires").map(Value::asInstant).orElse(null);
}
@ -86,7 +83,7 @@ public class Order extends AcmeJsonResource {
/**
* Gets the "not before" date that was used for the order, or {@code null}.
*/
@CheckForNull
@Nullable
public Instant getNotBefore() {
return getJSON().get("notBefore").map(Value::asInstant).orElse(null);
}
@ -94,7 +91,7 @@ public class Order extends AcmeJsonResource {
/**
* Gets the "not after" date that was used for the order, or {@code null}.
*/
@CheckForNull
@Nullable
public Instant getNotAfter() {
return getJSON().get("notAfter").map(Value::asInstant).orElse(null);
}
@ -124,7 +121,7 @@ public class Order extends AcmeJsonResource {
/**
* Gets the {@link Certificate} if it is available. {@code null} otherwise.
*/
@CheckForNull
@Nullable
public Certificate getCertificate() {
return getJSON().get("certificate")
.map(Value::asURL)
@ -138,7 +135,7 @@ public class Order extends AcmeJsonResource {
*
* @since 2.6
*/
@CheckForNull
@Nullable
public Certificate getAutoRenewalCertificate() {
return getJSON().get("star-certificate")
.map(Value::asURL)
@ -188,7 +185,7 @@ public class Order extends AcmeJsonResource {
*
* @since 2.3
*/
@CheckForNull
@Nullable
public Instant getAutoRenewalStartDate() {
return getJSON().get("auto-renewal")
.optional()
@ -206,7 +203,7 @@ public class Order extends AcmeJsonResource {
*
* @since 2.3
*/
@CheckForNull
@Nullable
public Instant getAutoRenewalEndDate() {
return getJSON().get("auto-renewal")
.optional()
@ -223,7 +220,7 @@ public class Order extends AcmeJsonResource {
*
* @since 2.3
*/
@CheckForNull
@Nullable
public Duration getAutoRenewalLifetime() {
return getJSON().get("auto-renewal")
.optional()
@ -240,7 +237,7 @@ public class Order extends AcmeJsonResource {
*
* @since 2.7
*/
@CheckForNull
@Nullable
public Duration getAutoRenewalLifetimeAdjust() {
return getJSON().get("auto-renewal")
.optional()

View File

@ -23,8 +23,7 @@ import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.annotation.ParametersAreNonnullByDefault;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.connector.Connection;
import org.shredzone.acme4j.connector.Resource;
import org.shredzone.acme4j.exception.AcmeException;
@ -36,20 +35,19 @@ import org.slf4j.LoggerFactory;
/**
* A builder for a new {@link Order} object.
*/
@ParametersAreNonnullByDefault
public class OrderBuilder {
private static final Logger LOG = LoggerFactory.getLogger(OrderBuilder.class);
private final Login login;
private final Set<Identifier> identifierSet = new LinkedHashSet<>();
private Instant notBefore;
private Instant notAfter;
private @Nullable Instant notBefore;
private @Nullable Instant notAfter;
private boolean autoRenewal;
private Instant autoRenewalStart;
private Instant autoRenewalEnd;
private Duration autoRenewalLifetime;
private Duration autoRenewalLifetimeAdjust;
private @Nullable Instant autoRenewalStart;
private @Nullable Instant autoRenewalEnd;
private @Nullable Duration autoRenewalLifetime;
private @Nullable Duration autoRenewalLifetimeAdjust;
private boolean autoRenewalGet;
/**

View File

@ -22,10 +22,7 @@ import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.exception.AcmeProtocolException;
import org.shredzone.acme4j.toolbox.JSON;
import org.shredzone.acme4j.toolbox.JSON.Value;
@ -35,8 +32,6 @@ import org.shredzone.acme4j.toolbox.JSON.Value;
*
* @see <a href="https://tools.ietf.org/html/rfc7807">RFC 7807</a>
*/
@ParametersAreNonnullByDefault
@Immutable
public class Problem implements Serializable {
private static final long serialVersionUID = -8418248862966754214L;
@ -78,7 +73,7 @@ public class Problem implements Serializable {
*
* @see #toString()
*/
@CheckForNull
@Nullable
public String getTitle() {
return problemJson.get("title").map(Value::asString).orElse(null);
}
@ -89,7 +84,7 @@ public class Problem implements Serializable {
*
* @see #toString()
*/
@CheckForNull
@Nullable
public String getDetail() {
return problemJson.get("detail").map(Value::asString).orElse(null);
}
@ -98,7 +93,7 @@ public class Problem implements Serializable {
* Returns an URI that identifies the specific occurence of the problem. It is always
* an absolute URI.
*/
@CheckForNull
@Nullable
public URI getInstance() {
return problemJson.get("instance")
.map(Value::asString)
@ -117,7 +112,7 @@ public class Problem implements Serializable {
*
* @since 2.3
*/
@CheckForNull
@Nullable
public Identifier getIdentifier() {
return problemJson.get("identifier")
.optional()

View File

@ -15,9 +15,7 @@ package org.shredzone.acme4j;
import java.util.Arrays;
import javax.annotation.CheckForNull;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
import edu.umd.cs.findbugs.annotations.Nullable;
/**
* Enumeration of revocation reasons.
@ -25,8 +23,6 @@ import javax.annotation.concurrent.Immutable;
* @see <a href="https://tools.ietf.org/html/rfc5280#section-5.3.1">RFC 5280 Section
* 5.3.1</a>
*/
@ParametersAreNonnullByDefault
@Immutable
public enum RevocationReason {
UNSPECIFIED(0),
@ -60,7 +56,7 @@ public enum RevocationReason {
* Reason code as defined in RFC 5280
* @return Matching {@link RevocationReason}, or {@code null} if not known
*/
@CheckForNull
@Nullable
public static RevocationReason code(int reasonCode) {
return Arrays.stream(values())
.filter(rr -> rr.reasonCode == reasonCode)

View File

@ -26,11 +26,7 @@ import java.util.ServiceLoader;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.StreamSupport;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.ThreadSafe;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.connector.Connection;
import org.shredzone.acme4j.connector.NetworkSettings;
import org.shredzone.acme4j.connector.Resource;
@ -43,8 +39,6 @@ import org.shredzone.acme4j.toolbox.JSON.Value;
/**
* A session stores the ACME server URI. It also tracks communication parameters.
*/
@ParametersAreNonnullByDefault
@ThreadSafe
public class Session {
private static final GenericAcmeProvider GENERIC_PROVIDER = new GenericAcmeProvider();
@ -55,10 +49,10 @@ public class Session {
private final URI serverUri;
private final AcmeProvider provider;
private String nonce;
private @Nullable String nonce;
private Locale locale = Locale.getDefault();
protected ZonedDateTime directoryLastModified;
protected ZonedDateTime directoryExpires;
protected @Nullable ZonedDateTime directoryLastModified;
protected @Nullable ZonedDateTime directoryExpires;
/**
* Creates a new {@link Session}.
@ -143,7 +137,7 @@ public class Session {
/**
* Gets the last base64 encoded nonce, or {@code null} if the session is new.
*/
@CheckForNull
@Nullable
public String getNonce() {
return nonce;
}
@ -256,7 +250,7 @@ public class Session {
* (directory has not been read yet or did not provide this information).
* @since 2.10
*/
@CheckForNull
@Nullable
public ZonedDateTime getDirectoryLastModified() {
return directoryLastModified;
}
@ -282,7 +276,7 @@ public class Session {
* information.
* @since 2.10
*/
@CheckForNull
@Nullable
public ZonedDateTime getDirectoryExpires() {
return directoryExpires;
}

View File

@ -15,14 +15,9 @@ package org.shredzone.acme4j;
import java.util.Arrays;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* Status codes of challenges and authorizations.
*/
@ParametersAreNonnullByDefault
@Immutable
public enum Status {
/**

View File

@ -15,9 +15,7 @@ package org.shredzone.acme4j.challenge;
import java.time.Instant;
import javax.annotation.CheckForNull;
import javax.annotation.ParametersAreNonnullByDefault;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.AcmeJsonResource;
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.Problem;
@ -40,7 +38,6 @@ import org.slf4j.LoggerFactory;
* own type. {@link Challenge#prepareResponse(JSONBuilder)} should be overridden to put
* all required data to the response.
*/
@ParametersAreNonnullByDefault
public class Challenge extends AcmeJsonResource {
private static final long serialVersionUID = 2338794776848388099L;
private static final Logger LOG = LoggerFactory.getLogger(Challenge.class);
@ -84,7 +81,7 @@ public class Challenge extends AcmeJsonResource {
/**
* Returns the validation date, if returned by the server.
*/
@CheckForNull
@Nullable
public Instant getValidated() {
return getJSON().get(KEY_VALIDATED).map(Value::asInstant).orElse(null);
}
@ -94,7 +91,7 @@ public class Challenge extends AcmeJsonResource {
* server. If there are multiple errors, they can be found in
* {@link Problem#getSubProblems()}.
*/
@CheckForNull
@Nullable
public Problem getError() {
return getJSON().get(KEY_ERROR)
.map(it -> it.asProblem(getLocation()))

View File

@ -16,15 +16,12 @@ package org.shredzone.acme4j.challenge;
import static org.shredzone.acme4j.toolbox.AcmeUtils.base64UrlEncode;
import static org.shredzone.acme4j.toolbox.AcmeUtils.sha256hash;
import javax.annotation.ParametersAreNonnullByDefault;
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.toolbox.JSON;
/**
* Implements the {@value TYPE} challenge.
*/
@ParametersAreNonnullByDefault
public class Dns01Challenge extends TokenChallenge {
private static final long serialVersionUID = 6964687027713533075L;

View File

@ -13,15 +13,12 @@
*/
package org.shredzone.acme4j.challenge;
import javax.annotation.ParametersAreNonnullByDefault;
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.toolbox.JSON;
/**
* Implements the {@value TYPE} challenge.
*/
@ParametersAreNonnullByDefault
public class Http01Challenge extends TokenChallenge {
private static final long serialVersionUID = 3322211185872544605L;

View File

@ -15,8 +15,6 @@ package org.shredzone.acme4j.challenge;
import static org.shredzone.acme4j.toolbox.AcmeUtils.sha256hash;
import javax.annotation.ParametersAreNonnullByDefault;
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.toolbox.JSON;
@ -25,7 +23,6 @@ import org.shredzone.acme4j.toolbox.JSON;
*
* @since 2.1
*/
@ParametersAreNonnullByDefault
public class TlsAlpn01Challenge extends TokenChallenge {
private static final long serialVersionUID = -5590351078176091228L;

View File

@ -17,8 +17,6 @@ import static org.shredzone.acme4j.toolbox.AcmeUtils.base64UrlEncode;
import java.security.PublicKey;
import javax.annotation.ParametersAreNonnullByDefault;
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.exception.AcmeProtocolException;
import org.shredzone.acme4j.toolbox.AcmeUtils;
@ -29,7 +27,6 @@ import org.shredzone.acme4j.toolbox.JoseUtils;
* An extension of {@link Challenge} that handles challenges with a {@code token} and
* {@code keyAuthorization}.
*/
@ParametersAreNonnullByDefault
public class TokenChallenge extends Challenge {
private static final long serialVersionUID = 1634133407432681800L;

View File

@ -0,0 +1,23 @@
/*
* acme4j - Java ACME client
*
* Copyright (C) 2020 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
@ReturnValuesAreNonnullByDefault
@DefaultAnnotationForParameters(NonNull.class)
@DefaultAnnotationForFields(NonNull.class)
package org.shredzone.acme4j.challenge;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForFields;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForParameters;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;

View File

@ -22,10 +22,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.Session;
import org.shredzone.acme4j.exception.AcmeException;
@ -37,7 +34,6 @@ import org.shredzone.acme4j.toolbox.JSONBuilder;
/**
* Connects to the ACME server and offers different methods for invoking the API.
*/
@ParametersAreNonnullByDefault
public interface Connection extends AutoCloseable {
/**
@ -166,7 +162,7 @@ public interface Connection extends AutoCloseable {
*
* @return Base64 encoded nonce, or {@code null} if no nonce header was set
*/
@CheckForNull
@Nullable
String getNonce();
/**
@ -176,7 +172,7 @@ public interface Connection extends AutoCloseable {
*
* @return Location {@link URL}, or {@code null} if no Location header was set
*/
@CheckForNull
@Nullable
URL getLocation();
/**

View File

@ -41,10 +41,7 @@ import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.Problem;
import org.shredzone.acme4j.Session;
@ -66,7 +63,6 @@ import org.slf4j.LoggerFactory;
/**
* Default implementation of {@link Connection}.
*/
@ParametersAreNonnullByDefault
public class DefaultConnection implements Connection {
private static final Logger LOG = LoggerFactory.getLogger(DefaultConnection.class);
@ -95,7 +91,7 @@ public class DefaultConnection implements Connection {
private static final Pattern MAX_AGE_PATTERN = Pattern.compile("(?:^|.*?,)\\s*max-age=(\\d+)\\s*(?:,.*|$)", Pattern.CASE_INSENSITIVE);
protected final HttpConnector httpConnector;
protected HttpURLConnection conn;
protected @Nullable HttpURLConnection conn;
/**
* Creates a new {@link DefaultConnection}.
@ -232,7 +228,7 @@ public class DefaultConnection implements Connection {
}
@Override
@CheckForNull
@Nullable
public String getNonce() {
assertConnectionIsOpen();
@ -251,7 +247,7 @@ public class DefaultConnection implements Connection {
}
@Override
@CheckForNull
@Nullable
public URL getLocation() {
assertConnectionIsOpen();
@ -625,7 +621,7 @@ public class DefaultConnection implements Connection {
* @return Absolute URL of the given link, or {@code null} if the link was
* {@code null}.
*/
@CheckForNull
@Nullable
private URL resolveRelative(@Nullable String link) {
if (link == null) {
return null;
@ -647,7 +643,7 @@ public class DefaultConnection implements Connection {
* @return Absolute URI of the given link, or {@code null} if the URI was
* {@code null}.
*/
@CheckForNull
@Nullable
private URI resolveUri(@Nullable String uri) {
if (uri == null) {
return null;

View File

@ -19,10 +19,6 @@ import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Properties;
import javax.annotation.OverridingMethodsMustInvokeSuper;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.ThreadSafe;
import org.slf4j.LoggerFactory;
/**
@ -32,8 +28,6 @@ import org.slf4j.LoggerFactory;
* Subclasses may reconfigure the {@link HttpURLConnection} and pin it to a concrete SSL
* certificate.
*/
@ParametersAreNonnullByDefault
@ThreadSafe
public class HttpConnector {
private static final String USER_AGENT;
@ -90,7 +84,6 @@ public class HttpConnector {
* @param settings
* {@link NetworkSettings} with settings to be used
*/
@OverridingMethodsMustInvokeSuper
protected void configure(HttpURLConnection conn, NetworkSettings settings) {
int timeout = (int) settings.getTimeout().toMillis();
conn.setConnectTimeout(timeout);

View File

@ -16,15 +16,13 @@ package org.shredzone.acme4j.connector;
import java.net.Proxy;
import java.time.Duration;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import edu.umd.cs.findbugs.annotations.Nullable;
/**
* Contains network settings to be used for network connections.
*
* @since 2.8
*/
@ParametersAreNonnullByDefault
public class NetworkSettings {
private Proxy proxy = Proxy.NO_PROXY;

View File

@ -13,14 +13,9 @@
*/
package org.shredzone.acme4j.connector;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* Enumeration of resources.
*/
@ParametersAreNonnullByDefault
@Immutable
public enum Resource {
NEW_NONCE("newNonce"),

View File

@ -21,9 +21,7 @@ import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.BiFunction;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.AcmeResource;
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.Session;
@ -38,7 +36,6 @@ import org.shredzone.acme4j.toolbox.JSON;
* @param <T>
* {@link AcmeResource} type to iterate over
*/
@ParametersAreNonnullByDefault
public class ResourceIterator<T extends AcmeResource> implements Iterator<T> {
private final Login login;
@ -46,7 +43,7 @@ public class ResourceIterator<T extends AcmeResource> implements Iterator<T> {
private final Deque<URL> urlList = new ArrayDeque<>();
private final BiFunction<Login, URL, T> creator;
private boolean eol = false;
private URL nextUrl;
private @Nullable URL nextUrl;
/**
* Creates a new {@link ResourceIterator}.

View File

@ -16,13 +16,10 @@ package org.shredzone.acme4j.connector;
import java.io.IOException;
import java.io.InputStream;
import javax.annotation.ParametersAreNonnullByDefault;
/**
* Normalizes line separators in an InputStream. Converts all line separators to '\n'.
* Multiple line separators are compressed to a single line separator.
*/
@ParametersAreNonnullByDefault
public class TrimmingInputStream extends InputStream {
private final InputStream in;

View File

@ -0,0 +1,23 @@
/*
* acme4j - Java ACME client
*
* Copyright (C) 2020 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
@ReturnValuesAreNonnullByDefault
@DefaultAnnotationForParameters(NonNull.class)
@DefaultAnnotationForFields(NonNull.class)
package org.shredzone.acme4j.connector;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForFields;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForParameters;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;

View File

@ -13,14 +13,9 @@
*/
package org.shredzone.acme4j.exception;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* A generic ACME exception.
*/
@ParametersAreNonnullByDefault
@Immutable
public class AcmeException extends Exception {
private static final long serialVersionUID = -2935088954705632025L;

View File

@ -17,17 +17,12 @@ import static java.util.Objects.requireNonNull;
import java.net.URL;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
import org.shredzone.acme4j.AcmeResource;
/**
* This runtime exception is thrown when an {@link AcmeException} occured while trying to
* lazy-load a resource from the ACME server.
*/
@ParametersAreNonnullByDefault
@Immutable
public class AcmeLazyLoadingException extends RuntimeException {
private static final long serialVersionUID = 1000353433913721901L;

View File

@ -15,15 +15,10 @@ package org.shredzone.acme4j.exception;
import java.io.IOException;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* This exception is thrown when a network error occured while communicating with the
* server.
*/
@ParametersAreNonnullByDefault
@Immutable
public class AcmeNetworkException extends AcmeException {
private static final long serialVersionUID = 2054398693543329179L;

View File

@ -13,15 +13,10 @@
*/
package org.shredzone.acme4j.exception;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* This runtime exception is thrown on ACME protocol errors that should not occur. For
* example, this exception is thrown when a server response could not be parsed.
*/
@ParametersAreNonnullByDefault
@Immutable
public class AcmeProtocolException extends RuntimeException {
private static final long serialVersionUID = 2031203835755725193L;

View File

@ -18,23 +18,17 @@ import java.time.Instant;
import java.util.Collection;
import java.util.Collections;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.Problem;
/**
* An exception that is thrown when a rate limit was exceeded.
*/
@ParametersAreNonnullByDefault
@Immutable
public class AcmeRateLimitedException extends AcmeServerException {
private static final long serialVersionUID = 4150484059796413069L;
private final Instant retryAfter;
private final Collection<URL> documents;
private final @Nullable Instant retryAfter;
private final @Nullable Collection<URL> documents;
/**
* Creates a new {@link AcmeRateLimitedException}.
@ -59,7 +53,7 @@ public class AcmeRateLimitedException extends AcmeServerException {
* Returns the moment the request is expected to succeed again. {@code null} if this
* moment is not known.
*/
@CheckForNull
@Nullable
public Instant getRetryAfter() {
return retryAfter;
}
@ -68,7 +62,7 @@ public class AcmeRateLimitedException extends AcmeServerException {
* Collection of URLs pointing to documents about the rate limit that was hit.
* {@code null} if the server did not provide such URLs.
*/
@CheckForNull
@Nullable
public Collection<URL> getDocuments() {
return documents;
}

View File

@ -16,15 +16,10 @@ package org.shredzone.acme4j.exception;
import java.time.Instant;
import java.util.Objects;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
/**
* This exception is thrown when a server side process has not been completed yet, and the
* server returned an estimated retry date.
*/
@ParametersAreNonnullByDefault
@Immutable
public class AcmeRetryAfterException extends AcmeException {
private static final long serialVersionUID = 4461979121063649905L;

View File

@ -16,17 +16,12 @@ package org.shredzone.acme4j.exception;
import java.net.URI;
import java.util.Objects;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
import org.shredzone.acme4j.Problem;
/**
* An exception that is thrown when the ACME server returned an error. It contains
* further details of the cause.
*/
@ParametersAreNonnullByDefault
@Immutable
public class AcmeServerException extends AcmeException {
private static final long serialVersionUID = 5971622508467042792L;

View File

@ -13,17 +13,12 @@
*/
package org.shredzone.acme4j.exception;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
import org.shredzone.acme4j.Problem;
/**
* An exception that is thrown when the client is not authorized. The details will give
* an explanation for the reasons (e.g. "client not on a whitelist").
*/
@ParametersAreNonnullByDefault
@Immutable
public class AcmeUnauthorizedException extends AcmeServerException {
private static final long serialVersionUID = 9064697508262919366L;

View File

@ -17,11 +17,7 @@ import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.Problem;
/**
@ -30,12 +26,10 @@ import org.shredzone.acme4j.Problem;
* Usually this exception is thrown when the terms of service have changed, and the CA
* requires an agreement to the new terms before proceeding.
*/
@ParametersAreNonnullByDefault
@Immutable
public class AcmeUserActionRequiredException extends AcmeServerException {
private static final long serialVersionUID = 7719055447283858352L;
private final URI tosUri;
private final @Nullable URI tosUri;
/**
* Creates a new {@link AcmeUserActionRequiredException}.
@ -54,7 +48,7 @@ public class AcmeUserActionRequiredException extends AcmeServerException {
* Returns the {@link URI} of the terms-of-service document to accept, or {@code null}
* if the server did not provide a link to such a document.
*/
@CheckForNull
@Nullable
public URI getTermsOfServiceUri() {
return tosUri;
}

View File

@ -0,0 +1,23 @@
/*
* acme4j - Java ACME client
*
* Copyright (C) 2020 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
@ReturnValuesAreNonnullByDefault
@DefaultAnnotationForParameters(NonNull.class)
@DefaultAnnotationForFields(NonNull.class)
package org.shredzone.acme4j.exception;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForFields;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForParameters;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;

View File

@ -0,0 +1,23 @@
/*
* acme4j - Java ACME client
*
* Copyright (C) 2020 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
@ReturnValuesAreNonnullByDefault
@DefaultAnnotationForParameters(NonNull.class)
@DefaultAnnotationForFields(NonNull.class)
package org.shredzone.acme4j;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForFields;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForParameters;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;

View File

@ -22,8 +22,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.function.BiFunction;
import javax.annotation.ParametersAreNonnullByDefault;
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.Session;
import org.shredzone.acme4j.challenge.Challenge;
@ -44,7 +42,6 @@ import org.shredzone.acme4j.toolbox.JSON;
* Implementing classes must implement at least {@link AcmeProvider#accepts(URI)}
* and {@link AbstractAcmeProvider#resolve(URI)}.
*/
@ParametersAreNonnullByDefault
public abstract class AbstractAcmeProvider implements AcmeProvider {
private static final Map<String, BiFunction<Login, JSON, Challenge>> CHALLENGES = challengeMap();

View File

@ -17,9 +17,7 @@ import java.net.URI;
import java.net.URL;
import java.util.ServiceLoader;
import javax.annotation.CheckForNull;
import javax.annotation.ParametersAreNonnullByDefault;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.Session;
import org.shredzone.acme4j.challenge.Challenge;
@ -33,7 +31,6 @@ import org.shredzone.acme4j.toolbox.JSON;
* <p>
* Provider implementations must be registered with Java's {@link ServiceLoader}.
*/
@ParametersAreNonnullByDefault
public interface AcmeProvider {
/**
@ -80,7 +77,7 @@ public interface AcmeProvider {
* @return Directory data, as JSON object, or {@code null} if the directory has not
* been changed since the last request.
*/
@CheckForNull
@Nullable
JSON directory(Session session, URI serverUri) throws AcmeException;
/**
@ -93,7 +90,7 @@ public interface AcmeProvider {
* @return {@link Challenge} instance, or {@code null} if this provider is unable to
* generate a matching {@link Challenge} instance.
*/
@CheckForNull
@Nullable
Challenge createChallenge(Login login, JSON data);
}

View File

@ -17,15 +17,12 @@ import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import javax.annotation.ParametersAreNonnullByDefault;
/**
* A generic {@link AcmeProvider}. It should be working for all ACME servers complying to
* the ACME specifications.
* <p>
* The {@code serverUri} is either a http or https URI to the server's directory service.
*/
@ParametersAreNonnullByDefault
public class GenericAcmeProvider extends AbstractAcmeProvider {
@Override

View File

@ -17,8 +17,6 @@ import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import javax.annotation.ParametersAreNonnullByDefault;
import org.shredzone.acme4j.exception.AcmeProtocolException;
import org.shredzone.acme4j.provider.AbstractAcmeProvider;
import org.shredzone.acme4j.provider.AcmeProvider;
@ -33,7 +31,6 @@ import org.shredzone.acme4j.provider.AcmeProvider;
*
* @see <a href="https://letsencrypt.org/">Let's Encrypt</a>
*/
@ParametersAreNonnullByDefault
public class LetsEncryptAcmeProvider extends AbstractAcmeProvider {
private static final String V02_DIRECTORY_URL = "https://acme-v02.api.letsencrypt.org/directory";

View File

@ -0,0 +1,23 @@
/*
* acme4j - Java ACME client
*
* Copyright (C) 2020 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
@ReturnValuesAreNonnullByDefault
@DefaultAnnotationForParameters(NonNull.class)
@DefaultAnnotationForFields(NonNull.class)
package org.shredzone.acme4j.provider.letsencrypt;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForFields;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForParameters;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;

View File

@ -0,0 +1,23 @@
/*
* acme4j - Java ACME client
*
* Copyright (C) 2020 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
@ReturnValuesAreNonnullByDefault
@DefaultAnnotationForParameters(NonNull.class)
@DefaultAnnotationForFields(NonNull.class)
package org.shredzone.acme4j.provider;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForFields;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForParameters;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;

View File

@ -19,8 +19,6 @@ import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.ParametersAreNonnullByDefault;
import org.shredzone.acme4j.connector.HttpConnector;
import org.shredzone.acme4j.provider.AbstractAcmeProvider;
import org.shredzone.acme4j.provider.AcmeProvider;
@ -36,7 +34,6 @@ import org.shredzone.acme4j.provider.AcmeProvider;
* possible to connect to an external Pebble server on the given {@code other-host} and
* port. The port is optional, and if omitted, the standard port is used.
*/
@ParametersAreNonnullByDefault
public class PebbleAcmeProvider extends AbstractAcmeProvider {
private static final Pattern HOST_PATTERN = Pattern.compile("^/([^:/]+)(?:\\:(\\d+))?/?$");

View File

@ -22,14 +22,14 @@ import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Objects;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.ThreadSafe;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.connector.HttpConnector;
import org.shredzone.acme4j.connector.NetworkSettings;
@ -37,10 +37,8 @@ import org.shredzone.acme4j.connector.NetworkSettings;
* {@link HttpConnector} to be used for Pebble. Pebble uses a static, self signed SSL
* certificate.
*/
@ParametersAreNonnullByDefault
@ThreadSafe
public class PebbleHttpConnector extends HttpConnector {
private static SSLSocketFactory sslSocketFactory;
private static @Nullable SSLSocketFactory sslSocketFactory = null;
@Override
public HttpURLConnection openConnection(URL url, NetworkSettings settings) throws IOException {
@ -75,7 +73,7 @@ public class PebbleHttpConnector extends HttpConnector {
throw new IOException("Could not create truststore", ex);
}
}
return sslSocketFactory;
return Objects.requireNonNull(sslSocketFactory);
}
}

View File

@ -0,0 +1,23 @@
/*
* acme4j - Java ACME client
*
* Copyright (C) 2020 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
@ReturnValuesAreNonnullByDefault
@DefaultAnnotationForParameters(NonNull.class)
@DefaultAnnotationForFields(NonNull.class)
package org.shredzone.acme4j.provider.pebble;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForFields;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForParameters;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;

View File

@ -29,12 +29,7 @@ import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.WillNotClose;
import javax.annotation.concurrent.Immutable;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.shredzone.acme4j.exception.AcmeProtocolException;
/**
@ -43,7 +38,6 @@ import org.shredzone.acme4j.exception.AcmeProtocolException;
* This class is internal. You may use it in your own code, but be warned that methods may
* change their signature or disappear without prior announcement.
*/
@ParametersAreNonnullByDefault
public final class AcmeUtils {
private static final char[] HEX = "0123456789abcdef".toCharArray();
private static final String ACME_ERROR_PREFIX = "urn:ietf:params:acme:error:";
@ -72,8 +66,6 @@ public final class AcmeUtils {
/**
* Enumeration of PEM labels.
*/
@ParametersAreNonnullByDefault
@Immutable
public enum PemLabel {
CERTIFICATE("CERTIFICATE"),
CERTIFICATE_REQUEST("CERTIFICATE REQUEST"),
@ -239,7 +231,7 @@ public final class AcmeUtils {
* Error type to strip the prefix from. {@code null} is safe.
* @return Stripped error type, or {@code null} if the prefix was not found.
*/
@CheckForNull
@Nullable
public static String stripErrorPrefix(@Nullable String type) {
if (type != null && type.startsWith(ACME_ERROR_PREFIX)) {
return type.substring(ACME_ERROR_PREFIX.length());
@ -258,7 +250,7 @@ public final class AcmeUtils {
* @param out
* {@link Writer} to write to. It will not be closed after use!
*/
public static void writeToPem(byte[] encoded, PemLabel label, @WillNotClose Writer out)
public static void writeToPem(byte[] encoded, PemLabel label, Writer out)
throws IOException {
out.append("-----BEGIN ").append(label.toString()).append("-----\n");
out.append(new String(PEM_ENCODER.encode(encoded), StandardCharsets.US_ASCII));
@ -274,7 +266,7 @@ public final class AcmeUtils {
* @throws AcmeProtocolException
* if the Content-Type header contains a different charset than "utf-8".
*/
@CheckForNull
@Nullable
public static String getContentType(@Nullable String header) {
if (header != null) {
Matcher m = CONTENT_TYPE_PATTERN.matcher(header);

View File

@ -43,11 +43,7 @@ import java.util.function.Function;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.WillClose;
import javax.annotation.concurrent.Immutable;
import edu.umd.cs.findbugs.annotations.Nullable;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.jose4j.json.JsonUtil;
import org.jose4j.lang.JoseException;
@ -59,8 +55,6 @@ import org.shredzone.acme4j.exception.AcmeProtocolException;
/**
* A model containing a JSON result. The content is immutable.
*/
@ParametersAreNonnullByDefault
@Immutable
public final class JSON implements Serializable {
private static final long serialVersionUID = 3091273044605709204L;
@ -101,7 +95,7 @@ public final class JSON implements Serializable {
* {@link InputStream} to read from. Will be closed after use.
* @return {@link JSON} of the read content.
*/
public static JSON parse(@WillClose InputStream in) throws IOException {
public static JSON parse(InputStream in) throws IOException {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, "utf-8"))) {
String json = reader.lines().map(String::trim).collect(joining());
return parse(json);
@ -205,8 +199,6 @@ public final class JSON implements Serializable {
/**
* Represents a JSON array.
*/
@ParametersAreNonnullByDefault
@Immutable
public static final class Array implements Iterable<Value> {
private final String path;
private final List<Object> data;
@ -275,11 +267,9 @@ public final class JSON implements Serializable {
* All return values are never {@code null} unless specified otherwise. For optional
* parameters, use {@link Value#optional()}.
*/
@ParametersAreNonnullByDefault
@Immutable
public static final class Value {
private final String path;
private final Object val;
private final @Nullable Object val;
/**
* Creates a new {@link Value}.
@ -519,7 +509,6 @@ public final class JSON implements Serializable {
/**
* An {@link Iterator} over array {@link Value}.
*/
@ParametersAreNonnullByDefault
private static class ValueIterator implements Iterator<Value> {
private final Array array;
private int index = 0;

View File

@ -26,9 +26,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.jose4j.json.JsonUtil;
/**
@ -42,7 +40,6 @@ import org.jose4j.json.JsonUtil;
* cb.array("array", 123, 456, 789);
* </pre>
*/
@ParametersAreNonnullByDefault
public class JSONBuilder {
private final Map<String, Object> data = new LinkedHashMap<>();

View File

@ -18,10 +18,9 @@ import java.security.KeyPair;
import java.security.PublicKey;
import java.util.Map;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.crypto.SecretKey;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.jose4j.jwk.EllipticCurveJsonWebKey;
import org.jose4j.jwk.JsonWebKey;
import org.jose4j.jwk.PublicJsonWebKey;
@ -37,7 +36,6 @@ import org.slf4j.LoggerFactory;
*
* @since 2.7
*/
@ParametersAreNonnullByDefault
public final class JoseUtils {
private static final Logger LOG = LoggerFactory.getLogger(JoseUtils.class);
@ -65,7 +63,7 @@ public final class JoseUtils {
* @return JSON structure of the JOSE request, ready to be sent.
*/
public static JSONBuilder createJoseRequest(URL url, KeyPair keypair,
@Nullable JSONBuilder payload, @Nullable String nonce, @Nullable String kid) {
@Nullable JSONBuilder payload, @Nullable String nonce, @Nullable String kid) {
try {
PublicJsonWebKey jwk = PublicJsonWebKey.Factory.newPublicJwk(keypair.getPublic());

View File

@ -0,0 +1,23 @@
/*
* acme4j - Java ACME client
*
* Copyright (C) 2020 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
@ReturnValuesAreNonnullByDefault
@DefaultAnnotationForParameters(NonNull.class)
@DefaultAnnotationForFields(NonNull.class)
package org.shredzone.acme4j.toolbox;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForFields;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForParameters;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;

View File

@ -30,8 +30,6 @@ import java.time.temporal.ChronoUnit;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.ParametersAreNonnullByDefault;
import org.junit.Test;
import org.shredzone.acme4j.Login;
import org.shredzone.acme4j.Session;
@ -310,7 +308,6 @@ public class AbstractAcmeProviderTest {
}
}
@ParametersAreNonnullByDefault
private static class TestAbstractAcmeProvider extends AbstractAcmeProvider {
private final Connection connection;

View File

@ -17,8 +17,6 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
@ -33,7 +31,6 @@ import org.shredzone.acme4j.toolbox.JSONBuilder;
/**
* The BammBamm client connects to the pebble-challtestsrv.
*/
@ParametersAreNonnullByDefault
public class BammBammClient {
private static final HttpClient CLIENT = HttpClients.createDefault();

View File

@ -0,0 +1,23 @@
/*
* acme4j - Java ACME client
*
* Copyright (C) 2020 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
@ReturnValuesAreNonnullByDefault
@DefaultAnnotationForParameters(NonNull.class)
@DefaultAnnotationForFields(NonNull.class)
package org.shredzone.acme4j.it;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForFields;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForParameters;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;

View File

@ -31,9 +31,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Objects;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.WillClose;
import edu.umd.cs.findbugs.annotations.Nullable;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
@ -57,7 +55,6 @@ import org.shredzone.acme4j.Identifier;
* <p>
* Requires {@code Bouncy Castle}. This class is part of the {@code acme4j-utils} module.
*/
@ParametersAreNonnullByDefault
public class CSRBuilder {
private static final String SIGNATURE_ALG = "SHA256withRSA";
private static final String EC_SIGNATURE_ALG = "SHA256withECDSA";
@ -65,7 +62,7 @@ public class CSRBuilder {
private final X500NameBuilder namebuilder = new X500NameBuilder(X500Name.getDefaultStyle());
private final List<String> namelist = new ArrayList<>();
private final List<InetAddress> iplist = new ArrayList<>();
private PKCS10CertificationRequest csr = null;
private @Nullable PKCS10CertificationRequest csr = null;
/**
* Adds a domain name to the CSR. The first domain name added will also be the
@ -296,7 +293,7 @@ public class CSRBuilder {
* {@link Writer} to write the PEM file to. The {@link Writer} is closed
* after use.
*/
public void write(@WillClose Writer w) throws IOException {
public void write(Writer w) throws IOException {
if (csr == null) {
throw new IllegalStateException("sign CSR first");
}
@ -313,7 +310,7 @@ public class CSRBuilder {
* {@link OutputStream} to write the PEM file to. The {@link OutputStream}
* is closed after use.
*/
public void write(@WillClose OutputStream out) throws IOException {
public void write(OutputStream out) throws IOException {
write(new OutputStreamWriter(out, "utf-8"));
}

View File

@ -33,9 +33,6 @@ import java.util.Date;
import java.util.Objects;
import java.util.function.Function;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.WillClose;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DEROctetString;
@ -64,7 +61,6 @@ import org.shredzone.acme4j.challenge.TlsAlpn01Challenge;
* <p>
* Requires {@code Bouncy Castle}. This class is part of the {@code acme4j-utils} module.
*/
@ParametersAreNonnullByDefault
public final class CertificateUtils {
/**
@ -87,7 +83,7 @@ public final class CertificateUtils {
* closed after use.
* @return CSR that was read
*/
public static PKCS10CertificationRequest readCSR(@WillClose InputStream in) throws IOException {
public static PKCS10CertificationRequest readCSR(InputStream in) throws IOException {
try (PEMParser pemParser = new PEMParser(new InputStreamReader(in, StandardCharsets.US_ASCII))) {
Object parsedObj = pemParser.readObject();
if (!(parsedObj instanceof PKCS10CertificationRequest)) {

View File

@ -23,9 +23,6 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.WillClose;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.openssl.PEMException;
@ -39,7 +36,6 @@ import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
* <p>
* Requires {@code Bouncy Castle}. This class is part of the {@code acme4j-utils} module.
*/
@ParametersAreNonnullByDefault
public class KeyPairUtils {
private KeyPairUtils() {
@ -104,7 +100,7 @@ public class KeyPairUtils {
* after use.
* @return {@link KeyPair} read
*/
public static KeyPair readKeyPair(@WillClose Reader r) throws IOException {
public static KeyPair readKeyPair(Reader r) throws IOException {
try (PEMParser parser = new PEMParser(r)) {
PEMKeyPair keyPair = (PEMKeyPair) parser.readObject();
return new JcaPEMKeyConverter().getKeyPair(keyPair);
@ -122,7 +118,7 @@ public class KeyPairUtils {
* {@link Writer} to write the PEM file to. The {@link Writer} is closed
* after use.
*/
public static void writeKeyPair(KeyPair keypair, @WillClose Writer w) throws IOException {
public static void writeKeyPair(KeyPair keypair, Writer w) throws IOException {
try (JcaPEMWriter jw = new JcaPEMWriter(w)) {
jw.writeObject(keypair);
}

View File

@ -0,0 +1,23 @@
/*
* acme4j - Java ACME client
*
* Copyright (C) 2020 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
@ReturnValuesAreNonnullByDefault
@DefaultAnnotationForParameters(NonNull.class)
@DefaultAnnotationForFields(NonNull.class)
package org.shredzone.acme4j.util;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForFields;
import edu.umd.cs.findbugs.annotations.DefaultAnnotationForParameters;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.ReturnValuesAreNonnullByDefault;

22
pom.xml
View File

@ -80,7 +80,7 @@
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>3.1.12.2</version>
<version>4.0.0</version>
<configuration>
<excludeFilterFile>src/config/spotbugs-exclude.xml</excludeFilterFile>
</configuration>
@ -171,16 +171,16 @@
</build>
<dependencies>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-annotations</artifactId>
<version>4.0.3</version>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>

View File

@ -4,7 +4,10 @@ This document will help you migrate your code to the latest _acme4j_ version.
## Migration to Version 2.10
- In a preparation for Java 9 modules, the JSR305 null-safe annotations have been replaced by SpotBugs annotations. This _should_ have no impact on your code, as the method signatures themselves are unchanged. However, the compiler could now complain about some `null` dereferences that have been undetected before. Reason is that JSR305 uses the `javax.annotations` package, which leads to split packages in a Java 9 modular environment.
- When fetching the directory, acme4j now evaluates HTTP caching headers instead of just caching the directory for 1 hour. However, Let's Encrypt explicitly forbids caching, which means that a fresh copy of the directory is now fetched from the server every time it is needed. I don't like it, but it is the RFC conformous behavior. It needs to be [fixed on Let's Encrypt side](https://github.com/letsencrypt/boulder/issues/4814).
- `AcmeProvider.directory(Session, URI)` is now responsible for maintaining the cache. Implementations can use `Session.setDirectoryExpires()`, `Session.setDirectoryLastModified()`, and the respective getters, for keeping track of the local directory state. `AcmeProvider.directory(Session, URI)` may now return `null`, to indicate that the remote directory was unchanged and the local copy is still valid. It's not permitted to return `null` if `Session.hasDirectory()` returns `false`, though! If your `AcmeProvider` is derived from `AbstractAcmeProvider`, and you haven't overridden the `directory()` method, no migration is necessary.
## Migration to Version 2.9