diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporterCustomizer.java b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporterCustomizer.java deleted file mode 100644 index 7695d0e72..000000000 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporterCustomizer.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.eclipse.aether.transport.jdk; - -import java.net.http.HttpClient; - -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.repository.RemoteRepository; - -/** - * JDK Transport customizer. - * - * @since TBD - */ -final class JdkHttpTransporterCustomizer { - private JdkHttpTransporterCustomizer() {} - - static void customizeBuilder( - RepositorySystemSession session, RemoteRepository repository, HttpClient.Builder builder) {} - - static void customizeHttpClient(RepositorySystemSession session, RemoteRepository repository, HttpClient client) {} -} diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-19/pom.xml b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-19/pom.xml deleted file mode 100644 index 423aff856..000000000 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-19/pom.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - 4.0.0 - - - org.apache.maven.resolver - maven-resolver-transport-jdk-parent - 2.0.0-SNAPSHOT - - - maven-resolver-transport-jdk-19 - jar - - Maven Artifact Resolver Transport JDK (19) - Maven Artifact Transport JDK Java 11+. - - - org.apache.maven.resolver.transport.jdk - ${Automatic-Module-Name} - - 19 - - true - true - - - - - org.slf4j - slf4j-api - - - org.apache.maven.resolver - maven-resolver-api - - - org.apache.maven.resolver - maven-resolver-spi - - - org.apache.maven.resolver - maven-resolver-util - - - javax.inject - javax.inject - provided - true - - - - - - - org.eclipse.sisu - sisu-maven-plugin - - - biz.aQute.bnd - bnd-maven-plugin - - - org.apache.maven.plugins - maven-jar-plugin - - - ${project.build.outputDirectory}/META-INF/MANIFEST.MF - - - - - - - diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-19/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporterCustomizer.java b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-19/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporterCustomizer.java deleted file mode 100644 index 63929635c..000000000 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-19/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporterCustomizer.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.eclipse.aether.transport.jdk; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.net.http.HttpClient; - -import org.eclipse.aether.ConfigurationProperties; -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.repository.RemoteRepository; -import org.eclipse.aether.util.ConfigUtils; - -/** - * JDK Transport customizer. - * - * @since TBD - */ -final class JdkHttpTransporterCustomizer { - private JdkHttpTransporterCustomizer() {} - - static void customizeBuilder( - RepositorySystemSession session, RemoteRepository repository, HttpClient.Builder builder) { - InetAddress localAddress = getHttpLocalAddress(session, repository); - if (localAddress != null) { - builder.localAddress(localAddress); - } - } - - static void customizeHttpClient(RepositorySystemSession session, RemoteRepository repository, HttpClient client) {} - - /** - * Returns non-null {@link InetAddress} if set in configuration, {@code null} otherwise. - */ - private static InetAddress getHttpLocalAddress(RepositorySystemSession session, RemoteRepository repository) { - String bindAddress = ConfigUtils.getString( - session, - null, - ConfigurationProperties.HTTP_LOCAL_ADDRESS + "." + repository.getId(), - ConfigurationProperties.HTTP_LOCAL_ADDRESS); - if (bindAddress == null) { - return null; - } - try { - return InetAddress.getByName(bindAddress); - } catch (UnknownHostException uhe) { - throw new IllegalArgumentException( - "Given bind address (" + bindAddress + ") cannot be resolved for remote repository " + repository, - uhe); - } - } -} diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-21/pom.xml b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-21/pom.xml deleted file mode 100644 index f71b38e2f..000000000 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-21/pom.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - 4.0.0 - - - org.apache.maven.resolver - maven-resolver-transport-jdk-parent - 2.0.0-SNAPSHOT - - - maven-resolver-transport-jdk-21 - jar - - Maven Artifact Resolver Transport JDK (21) - Maven Artifact Transport JDK Java 11+. - - - org.apache.maven.resolver.transport.jdk - ${Automatic-Module-Name} - - 21 - - true - true - - - - - org.slf4j - slf4j-api - - - org.apache.maven.resolver - maven-resolver-api - - - org.apache.maven.resolver - maven-resolver-spi - - - org.apache.maven.resolver - maven-resolver-util - - - javax.inject - javax.inject - provided - true - - - - - - - org.eclipse.sisu - sisu-maven-plugin - - - biz.aQute.bnd - bnd-maven-plugin - - - org.apache.maven.plugins - maven-jar-plugin - - - ${project.build.outputDirectory}/META-INF/MANIFEST.MF - - - - - - - diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-21/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporterCustomizer.java b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-21/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporterCustomizer.java deleted file mode 100644 index 4dd30d8c2..000000000 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-21/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporterCustomizer.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.eclipse.aether.transport.jdk; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.net.http.HttpClient; - -import org.eclipse.aether.ConfigurationProperties; -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.repository.RemoteRepository; -import org.eclipse.aether.util.ConfigUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * JDK Transport customizer. - * - * @since TBD - */ -final class JdkHttpTransporterCustomizer { - private static final Logger LOGGER = LoggerFactory.getLogger(JdkHttpTransporterCustomizer.class); - - private JdkHttpTransporterCustomizer() {} - - static void customizeBuilder( - RepositorySystemSession session, RemoteRepository repository, HttpClient.Builder builder) { - InetAddress localAddress = getHttpLocalAddress(session, repository); - if (localAddress != null) { - builder.localAddress(localAddress); - } - } - - static void customizeHttpClient(RepositorySystemSession session, RemoteRepository repository, HttpClient client) { - if (!session.addOnSessionEndedHandler(client::close)) { - LOGGER.warn("Using Resolver 2 feature without Resolver 2 session handling, you may leak resources."); - } - } - - /** - * Returns non-null {@link InetAddress} if set in configuration, {@code null} otherwise. - */ - private static InetAddress getHttpLocalAddress(RepositorySystemSession session, RemoteRepository repository) { - String bindAddress = ConfigUtils.getString( - session, - null, - ConfigurationProperties.HTTP_LOCAL_ADDRESS + "." + repository.getId(), - ConfigurationProperties.HTTP_LOCAL_ADDRESS); - if (bindAddress == null) { - return null; - } - try { - return InetAddress.getByName(bindAddress); - } catch (UnknownHostException uhe) { - throw new IllegalArgumentException( - "Given bind address (" + bindAddress + ") cannot be resolved for remote repository " + repository, - uhe); - } - } -} diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-8/pom.xml b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-8/pom.xml deleted file mode 100644 index ab221e91c..000000000 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-8/pom.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - - 4.0.0 - - - org.apache.maven.resolver - maven-resolver-transport-jdk-parent - 2.0.0-SNAPSHOT - - - maven-resolver-transport-jdk-8 - jar - - Maven Artifact Resolver Transport JDK (8) - Maven Artifact Transport JDK Java 11+. - - - org.apache.maven.resolver.transport.jdk - ${Automatic-Module-Name} - - - - - org.slf4j - slf4j-api - - - org.apache.maven.resolver - maven-resolver-api - - - org.apache.maven.resolver - maven-resolver-spi - - - org.apache.maven.resolver - maven-resolver-util - - - javax.inject - javax.inject - provided - true - - - - - - - org.eclipse.sisu - sisu-maven-plugin - - - biz.aQute.bnd - bnd-maven-plugin - - - org.apache.maven.plugins - maven-jar-plugin - - - ${project.build.outputDirectory}/META-INF/MANIFEST.MF - - - - - - - diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-8/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporterFactory.java b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-8/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporterFactory.java deleted file mode 100644 index 81b8c34f9..000000000 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-8/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporterFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.eclipse.aether.transport.jdk; - -import javax.inject.Named; - -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.repository.RemoteRepository; -import org.eclipse.aether.spi.connector.transport.Transporter; -import org.eclipse.aether.spi.connector.transport.TransporterFactory; -import org.eclipse.aether.transfer.NoTransporterException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static java.util.Objects.requireNonNull; - -/** - * JDK Transport factory: on Java 8 is no-op. - * - * @since TBD - */ -@Named(JdkTransporterFactory.NAME) -public final class JdkTransporterFactory implements TransporterFactory { - public static final String NAME = "jdk"; - - private static final Logger LOGGER = LoggerFactory.getLogger(JdkTransporterFactory.class); - - private float priority = Float.MIN_VALUE; - - @Override - public float getPriority() { - return priority; - } - - public JdkTransporterFactory setPriority(float priority) { - this.priority = priority; - return this; - } - - @Override - public Transporter newInstance(RepositorySystemSession session, RemoteRepository repository) - throws NoTransporterException { - requireNonNull(session, "session cannot be null"); - requireNonNull(repository, "repository cannot be null"); - - LOGGER.debug("Needs Java11+ to function"); - throw new NoTransporterException(repository, "JDK Transport needs Java11+"); - } -} diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk/pom.xml b/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk/pom.xml deleted file mode 100644 index 3d66c1636..000000000 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk/pom.xml +++ /dev/null @@ -1,212 +0,0 @@ - - - - 4.0.0 - - - org.apache.maven.resolver - maven-resolver-transport-jdk-parent - 2.0.0-SNAPSHOT - - - maven-resolver-transport-jdk - jar - - Maven Artifact Resolver Transport JDK (mr) - Maven Artifact Transport JDK Java 11+. - - - org.apache.maven.resolver.transport.jdk - ${Automatic-Module-Name} - - - - - - org.apache.maven.resolver - maven-resolver-transport-jdk-8 - ${project.version} - true - - - org.apache.maven.resolver - maven-resolver-transport-jdk-11 - ${project.version} - true - - - org.apache.maven.resolver - maven-resolver-transport-jdk-19 - ${project.version} - true - - - org.apache.maven.resolver - maven-resolver-transport-jdk-21 - ${project.version} - true - - - - - org.slf4j - slf4j-api - - - org.apache.maven.resolver - maven-resolver-api - - - org.apache.maven.resolver - maven-resolver-spi - - - org.apache.maven.resolver - maven-resolver-util - - - javax.inject - javax.inject - provided - true - - - - - - - false - ${project.build.directory}/generated-resources - - - - - org.apache.maven.plugins - maven-enforcer-plugin - - - enforce-bytecode-version - - enforce - - - true - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - java8 - - unpack - - generate-resources - - - - org.apache.maven.resolver - maven-resolver-transport-jdk-8 - ${project.version} - jar - ${project.build.directory}/generated-resources - META-INF/maven/** - - - - - - java11 - - unpack - - generate-resources - - - - org.apache.maven.resolver - maven-resolver-transport-jdk-11 - ${project.version} - jar - ${project.build.directory}/generated-resources/META-INF/versions/11 - **/*.class - - - - - - java19 - - unpack - - generate-resources - - - - org.apache.maven.resolver - maven-resolver-transport-jdk-19 - ${project.version} - jar - ${project.build.directory}/generated-resources/META-INF/versions/19 - **/*.class - - - - - - java21 - - unpack - - generate-resources - - - - org.apache.maven.resolver - maven-resolver-transport-jdk-21 - ${project.version} - jar - ${project.build.directory}/generated-resources/META-INF/versions/21 - **/*.class - - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - ${project.build.outputDirectory}/META-INF/MANIFEST.MF - - true - - - - - - - - diff --git a/maven-resolver-transport-jdk-parent/pom.xml b/maven-resolver-transport-jdk-parent/pom.xml deleted file mode 100644 index 78a507866..000000000 --- a/maven-resolver-transport-jdk-parent/pom.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - 4.0.0 - - - org.apache.maven.resolver - maven-resolver - 2.0.0-SNAPSHOT - - - maven-resolver-transport-jdk-parent - pom - - Maven Artifact Resolver Transport JDK (parent) - Maven Artifact Transport JDK Java 11+. - - - maven-resolver-transport-jdk-8 - maven-resolver-transport-jdk-11 - maven-resolver-transport-jdk-19 - maven-resolver-transport-jdk-21 - maven-resolver-transport-jdk - - - diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/pom.xml b/maven-resolver-transport-jdk/pom.xml similarity index 72% rename from maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/pom.xml rename to maven-resolver-transport-jdk/pom.xml index 49e2bcf47..ed1827e9a 100644 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/pom.xml +++ b/maven-resolver-transport-jdk/pom.xml @@ -22,20 +22,21 @@ org.apache.maven.resolver - maven-resolver-transport-jdk-parent + maven-resolver 2.0.0-SNAPSHOT - maven-resolver-transport-jdk-11 + maven-resolver-transport-jdk jar - Maven Artifact Resolver Transport JDK (11) + Maven Artifact Resolver Transport JDK Maven Artifact Transport JDK Java 11+. org.apache.maven.resolver.transport.jdk ${Automatic-Module-Name} + 11 @@ -83,7 +84,34 @@ + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + + force-java8-spi + + compile + + compile + + 8 + **/JdkTransporterFactory.java + + + + default-compile + + compile + + compile + + **/JdkTransporterFactory.java + + + + - diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpException.java b/maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpException.java similarity index 100% rename from maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpException.java rename to maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpException.java diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporter.java b/maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporter.java similarity index 84% rename from maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporter.java rename to maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporter.java index bb2f97ea6..26f91d293 100644 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporter.java +++ b/maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/JdkHttpTransporter.java @@ -23,12 +23,16 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.Authenticator; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.PasswordAuthentication; import java.net.ProxySelector; import java.net.URI; import java.net.URISyntaxException; +import java.net.UnknownHostException; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; @@ -46,6 +50,7 @@ import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -61,6 +66,7 @@ import org.eclipse.aether.transfer.NoTransporterException; import org.eclipse.aether.util.ConfigUtils; import org.eclipse.aether.util.FileUtils; +import org.slf4j.LoggerFactory; /** * JDK Transport using {@link HttpClient}. @@ -68,6 +74,10 @@ * @since TBD */ final class JdkHttpTransporter extends AbstractTransporter { + private static final DateTimeFormatter RFC7231 = DateTimeFormatter.ofPattern( + "EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH) + .withZone(ZoneId.of("GMT")); + private static final int MULTIPLE_CHOICES = 300; private static final int NOT_FOUND = 404; @@ -305,10 +315,10 @@ protected void implPut(PutTask task) throws Exception { @Override protected void implClose() { - // nop + // no-op } - private static Map extractXChecksums(HttpResponse response) { + private Map extractXChecksums(HttpResponse response) { String value; HashMap result = new HashMap<>(); // Central style: x-checksum-sha1: c74edb60ca2a0b57ef88d9a7da28f591e3d4ce7b @@ -338,7 +348,7 @@ private static Map extractXChecksums(HttpResponse response) { return result.isEmpty() ? null : result; } - private static Map extractNexus2Checksums(HttpResponse response) { + private Map extractNexus2Checksums(HttpResponse response) { // Nexus-style, ETag: "{SHA1{d40d68ba1f88d8e9b0040f175a6ff41928abd5e7}}" String etag = response.headers().firstValue("ETag").orElse(null); if (etag != null) { @@ -350,19 +360,36 @@ private static Map extractNexus2Checksums(HttpResponse respon return null; } - private static final DateTimeFormatter RFC7231 = DateTimeFormatter.ofPattern( - "EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH) - .withZone(ZoneId.of("GMT")); + private InetAddress getHttpLocalAddress(RepositorySystemSession session, RemoteRepository repository) { + String bindAddress = ConfigUtils.getString( + session, + null, + ConfigurationProperties.HTTP_LOCAL_ADDRESS + "." + repository.getId(), + ConfigurationProperties.HTTP_LOCAL_ADDRESS); + if (bindAddress == null) { + return null; + } + try { + return InetAddress.getByName(bindAddress); + } catch (UnknownHostException uhe) { + throw new IllegalArgumentException( + "Given bind address (" + bindAddress + ") cannot be resolved for remote repository " + repository, + uhe); + } + } /** * Visible for testing. */ static final String HTTP_INSTANCE_KEY_PREFIX = JdkTransporterFactory.class.getName() + ".http."; - private static HttpClient getOrCreateClient(RepositorySystemSession session, RemoteRepository repository) + private HttpClient getOrCreateClient(RepositorySystemSession session, RemoteRepository repository) throws NoTransporterException { final String instanceKey = HTTP_INSTANCE_KEY_PREFIX + repository.getId(); + // todo: normally a single client per JVM is sufficient - in particular cause part of the config + // is global and not per instance so we should create a client only when conf changes for a repo + // else fallback on a global client try { return (HttpClient) session.getData().computeIfAbsent(instanceKey, () -> { HashMap authentications = new HashMap<>(); @@ -393,12 +420,16 @@ private static HttpClient getOrCreateClient(RepositorySystemSession session, Rem ConfigurationProperties.CONNECT_TIMEOUT); HttpClient.Builder builder = HttpClient.newBuilder() - .version(HttpClient.Version.HTTP_2) + .version(HttpClient.Version.valueOf(ConfigUtils.getString( + session, + "HTTP_1_1", // v2 is not safe yet in the wild + "http.version." + repository.getId(), + "http.version"))) .followRedirects(HttpClient.Redirect.NORMAL) .connectTimeout(Duration.ofMillis(connectTimeout)) .sslContext(sslContext); - JdkHttpTransporterCustomizer.customizeBuilder(session, repository, builder); + setLocalAddress(builder, () -> getHttpLocalAddress(session, repository)); if (repository.getProxy() != null) { ProxySelector proxy = ProxySelector.of(new InetSocketAddress( @@ -429,7 +460,20 @@ protected PasswordAuthentication getPasswordAuthentication() { } HttpClient result = builder.build(); - JdkHttpTransporterCustomizer.customizeHttpClient(session, repository, result); + if (!session.addOnSessionEndedHandler(() -> { + if (result instanceof AutoCloseable) { + try { + ((AutoCloseable) client).close(); + } catch (final Exception e) { + throw new IllegalStateException(e); + } + } + })) { + LoggerFactory.getLogger(JdkHttpTransporter.class) + .warn( + "Using Resolver 2 feature without Resolver 2 session handling, you may leak resources."); + } + return result; } catch (NoSuchAlgorithmException e) { throw new WrapperEx(e); @@ -440,6 +484,27 @@ protected PasswordAuthentication getPasswordAuthentication() { } } + private void setLocalAddress(HttpClient.Builder builder, Supplier addressSupplier) { + try { + final InetAddress address = addressSupplier.get(); + if (address == null) { + return; + } + + final Method mtd = builder.getClass().getDeclaredMethod("localAddress", InetAddress.class); + if (!mtd.canAccess(builder)) { + mtd.setAccessible(true); + } + mtd.invoke(builder, address); + } catch (final NoSuchMethodException nsme) { + // skip, not yet in the API + } catch (InvocationTargetException e) { + throw new IllegalStateException(e.getTargetException()); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } + } + private static final class WrapperEx extends RuntimeException { private WrapperEx(Throwable cause) { super(cause); diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporterFactory.java b/maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporterFactory.java similarity index 72% rename from maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporterFactory.java rename to maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporterFactory.java index ef076f038..9328d8b01 100644 --- a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporterFactory.java +++ b/maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporterFactory.java @@ -25,6 +25,7 @@ import org.eclipse.aether.spi.connector.transport.Transporter; import org.eclipse.aether.spi.connector.transport.TransporterFactory; import org.eclipse.aether.transfer.NoTransporterException; +import org.slf4j.LoggerFactory; import static java.util.Objects.requireNonNull; @@ -55,10 +56,28 @@ public Transporter newInstance(RepositorySystemSession session, RemoteRepository requireNonNull(session, "session cannot be null"); requireNonNull(repository, "repository cannot be null"); + if (javaVersion() < 11) { + LoggerFactory.getLogger(JdkTransporterFactory.class).debug("Needs Java11+ to function"); + throw new NoTransporterException(repository, "JDK Transport needs Java11+"); + } + if (!"http".equalsIgnoreCase(repository.getProtocol()) && !"https".equalsIgnoreCase(repository.getProtocol())) { throw new NoTransporterException(repository, "Only HTTP/HTTPS is supported"); } return new JdkHttpTransporter(session, repository); } + + // simple heuristic + private int javaVersion() { + try { + final String version = System.getProperty("java.version", "11" /* default must pass */); + final int dot = version.indexOf('.'); + final int iphen = version.indexOf('-'); + final int sep = (dot > 0 && dot < iphen || iphen < 0) ? dot : iphen; + return Integer.parseInt(sep > 0 ? version.substring(0, sep) : version); + } catch (final NumberFormatException nfe) { + return 11; // unlikely to be a pre-java 11 version so let it pass + } + } } diff --git a/maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/src/main/java/org/eclipse/aether/transport/jdk/package-info.java b/maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/package-info.java similarity index 100% rename from maven-resolver-transport-jdk-parent/maven-resolver-transport-jdk-11/src/main/java/org/eclipse/aether/transport/jdk/package-info.java rename to maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/package-info.java diff --git a/pom.xml b/pom.xml index acc127854..1d409b764 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ maven-resolver-transport-classpath maven-resolver-transport-file maven-resolver-transport-jetty - maven-resolver-transport-jdk-parent + maven-resolver-transport-jdk maven-resolver-transport-http maven-resolver-transport-wagon maven-resolver-supplier @@ -101,7 +101,7 @@ 4.0.0-alpha-8 [3.8.8,) - [21,) + [11,) 2023-11-15T14:56:04Z