diff --git a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/ApplicationDependencyModelResolver.java b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/ApplicationDependencyModelResolver.java index 8f1a10ad091088..1c375775268e31 100644 --- a/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/ApplicationDependencyModelResolver.java +++ b/independent-projects/bootstrap/maven-resolver/src/main/java/io/quarkus/bootstrap/resolver/maven/ApplicationDependencyModelResolver.java @@ -12,9 +12,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositoryException; -import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.*; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.collection.*; import org.eclipse.aether.graph.DefaultDependencyNode; @@ -27,6 +25,7 @@ import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector; import org.eclipse.aether.util.graph.transformer.ConflictIdSorter; import org.eclipse.aether.util.graph.transformer.ConflictMarker; +import org.eclipse.aether.util.listener.ChainedRepositoryListener; import org.jboss.logging.Logger; import io.quarkus.bootstrap.BootstrapConstants; @@ -71,6 +70,8 @@ public static Artifact getRuntimeArtifact(DependencyNode dep) { return (Artifact) dep.getData().get(QUARKUS_RUNTIME_ARTIFACT); } + private final ExtensionInfo EXT_INFO_NONE = new ExtensionInfo(); + private byte walkingFlags = COLLECT_TOP_EXTENSION_RUNTIME_NODES | COLLECT_DIRECT_DEPS; private final List topExtensionDeps = new ArrayList<>(); private ExtensionDependency lastVisitedRuntimeExtNode; @@ -136,6 +137,7 @@ public void resolve(CollectRequest collectRtDepsRequest) throws AppModelResolver final DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(originalSession); session.setDependencySelector( DeploymentDependencySelector.ensureDeploymentDependencySelector(session.getDependencySelector())); + //session.setRepositoryListener(repoListener); try { this.resolver = new MavenArtifactResolver(new BootstrapMavenContext(BootstrapMavenContext.config() .setRepositorySystem(resolver.getSystem()) @@ -153,9 +155,9 @@ public void resolve(CollectRequest collectRtDepsRequest) throws AppModelResolver var current = System.currentTimeMillis(); processDependencies(root); + //visitRuntimeDependencies(root.getChildren()); System.out.println("Process rt deps " + (System.currentTimeMillis() - current) + ", conditional deps " + conditionalDepsToProcess.size()); - //visitRuntimeDependencies(root.getChildren()); List activatedConditionalDeps = List.of(); @@ -170,12 +172,10 @@ public void resolve(CollectRequest collectRtDepsRequest) throws AppModelResolver final Iterator i = unsatisfiedConditionalDeps.iterator(); while (i.hasNext()) { final ConditionalDependency cd = i.next(); - final boolean satisfied = cd.isSatisfied(); - if (!satisfied) { + if (!cd.isSatisfied()) { continue; } i.remove(); - cd.activate(); activatedConditionalDeps.add(cd); } @@ -193,9 +193,7 @@ public void resolve(CollectRequest collectRtDepsRequest) throws AppModelResolver injectDeployment(activatedConditionalDeps); System.out.println("Deployment injection: " + (System.currentTimeMillis() - current)); - current = System.currentTimeMillis(); root = normalize(originalSession, root); - System.out.println("Normalize graph " + (System.currentTimeMillis() - current)); // add deployment dependencies current = System.currentTimeMillis(); new BuildDependencyGraphVisitor(originalResolver, appBuilder, buildTreeConsumer).visit(root); @@ -362,11 +360,15 @@ private DependencyNode normalize(RepositorySystemSession session, DependencyNode return root; } - private DependencyNode resolveRuntimeDeps(CollectRequest request) throws AppModelResolverException { + private DependencyNode resolveRuntimeDeps(CollectRequest request) + throws AppModelResolverException { var session = resolver.getSession(); + var repoListener = new ProcessingRepositoryListener(); if (!CONVERGED_TREE_ONLY && collectReloadableModules) { final DefaultRepositorySystemSession mutableSession; mutableSession = new DefaultRepositorySystemSession(resolver.getSession()); + mutableSession.setRepositoryListener( + ChainedRepositoryListener.newInstance(repoListener, resolver.getSession().getRepositoryListener())); mutableSession.setDependencyGraphTransformer(new DependencyGraphTransformer() { @Override @@ -401,6 +403,8 @@ private void walk(DependencyNode node, Map visit } catch (DependencyResolutionException e) { final Artifact a = request.getRoot() == null ? request.getRootArtifact() : request.getRoot().getArtifact(); throw new BootstrapMavenException("Failed to resolve dependencies for " + a, e); + } finally { + CompletableFuture.allOf(repoListener.futures.toArray(new CompletableFuture[0])).join(); } } @@ -754,9 +758,9 @@ private ExtensionInfo getExtensionInfoOrNull(Artifact artifact, List { @@ -769,10 +773,12 @@ private ExtensionInfo getExtensionInfoOrNull(Artifact artifact, List exclusions, List repos) { + try { + return resolver.getSystem() + .collectDependencies(resolver.getSession(), getCollectRequest(artifact, exclusions, repos)).getRoot(); + } catch (DependencyCollectionException e) { + throw new DeploymentInjectionException("Failed to collect dependencies for " + artifact, e); + } + } + + private CollectRequest getCollectRequest(Artifact artifact, Collection exclusions, + List repos) { final CollectRequest request; if (managedDeps.isEmpty()) { request = new CollectRequest() @@ -914,11 +930,7 @@ private DependencyNode collectDependencies(Artifact artifact, Collection repos) { @@ -959,6 +971,7 @@ private static Properties readDescriptor(Path path) throws IOException { } private class ExtensionInfo { + final Artifact runtimeArtifact; final Properties props; final Artifact deploymentArtifact; @@ -966,6 +979,14 @@ private class ExtensionInfo { final ArtifactKey[] dependencyCondition; boolean activated; + private ExtensionInfo() { + runtimeArtifact = null; + props = null; + deploymentArtifact = null; + conditionalDeps = null; + dependencyCondition = null; + } + ExtensionInfo(Artifact runtimeArtifact, Properties props) throws BootstrapDependencyProcessingException { this.runtimeArtifact = runtimeArtifact; this.props = props; @@ -1132,4 +1153,42 @@ private static String toCompactCoords(Artifact a) { b.append(a.getVersion()); return b.toString(); } + + private class ProcessingRepositoryListener extends AbstractRepositoryListener { + + final List> futures = new ArrayList<>(); + + private ProcessingRepositoryListener() { + } + + @Override + public void artifactResolved(RepositoryEvent repositoryEvent) { + if (ArtifactCoords.TYPE_JAR.equals(repositoryEvent.getArtifact().getExtension())) { + futures.add(CompletableFuture.runAsync(() -> { + final Properties descriptor = PathTree.ofDirectoryOrArchive(repositoryEvent.getFile().toPath()) + .apply(BootstrapConstants.DESCRIPTOR_PATH, visit -> { + if (visit == null) { + return null; + } + try { + return readDescriptor(visit.getPath()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + }); + var artifact = repositoryEvent.getArtifact(); + var key = getKey(artifact); + if (descriptor != null) { + try { + allExtensions.put(key, new ExtensionInfo(artifact, descriptor)); + } catch (BootstrapDependencyProcessingException e) { + throw new RuntimeException(e); + } + } else { + allExtensions.put(key, EXT_INFO_NONE); + } + })); + } + } + } }