Skip to content

Commit

Permalink
fixes StackOverflow in maven dependency resolution
Browse files Browse the repository at this point in the history
fixes #6147

Signed-off-by: Juergen Albert <[email protected]>
  • Loading branch information
juergen-albert committed Aug 7, 2024
1 parent 035bab9 commit 037ffab
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -297,38 +300,60 @@ private List<RemoteRepository> getProjectRemoteRepositories() {
private void discoverArtifacts(Map<File, ArtifactResult> files, List<DependencyNode> nodes, String parent,
List<RemoteRepository> remoteRepositories) throws MojoExecutionException {

for (DependencyNode node : nodes) {
List<RemoteRepository> combinedRepositories = new ArrayList<>(remoteRepositories);
combinedRepositories.addAll(node.getRepositories());

// Ensure that the file is downloaded so we can index it
try {
ArtifactResult resolvedArtifact = postProcessor.postProcessResult(system.resolveArtifact(session,
new ArtifactRequest(node.getArtifact(), combinedRepositories, parent)));
logger.debug("Located file: {} for artifact {}", resolvedArtifact.getArtifact()
.getFile(), resolvedArtifact);

// Add artifact only if the scope of this artifact matches and
// if
// we don't already have another version (earlier means higher
// precedence regardless of version)
if (scopes.contains(node.getDependency()
.getScope()) && containsExactVersion.negate()
.test(resolvedArtifact, files.values())
) {
files.put(resolvedArtifact.getArtifact()
List<RemoteRepository> combinedRepositories = new ArrayList<>(remoteRepositories);
Queue<DependencyNode> processQueue = new LinkedList<>(nodes);
Set<String> visited = new HashSet<>();
DependencyNode node = processQueue.poll();
long nodesChecked = 0;
long nodesSkipped = 0;
long nodesFailed = 0;
while (node != null) {
String nodeString = node.toString();
if (!visited.contains(nodeString)) {
nodesChecked++;
combinedRepositories.addAll(node.getRepositories());

// Ensure that the file is downloaded so we can index it
try {
ArtifactResult resolvedArtifact = postProcessor.postProcessResult(system.resolveArtifact(session,
new ArtifactRequest(node.getArtifact(), combinedRepositories, node.getRequestContext())));
logger.debug("Located file: {} for artifact {}", resolvedArtifact.getArtifact()
.getFile(), resolvedArtifact);

// Add artifact only if the scope of this artifact matches
// and
// if
// we don't already have another version (earlier means
// higher
// precedence regardless of version)
if (scopes.contains(node.getDependency()
.getScope()) && containsExactVersion.negate()
.test(resolvedArtifact, files.values())) {
files.put(resolvedArtifact.getArtifact()
.getFile(), resolvedArtifact);
}
} catch (ArtifactResolutionException e) {
nodesFailed++;
logger.warn("Failed to resolve dependency {}", node.getArtifact());
}
} catch (ArtifactResolutionException e) {
logger.warn("Failed to resolve dependency {}", node.getArtifact());
}

if (includeTransitive) {
discoverArtifacts(files, node.getChildren(), node.getRequestContext(), combinedRepositories);
if (includeTransitive) {
processQueue.addAll(node.getChildren());
// discoverArtifacts(files, , node.getRequestContext(),
// combinedRepositories);
} else {
logger.debug("Ignoring transitive dependencies of {}", node.getDependency());
}
visited.add(nodeString);
} else {
logger.debug("Ignoring transitive dependencies of {}", node.getDependency());
nodesSkipped++;
}
node = processQueue.poll();
}

logger.info(
"Resolved all Dependencies for {}. Checked: {}, Skipped(no need to revisit): {}, Failed: {}, Resulting Dependencies: {}",
parent, nodesChecked, nodesSkipped, nodesFailed, files.size());
}

@SuppressWarnings("deprecation")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
invoker.goals=--no-transfer-progress package

# Run mvn with --debug for debug logging
#invoker.debug=true

# Run mvn in debugging mode and wait for a debugger to attach
#invoker.environmentVariables.MAVEN_DEBUG_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8000
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.2</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>

<artifactId>resolve-from-dependencies</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-maven-plugin</artifactId>
<version>${bnd.version}</version>
</plugin>
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-resolver-maven-plugin</artifactId>
<version>${bnd.version}</version>
<configuration>
<failOnChanges>false</failOnChanges>
<!-- Default to including *.bndrun <bndruns>
<bndrun>test.bndrun</bndrun>
</bndruns> -->
<includeDependencyManagement>true</includeDependencyManagement>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>resolve</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import aQute.bnd.build.Workspace
import aQute.bnd.build.model.BndEditModel
import aQute.bnd.osgi.Processor
import aQute.bnd.properties.Document
import aQute.lib.io.IO;

// The resolve-from-dependencies case

// Check the bndrun file exist!
File bndrunFile = new File(basedir, 'test.bndrun')
assert bndrunFile.isFile()

// Load the BndEditModel of the bndrun file so we can inspect the result
Processor processor = new Processor()
processor.setProperties(bndrunFile)
BndEditModel bem = new BndEditModel(Workspace.createStandaloneWorkspace(processor, bndrunFile.toURI()))
Document doc = new Document(IO.collect(bndrunFile))
bem.loadFrom(doc)

// Get the -runbundles.
def bemRunBundles = bem.getRunBundles()
assert bemRunBundles
assert bemRunBundles.size() > 0

StringBuilder sb = new StringBuilder()
bemRunBundles.get(0).formatTo(sb)
assert sb.toString().startsWith("org.freemarker.freemarker")
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-runfw: org.apache.felix.framework
-runrequires: osgi.identity;filter:='(osgi.identity=org.freemarker.freemarker)'

0 comments on commit 037ffab

Please sign in to comment.