Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,11 @@ public ArtifactVersions lookupArtifactVersions(
.map(v -> ArtifactVersionService.getArtifactVersion(v.toString()))
.collect(Collectors.toList()));
} catch (VersionRangeResolutionException e) {
throw new VersionRetrievalException(e.getMessage(), e);
throw new VersionRetrievalException(e.getMessage(), artifact, e);
} catch (RuntimeException e) {
// log the dependency should any runtime exception occur (e.x. broken comparison contract)
throw new VersionRetrievalException(
"Unable to retrieve versions for " + artifact + " for version range " + versionRange, artifact, e);
}
}

Expand Down Expand Up @@ -266,9 +270,12 @@ public Map<Dependency, ArtifactVersions> lookupDependenciesUpdates(
}

return dependencyUpdates;
} catch (ExecutionException | InterruptedException ie) {
} catch (ExecutionException | InterruptedException e) {
if (e.getCause() instanceof VersionRetrievalException) {
throw (VersionRetrievalException) e.getCause();
}
throw new VersionRetrievalException(
"Unable to acquire metadata for dependencies " + dependencies + ": " + ie.getMessage(), ie);
"Unable to acquire metadata for dependencies " + dependencies + ": " + e.getMessage(), null, e);
} finally {
executor.shutdown();
}
Expand Down Expand Up @@ -310,9 +317,12 @@ public Map<Plugin, PluginUpdatesDetails> lookupPluginsUpdates(Stream<Plugin> plu
}

return pluginUpdates;
} catch (ExecutionException | InterruptedException ie) {
} catch (ExecutionException | InterruptedException e) {
if (e.getCause() instanceof VersionRetrievalException) {
throw (VersionRetrievalException) e.getCause();
}
throw new VersionRetrievalException(
"Unable to acquire metadata for plugins " + plugins + ": " + ie.getMessage(), ie);
"Unable to acquire metadata for plugins " + plugins + ": " + e.getMessage(), null, e);
} finally {
executor.shutdown();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,40 @@
* under the License.
*/

import java.util.Optional;

import org.apache.maven.artifact.Artifact;

/**
* Exception thrown if version information cannot be retrieved
*/
public class VersionRetrievalException extends Exception {

private final Artifact artifact;

/**
* Constructs a new exception with {@code null} as its detail message.
* The cause is not initialized, and may subsequently be initialized by a
* call to {@link #initCause}.
*
* @param artifact {@link Artifact} instance causing the problem
*/
public VersionRetrievalException() {
super();
public VersionRetrievalException(Artifact artifact) {
this(null, artifact);
}

/**
* Constructs a new exception with the specified detail message. The
* cause is not initialized, and may subsequently be initialized by
* a call to {@link #initCause}.
*
* @param artifact {@link Artifact} instance causing the problem
* @param message the detail message. The detail message is saved for
* later retrieval by the {@link #getMessage()} method.
*/
public VersionRetrievalException(String message) {
public VersionRetrievalException(String message, Artifact artifact) {
super(message);
this.artifact = artifact;
}

/**
Expand All @@ -52,13 +63,14 @@ public VersionRetrievalException(String message) {
* wrappers for other throwables (for example, {@link
* java.security.PrivilegedActionException}).
*
* @param artifact {@link Artifact} instance causing the problem
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
*/
public VersionRetrievalException(Throwable cause) {
super(cause);
public VersionRetrievalException(Artifact artifact, Throwable cause) {
this(null, artifact, cause);
}

/**
Expand All @@ -69,12 +81,22 @@ public VersionRetrievalException(Throwable cause) {
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param artifact {@link Artifact} instance causing the problem
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or
* unknown.)
*/
public VersionRetrievalException(String message, Throwable cause) {
public VersionRetrievalException(String message, Artifact artifact, Throwable cause) {
super(message, cause);
this.artifact = artifact;
}

/**
* Returns the artifact causing the problem with version retrieval, if available
* @return {@link Optional} object containing artifact causing the problem with version retrieval, or empty
*/
public Optional<Artifact> getArtifact() {
return Optional.ofNullable(artifact);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,19 +113,15 @@ public static Set<Dependency> extractDependenciesFromDependencyManagement(
.orElse(Stream.empty()));

// log and try to correct versions where they don't appear in the original pom.xml
try {
return dependencies
.peek(dependency -> log.debug("dependency from pom: "
+ dependency.getGroupId() + ":" + dependency.getArtifactId() + ":" + dependency.getVersion()
+ ":" + dependency.getScope()))
.map(dependency -> dependency.getVersion() != null
? interpolateVersion(dependency, project)
: getVersionFromParent(dependency, project, processDependencyManagementTransitive, log)
.orElse(dependency))
.collect(() -> new TreeSet<>(DependencyComparator.INSTANCE), Set::add, Set::addAll);
} catch (IllegalArgumentException e) {
throw new VersionRetrievalException(e.getMessage());
}
return dependencies
.peek(dependency -> log.debug("dependency from pom: "
+ dependency.getGroupId() + ":" + dependency.getArtifactId() + ":" + dependency.getVersion()
+ ":" + dependency.getScope()))
.map(dependency -> dependency.getVersion() != null
? interpolateVersion(dependency, project)
: getVersionFromParent(dependency, project, processDependencyManagementTransitive, log)
.orElse(dependency))
.collect(() -> new TreeSet<>(DependencyComparator.INSTANCE), Set::add, Set::addAll);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
* Unit tests for {@link BoundArtifactVersion}
*/
class BoundArtifactVersionTest {

@Test
void testMajorUpperBoundGreaterThanNextMajor() {
BoundArtifactVersion bound = new BoundArtifactVersion("1.2.3", MAJOR);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,17 +197,17 @@ protected void doGenerateReport(Locale locale, Sink sink) throws MavenReportExce

renderReport(locale, sink, model);
} catch (VersionRetrievalException e) {
throw new RuntimeException(e);
throw new MavenReportException(e.getMessage(), e);
}
}

protected void handleDependencyManagementTransitive(
MavenProject project, Set<Dependency> dependencyManagementCollector) {
MavenProject project, Set<Dependency> dependencyManagementCollector) throws MavenReportException {
try {
dependencyManagementCollector.addAll(MavenProjectUtils.extractDependenciesFromDependencyManagement(
project, processDependencyManagementTransitive, getLog()));
} catch (VersionRetrievalException e) {
throw new RuntimeException(e);
throw new MavenReportException(e.getMessage(), e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.wagon.Wagon;
import org.codehaus.mojo.versions.reporting.ReportRendererFactory;
import org.codehaus.mojo.versions.reporting.util.AggregateReportUtils;
Expand Down Expand Up @@ -70,7 +71,8 @@ protected void populateDependencies(Set<Dependency> dependenciesCollector) {
* {@inheritDoc}
* */
@Override
protected void populateDependencyManagement(Set<Dependency> dependencyManagementCollector) {
protected void populateDependencyManagement(Set<Dependency> dependencyManagementCollector)
throws MavenReportException {
for (MavenProject project : AggregateReportUtils.getProjectsToProcess(getProject())) {
getLog().debug(String.format("Collecting managed dependencies for project %s", project.getName()));
handleDependencyManagementTransitive(project, dependencyManagementCollector);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.maven.model.Dependency;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.wagon.Wagon;
import org.codehaus.mojo.versions.reporting.ReportRendererFactory;
import org.codehaus.mojo.versions.utils.ArtifactFactory;
Expand Down Expand Up @@ -66,7 +67,8 @@ protected void populateDependencies(Set<Dependency> dependenciesCollector) {
* {@inheritDoc}
* */
@Override
protected void populateDependencyManagement(Set<Dependency> dependencyManagementCollector) {
protected void populateDependencyManagement(Set<Dependency> dependencyManagementCollector)
throws MavenReportException {
if (hasDependencyManagement(getProject())) {
getLog().debug(String.format(
"Collecting managed dependencies for project %s",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,9 @@ protected boolean processModel(
"Unable to parse the pom " + node.getModel().getPomFile(), e);
} catch (VersionRetrievalException e) {
throw new MojoFailureException(
"Unable to retrieve a dependency version while processing "
"Unable to retrieve dependency versions "
+ e.getArtifact().map(a -> "of " + a).orElse("")
+ " while processing "
+ node.getModel().getPomFile(),
e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
Expand Down Expand Up @@ -60,6 +61,7 @@ public abstract class UseLatestVersionsMojoBase extends AbstractVersionsDependen

/**
* Number of executor threads for update retrieval.
*
* @since 2.19.0
*/
@Parameter(property = "numThreads", defaultValue = "5")
Expand Down Expand Up @@ -95,10 +97,12 @@ public UseLatestVersionsMojoBase(
*/
private abstract static class ArtifactVersionChange {
private final DependencyChangeRecord.ChangeKind changeKind;

private final String newVersion;

/**
* Creates a new instance
*
* @param changeKind change kind
* @param newVersion new version
*/
Expand Down Expand Up @@ -130,6 +134,7 @@ private static final class DependencyVersionChange extends ArtifactVersionChange

/**
* Constructs a new instance
*
* @param changeKind change kind
* @param dependency {@code Dependency} instance
* @param newVersion new version
Expand Down Expand Up @@ -199,12 +204,15 @@ protected void update(MutableXMLStreamReader pom)
}
} catch (IOException e) {
throw new MojoExecutionException(e.getMessage(), e);
} catch (IllegalStateException e) {
if (e.getCause() instanceof MojoExecutionException) {
throw (MojoExecutionException) e.getCause();
}
if (e.getCause() instanceof VersionRetrievalException) {
throw (VersionRetrievalException) e.getCause();
} catch (CompletionException e) {
if (e.getCause() instanceof IllegalStateException) {
IllegalStateException ise = (IllegalStateException) e.getCause();
if (ise.getCause() instanceof MojoExecutionException) {
throw (MojoExecutionException) ise.getCause();
}
if (ise.getCause() instanceof VersionRetrievalException) {
throw (VersionRetrievalException) ise.getCause();
}
}
throw e;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ private void useReleases(
// Force releaseVersion version because org.apache.maven.artifact.metadata.MavenMetadataSource does not
// retrieve release version if provided snapshot version.
artifact.setVersion(releaseVersion);
Optional<String> targetVersion = findReleaseVersion(
pom, dep, version, releaseVersion, getHelper().lookupArtifactVersions(artifact, false));
Optional<String> targetVersion =
findReleaseVersion(releaseVersion, getHelper().lookupArtifactVersions(artifact, false));
if (targetVersion.isPresent()) {
updateDependencyVersion(pom, dep, targetVersion.get(), changeKind);
} else {
Expand All @@ -209,12 +209,7 @@ private void useReleases(
}
}

private Optional<String> findReleaseVersion(
MutableXMLStreamReader pom,
Dependency dep,
String version,
String releaseVersion,
ArtifactVersions versions) {
private Optional<String> findReleaseVersion(String releaseVersion, ArtifactVersions versions) {
return !allowRangeMatching
? versions.containsVersion(releaseVersion) ? Optional.of(releaseVersion) : Optional.empty()
: Arrays.stream(versions.getVersions(false))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Locale;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.doxia.module.xhtml5.Xhtml5SinkFactory;
import org.apache.maven.doxia.sink.SinkFactory;
import org.apache.maven.model.Dependency;
Expand All @@ -36,6 +37,7 @@
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.MavenReportException;
import org.codehaus.mojo.versions.api.VersionRetrievalException;
import org.codehaus.mojo.versions.model.RuleSet;
import org.codehaus.mojo.versions.reporting.ReportRendererFactoryImpl;
import org.codehaus.mojo.versions.utils.ArtifactFactory;
Expand All @@ -56,7 +58,10 @@
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.matchesPattern;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;

/**
Expand Down Expand Up @@ -389,4 +394,26 @@ public void testVersionlessDependency() throws IOException, MavenReportException
.withProcessDependencyManagementTransitive(false)
.generate(sinkFactory.createSink(os), sinkFactory, Locale.getDefault());
}

/*
* error while attempting a retrieval of a problematic artifact should be reported citing the artifact
* causing the problem
*/
@Test
public void testProblemCausingArtifact() throws IOException, MavenReportException {
OutputStream os = new ByteArrayOutputStream();
SinkFactory sinkFactory = new Xhtml5SinkFactory();
try {
new TestDependencyUpdatesReport()
.withOriginalDependencyManagement(dependencyOf("problem-causing-artifact", "1"))
.withProcessDependencyManagement(true)
.withProcessDependencyManagementTransitive(false)
.generate(sinkFactory.createSink(os), sinkFactory, Locale.getDefault());
fail("Should throw an exception");
} catch (MavenReportException e) {
assertThat(e.getCause(), instanceOf(VersionRetrievalException.class));
VersionRetrievalException vre = (VersionRetrievalException) e.getCause();
assertThat(vre.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
}
}
}
Loading