Replace new URL() with URI.create()

new URL() is deprecated starting Java 20
master
Richard Körber 2025-05-18 10:19:40 +02:00
parent 29c6dc97a1
commit b62709470e
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
19 changed files with 58 additions and 51 deletions

View File

@ -23,6 +23,7 @@ import java.io.IOException;
import java.io.Serial;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.security.KeyPair;
import java.security.Principal;
@ -206,7 +207,7 @@ public class Certificate extends AcmeResource {
url += '/';
}
url += getRenewalUniqueIdentifier(getCertificate());
return new URL(url);
return URI.create(url).toURL();
} catch (MalformedURLException ex) {
throw new AcmeProtocolException("Invalid RenewalInfo URL", ex);
}

View File

@ -17,6 +17,7 @@ import static java.util.Objects.requireNonNull;
import static org.shredzone.acme4j.toolbox.AcmeUtils.getRenewalUniqueIdentifier;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.security.KeyPair;
import java.security.cert.X509Certificate;
@ -171,7 +172,7 @@ public class Login {
url += '/';
}
url += getRenewalUniqueIdentifier(certificate);
return bindRenewalInfo(new URL(url));
return bindRenewalInfo(URI.create(url).toURL());
} catch (MalformedURLException ex) {
throw new AcmeProtocolException("Invalid RenewalInfo URL", ex);
}

View File

@ -54,7 +54,7 @@ public class BuypassAcmeProvider extends AbstractAcmeProvider {
}
try {
return new URL(directoryUrl);
return URI.create(directoryUrl).toURL();
} catch (MalformedURLException ex) {
throw new AcmeProtocolException(directoryUrl, ex);
}

View File

@ -56,7 +56,7 @@ public class GoogleAcmeProvider extends AbstractAcmeProvider {
}
try {
return new URL(directoryUrl);
return URI.create(directoryUrl).toURL();
} catch (MalformedURLException ex) {
throw new AcmeProtocolException(directoryUrl, ex);
}

View File

@ -55,7 +55,7 @@ public class LetsEncryptAcmeProvider extends AbstractAcmeProvider {
}
try {
return new URL(directoryUrl);
return URI.create(directoryUrl).toURL();
} catch (MalformedURLException ex) {
throw new AcmeProtocolException(directoryUrl, ex);
}

View File

@ -15,6 +15,7 @@ package org.shredzone.acme4j.provider.pebble;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.regex.Pattern;
@ -50,7 +51,7 @@ public class PebbleAcmeProvider extends AbstractAcmeProvider {
var path = serverUri.getPath();
int port = serverUri.getPort() != -1 ? serverUri.getPort() : PEBBLE_DEFAULT_PORT;
var baseUrl = new URL("https://localhost:" + port + "/dir");
var baseUrl = URI.create("https://localhost:" + port + "/dir").toURL();
if (path != null && !path.isEmpty() && !"/".equals(path)) {
baseUrl = parsePath(path);
@ -77,7 +78,11 @@ public class PebbleAcmeProvider extends AbstractAcmeProvider {
if (m.group(2) != null) {
port = Integer.parseInt(m.group(2));
}
return new URL("https", host, port, "/dir");
try {
return new URI("https", null, host, port, "/dir", null, null).toURL();
} catch (URISyntaxException ex) {
throw new IllegalArgumentException("Malformed Pebble host/port: " + path);
}
} else {
throw new IllegalArgumentException("Invalid Pebble host/port: " + path);
}

View File

@ -66,7 +66,7 @@ public class SslComAcmeProvider extends AbstractAcmeProvider {
}
try {
return new URL(directoryUrl);
return URI.create(directoryUrl).toURL();
} catch (MalformedURLException ex) {
throw new AcmeProtocolException(directoryUrl, ex);
}

View File

@ -50,7 +50,7 @@ public class ZeroSSLAcmeProvider extends AbstractAcmeProvider {
}
try {
return new URL(directoryUrl);
return URI.create(directoryUrl).toURL();
} catch (MalformedURLException ex) {
throw new AcmeProtocolException(directoryUrl, ex);
}

View File

@ -439,7 +439,7 @@ public final class JSON implements Serializable {
*/
public URL asURL() {
try {
return new URL(asString());
return asURI().toURL();
} catch (MalformedURLException ex) {
throw new AcmeProtocolException(path + ": bad URL " + val, ex);
}

View File

@ -21,6 +21,7 @@ import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serial;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
@ -38,7 +39,7 @@ public class AcmeResourceTest {
@Test
public void testConstructor() throws Exception {
var login = TestUtils.login();
var location = new URL("http://example.com/acme/resource");
var location = URI.create("http://example.com/acme/resource").toURL();
assertThrows(NullPointerException.class, () -> new DummyResource(null, null));
@ -53,7 +54,7 @@ public class AcmeResourceTest {
@Test
public void testSerialization() throws Exception {
var login = TestUtils.login();
var location = new URL("http://example.com/acme/resource");
var location = URI.create("http://example.com/acme/resource").toURL();
// Create a Challenge for testing
var challenge = new DummyResource(login, location);
@ -100,7 +101,7 @@ public class AcmeResourceTest {
public void testRebind() {
assertThrows(IllegalStateException.class, () -> {
var login = TestUtils.login();
var location = new URL("http://example.com/acme/resource");
var location = URI.create("http://example.com/acme/resource").toURL();
var resource = new DummyResource(login, location);
assertThat(resource.getLogin()).isEqualTo(login);

View File

@ -21,6 +21,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.security.KeyPair;
import java.security.cert.X509Certificate;
@ -287,7 +288,7 @@ public class CertificateTest {
// certid-cert.pem and certId provided by ACME ARI specs and known good
var certId = "aYhba4dGQEHhs3uEe6CuLN4ByNQ.AIdlQyE";
var certIdCert = TestUtils.createCertificate("/certid-cert.pem");
var certResourceUrl = new URL(resourceUrl.toExternalForm() + "/" + certId);
var certResourceUrl = URI.create(resourceUrl.toExternalForm() + "/" + certId).toURL();
var retryAfterInstant = Instant.now().plus(10L, ChronoUnit.DAYS);
var provider = new TestableConnectionProvider() {
@ -366,7 +367,7 @@ public class CertificateTest {
// certid-cert.pem and certId provided by ACME ARI specs and known good
var certId = "aYhba4dGQEHhs3uEe6CuLN4ByNQ.AIdlQyE";
var certIdCert = TestUtils.createCertificate("/certid-cert.pem");
var certResourceUrl = new URL(resourceUrl.toExternalForm() + "/" + certId);
var certResourceUrl = URI.create(resourceUrl.toExternalForm() + "/" + certId).toURL();
var provider = new TestableConnectionProvider() {
private boolean certRequested = false;

View File

@ -21,6 +21,7 @@ import static org.shredzone.acme4j.toolbox.TestUtils.url;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import org.junit.jupiter.api.Test;
@ -145,7 +146,7 @@ public class LoginTest {
*/
@Test
public void testBindChallenge() throws Exception {
var locationUrl = new URL("https://example.com/acme/challenge/1");
var locationUrl = URI.create("https://example.com/acme/challenge/1").toURL();
var mockChallenge = mock(Http01Challenge.class);
when(mockChallenge.getType()).thenReturn(Http01Challenge.TYPE);

View File

@ -21,7 +21,6 @@ import static org.shredzone.acme4j.toolbox.TestUtils.*;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.Locale;
@ -150,15 +149,15 @@ public class SessionTest {
assertThat(session.hasDirectory()).isFalse();
assertThat(session.resourceUrl(Resource.NEW_ACCOUNT))
.isEqualTo(new URL("https://example.com/acme/new-account"));
.isEqualTo(URI.create("https://example.com/acme/new-account").toURL());
// There is a local copy of the directory now
assertThat(session.hasDirectory()).isTrue();
assertThat(session.resourceUrl(Resource.NEW_AUTHZ))
.isEqualTo(new URL("https://example.com/acme/new-authz"));
.isEqualTo(URI.create("https://example.com/acme/new-authz").toURL());
assertThat(session.resourceUrl(Resource.NEW_ORDER))
.isEqualTo(new URL("https://example.com/acme/new-order"));
.isEqualTo(URI.create("https://example.com/acme/new-order").toURL());
assertThatExceptionOfType(AcmeNotSupportedException.class)
.isThrownBy(() -> session.resourceUrl(Resource.REVOKE_CERT))
@ -166,7 +165,7 @@ public class SessionTest {
assertThat(session.resourceUrlOptional(Resource.NEW_AUTHZ))
.isNotEmpty()
.contains(new URL("https://example.com/acme/new-authz"));
.contains(URI.create("https://example.com/acme/new-authz").toURL());
assertThat(session.resourceUrlOptional(Resource.REVOKE_CERT))
.isEmpty();
@ -223,11 +222,11 @@ public class SessionTest {
};
assertThat(session.resourceUrl(Resource.NEW_ACCOUNT))
.isEqualTo(new URL("https://example.com/acme/new-account"));
.isEqualTo(URI.create("https://example.com/acme/new-account").toURL());
assertThat(session.resourceUrl(Resource.NEW_AUTHZ))
.isEqualTo(new URL("https://example.com/acme/new-authz"));
.isEqualTo(URI.create("https://example.com/acme/new-authz").toURL());
assertThat(session.resourceUrl(Resource.NEW_ORDER))
.isEqualTo(new URL("https://example.com/acme/new-order"));
.isEqualTo(URI.create("https://example.com/acme/new-order").toURL());
var meta = session.getMetadata();
try (var softly = new AutoCloseableSoftAssertions()) {

View File

@ -88,9 +88,9 @@ public class DefaultConnectionTest {
@BeforeEach
public void setup(WireMockRuntimeInfo wmRuntimeInfo) throws Exception {
baseUrl = wmRuntimeInfo.getHttpBaseUrl();
directoryUrl = new URL(baseUrl + DIRECTORY_PATH);
newNonceUrl = new URL(baseUrl + NEW_NONCE_PATH);
requestUrl = new URL(baseUrl + REQUEST_PATH);
directoryUrl = URI.create(baseUrl + DIRECTORY_PATH).toURL();
newNonceUrl = URI.create(baseUrl + NEW_NONCE_PATH).toURL();
requestUrl = URI.create(baseUrl + REQUEST_PATH).toURL();
session = new Session(directoryUrl.toURI());
session.setLocale(Locale.JAPAN);
@ -262,7 +262,7 @@ public class DefaultConnectionTest {
try (var conn = session.connect()) {
conn.sendRequest(requestUrl, session, null);
var location = conn.getLocation();
assertThat(location).isEqualTo(new URL("https://example.com/otherlocation"));
assertThat(location).isEqualTo(URI.create("https://example.com/otherlocation").toURL());
}
}
@ -278,7 +278,7 @@ public class DefaultConnectionTest {
try (var conn = session.connect()) {
conn.sendRequest(requestUrl, session, null);
var location = conn.getLocation();
assertThat(location).isEqualTo(new URL(baseUrl + "/otherlocation"));
assertThat(location).isEqualTo(URI.create(baseUrl + "/otherlocation").toURL());
}
}
@ -295,9 +295,9 @@ public class DefaultConnectionTest {
try (var conn = session.connect()) {
conn.sendRequest(requestUrl, session, null);
assertThat(conn.getLinks("next")).containsExactly(new URL("https://example.com/acme/new-authz"));
assertThat(conn.getLinks("recover")).containsExactly(new URL(baseUrl + "/recover-acct"));
assertThat(conn.getLinks("terms-of-service")).containsExactly(new URL("https://example.com/acme/terms"));
assertThat(conn.getLinks("next")).containsExactly(URI.create("https://example.com/acme/new-authz").toURL());
assertThat(conn.getLinks("recover")).containsExactly(URI.create(baseUrl + "/recover-acct").toURL());
assertThat(conn.getLinks("terms-of-service")).containsExactly(URI.create("https://example.com/acme/terms").toURL());
assertThat(conn.getLinks("secret-stuff")).isEmpty();
}
}

View File

@ -17,7 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import java.net.Authenticator;
import java.net.URL;
import java.net.URI;
import java.net.http.HttpClient;
import java.time.Duration;
@ -71,7 +71,7 @@ public class HttpConnectorTest {
*/
@Test
public void testRequestBuilderDefaultValues() throws Exception {
var url = new URL("http://example.org:123/foo");
var url = URI.create("http://example.org:123/foo").toURL();
var settings = new NetworkSettings();
var connector = new HttpConnector(settings);

View File

@ -18,7 +18,6 @@ import static org.shredzone.acme4j.toolbox.TestUtils.createProblem;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import org.junit.jupiter.api.Test;
@ -35,7 +34,7 @@ public class AcmeUserActionRequiredExceptionTest {
var type = URI.create("urn:ietf:params:acme:error:userActionRequired");
var detail = "Accept new TOS";
var tosUri = URI.create("http://example.com/agreement.pdf");
var instanceUrl = new URL("http://example.com/howToAgree.html");
var instanceUrl = URI.create("http://example.com/howToAgree.html").toURL();
var problem = createProblem(type, detail, instanceUrl);
@ -55,7 +54,7 @@ public class AcmeUserActionRequiredExceptionTest {
public void testNullAcmeUserActionRequiredException() throws MalformedURLException {
var type = URI.create("urn:ietf:params:acme:error:userActionRequired");
var detail = "Call our service";
var instanceUrl = new URL("http://example.com/howToContactUs.html");
var instanceUrl = URI.create("http://example.com/howToContactUs.html").toURL();
var problem = createProblem(type, detail, instanceUrl);

View File

@ -108,7 +108,7 @@ public class TestableConnectionProvider extends DummyConnection implements AcmeP
*/
public Login createLogin() throws IOException {
var session = createSession();
return session.login(new URL(TestUtils.ACCOUNT_URL), TestUtils.createKeyPair());
return session.login(URI.create(TestUtils.ACCOUNT_URL).toURL(), TestUtils.createKeyPair());
}
@Override

View File

@ -129,7 +129,7 @@ public final class TestUtils {
*/
public static Login login() {
try {
return session().login(new URL(ACCOUNT_URL), createKeyPair());
return session().login(URI.create(ACCOUNT_URL).toURL(), createKeyPair());
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
@ -145,7 +145,7 @@ public final class TestUtils {
*/
public static URL url(String url) {
try {
return new URL(url);
return URI.create(url).toURL();
} catch (MalformedURLException ex) {
throw new IllegalArgumentException(url, ex);
}

View File

@ -18,7 +18,6 @@ import static org.assertj.core.api.Assertions.assertThatNoException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.time.Duration;
import org.junit.jupiter.api.Disabled;
@ -45,14 +44,14 @@ public class ProviderIT {
@Test
public void testBuypass() throws AcmeException, MalformedURLException {
var session = new Session("acme://buypass.com");
assertThat(session.getMetadata().getWebsite()).hasValue(new URL("https://buypass.com/"));
assertThat(session.getMetadata().getWebsite()).hasValue(URI.create("https://buypass.com/").toURL());
assertThatNoException().isThrownBy(() -> session.resourceUrl(Resource.NEW_ACCOUNT));
assertThat(session.getMetadata().isExternalAccountRequired()).isFalse();
assertThat(session.getMetadata().isAutoRenewalEnabled()).isFalse();
assertThat(session.resourceUrlOptional(Resource.RENEWAL_INFO)).isNotEmpty();
var sessionStage = new Session("acme://buypass.com/staging");
assertThat(sessionStage.getMetadata().getWebsite()).hasValue(new URL("https://buypass.com/"));
assertThat(sessionStage.getMetadata().getWebsite()).hasValue(URI.create("https://buypass.com/").toURL());
assertThatNoException().isThrownBy(() -> sessionStage.resourceUrl(Resource.NEW_ACCOUNT));
assertThat(sessionStage.getMetadata().isExternalAccountRequired()).isFalse();
assertThat(sessionStage.getMetadata().isAutoRenewalEnabled()).isFalse();
@ -65,14 +64,14 @@ public class ProviderIT {
@Test
public void testGoogle() throws AcmeException, MalformedURLException {
var session = new Session("acme://pki.goog");
assertThat(session.getMetadata().getWebsite()).hasValue(new URL("https://pki.goog"));
assertThat(session.getMetadata().getWebsite()).hasValue(URI.create("https://pki.goog").toURL());
assertThatNoException().isThrownBy(() -> session.resourceUrl(Resource.NEW_ACCOUNT));
assertThat(session.getMetadata().isExternalAccountRequired()).isTrue();
assertThat(session.getMetadata().isAutoRenewalEnabled()).isFalse();
assertThat(session.resourceUrlOptional(Resource.RENEWAL_INFO)).isNotEmpty();
var sessionStage = new Session("acme://pki.goog/staging");
assertThat(sessionStage.getMetadata().getWebsite()).hasValue(new URL("https://pki.goog"));
assertThat(sessionStage.getMetadata().getWebsite()).hasValue(URI.create("https://pki.goog").toURL());
assertThatNoException().isThrownBy(() -> sessionStage.resourceUrl(Resource.NEW_ACCOUNT));
assertThat(sessionStage.getMetadata().isExternalAccountRequired()).isTrue();
assertThat(sessionStage.getMetadata().isAutoRenewalEnabled()).isFalse();
@ -85,14 +84,14 @@ public class ProviderIT {
@Test
public void testLetsEncrypt() throws AcmeException, MalformedURLException {
var session = new Session("acme://letsencrypt.org");
assertThat(session.getMetadata().getWebsite()).hasValue(new URL("https://letsencrypt.org"));
assertThat(session.getMetadata().getWebsite()).hasValue(URI.create("https://letsencrypt.org").toURL());
assertThatNoException().isThrownBy(() -> session.resourceUrl(Resource.NEW_ACCOUNT));
assertThat(session.getMetadata().isExternalAccountRequired()).isFalse();
assertThat(session.getMetadata().isAutoRenewalEnabled()).isFalse();
assertThat(session.resourceUrlOptional(Resource.RENEWAL_INFO)).isNotEmpty();
var sessionStage = new Session("acme://letsencrypt.org/staging");
assertThat(sessionStage.getMetadata().getWebsite()).hasValue(new URL("https://letsencrypt.org/docs/staging-environment/"));
assertThat(sessionStage.getMetadata().getWebsite()).hasValue(URI.create("https://letsencrypt.org/docs/staging-environment/").toURL());
assertThatNoException().isThrownBy(() -> sessionStage.resourceUrl(Resource.NEW_ACCOUNT));
assertThat(sessionStage.getMetadata().isExternalAccountRequired()).isFalse();
assertThat(sessionStage.getMetadata().isAutoRenewalEnabled()).isFalse();
@ -118,14 +117,14 @@ public class ProviderIT {
@Test
public void testSslCom() throws AcmeException, MalformedURLException {
var sessionEcc = new Session("acme://ssl.com/ecc");
assertThat(sessionEcc.getMetadata().getWebsite()).hasValue(new URL("https://www.ssl.com"));
assertThat(sessionEcc.getMetadata().getWebsite()).hasValue(URI.create("https://www.ssl.com").toURL());
assertThatNoException().isThrownBy(() -> sessionEcc.resourceUrl(Resource.NEW_ACCOUNT));
assertThat(sessionEcc.getMetadata().isExternalAccountRequired()).isTrue();
assertThat(sessionEcc.getMetadata().isAutoRenewalEnabled()).isFalse();
assertThat(sessionEcc.resourceUrlOptional(Resource.RENEWAL_INFO)).isEmpty();
var sessionRsa = new Session("acme://ssl.com/rsa");
assertThat(sessionRsa.getMetadata().getWebsite()).hasValue(new URL("https://www.ssl.com"));
assertThat(sessionRsa.getMetadata().getWebsite()).hasValue(URI.create("https://www.ssl.com").toURL());
assertThatNoException().isThrownBy(() -> sessionRsa.resourceUrl(Resource.NEW_ACCOUNT));
assertThat(sessionRsa.getMetadata().isExternalAccountRequired()).isTrue();
assertThat(sessionRsa.getMetadata().isAutoRenewalEnabled()).isFalse();
@ -144,14 +143,14 @@ public class ProviderIT {
@Disabled("Instable due to frequent certificate expiration of acme-try.ssl.com")
public void testSslComStaging() throws AcmeException, MalformedURLException {
var sessionEccStage = new Session("acme://ssl.com/staging/ecc");
assertThat(sessionEccStage.getMetadata().getWebsite()).hasValue(new URL("https://www.ssl.com"));
assertThat(sessionEccStage.getMetadata().getWebsite()).hasValue(URI.create("https://www.ssl.com").toURL());
assertThatNoException().isThrownBy(() -> sessionEccStage.resourceUrl(Resource.NEW_ACCOUNT));
assertThat(sessionEccStage.getMetadata().isExternalAccountRequired()).isTrue();
assertThat(sessionEccStage.getMetadata().isAutoRenewalEnabled()).isFalse();
assertThat(sessionEccStage.resourceUrlOptional(Resource.RENEWAL_INFO)).isEmpty();
var sessionRsaStage = new Session("acme://ssl.com/staging/rsa");
assertThat(sessionRsaStage.getMetadata().getWebsite()).hasValue(new URL("https://www.ssl.com"));
assertThat(sessionRsaStage.getMetadata().getWebsite()).hasValue(URI.create("https://www.ssl.com").toURL());
assertThatNoException().isThrownBy(() -> sessionRsaStage.resourceUrl(Resource.NEW_ACCOUNT));
assertThat(sessionRsaStage.getMetadata().isExternalAccountRequired()).isTrue();
assertThat(sessionRsaStage.getMetadata().isAutoRenewalEnabled()).isFalse();