Repository: mojohaus/versions (java)

Issue:
NullPointerException when running compare-dependencies goal
Hi

This is the command I ran:
```
mvn -X versions:compare-dependencies  -DreportOutputFile=depDiffs.txt -DremotePom=group:artifact:version
```

Got this stacktrace:
```
[ERROR] Failed to execute goal org.codehaus.mojo:versions-maven-plugin:2.18.0:compare-dependencies (default-cli) on project system-tests: Execution default-cli of goal org.codehaus.mojo:versions-maven-plugin:2.18.0:compare-dependencies failed.: NullPointerException -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:versions-maven-plugin:2.18.0:compare-dependencies (default-cli) on project system-tests: Execution default-cli of goal org.codehaus.mojo:versions-maven-plugin:2.18.0:compare-dependencies failed.
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution default-cli of goal org.codehaus.mojo:versions-maven-plugin:2.18.0:compare-dependencies failed.
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:148)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: java.lang.NullPointerException
    at org.codehaus.mojo.versions.CompareDependenciesMojo.compareVersions (CompareDependenciesMojo.java:299)
    at org.codehaus.mojo.versions.CompareDependenciesMojo.update (CompareDependenciesMojo.java:183)
    at org.codehaus.mojo.versions.AbstractVersionsUpdaterMojo.process (AbstractVersionsUpdaterMojo.java:317)
    at org.codehaus.mojo.versions.AbstractVersionsUpdaterMojo.execute (AbstractVersionsUpdaterMojo.java:272)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:210)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:156)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:148)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:957)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:289)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:193)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
```

I don't have a working example, since this is a company product. But I might be able to get more information, with some help.
What can I get?

Pull request description:
Resolves #1197: Handling a no-version case in dependencyManagement for CompareDependenciesMojo
A dependency management entry can contain no version at all, in which case CompareDependenciesMojo will raise an NPE.

@slawekjaranowski please review

Patch:
diff --git a/pom.xml b/pom.xml
index e4bdc75c..1ceba078 100644
--- a/pom.xml
+++ b/pom.xml
@@ -137,7 +137,7 @@
     <fluidoVersion>${maven-fluido-skin.version}</fluidoVersion>
     <modelloNamespaceRuleVersion>2.1.0</modelloNamespaceRuleVersion>
     <modelloNamespaceReportVersion>2.0.0</modelloNamespaceReportVersion>
-    <byteBuddyVersion>1.15.10</byteBuddyVersion>
+    <byteBuddyVersion>1.15.11</byteBuddyVersion>
 
     <!-- use the same version as in Maven core -->
     <mavenResolverVersion>1.4.1</mavenResolverVersion>
@@ -325,7 +325,7 @@
       <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-text</artifactId>
-        <version>1.12.0</version>
+        <version>1.13.0</version>
       </dependency>
       <dependency>
         <groupId>org.apache.commons</groupId>
diff --git a/versions-maven-plugin/src/it-repo/dummy-aggregate-child-1.0.1-SNAPSHOT.pom b/versions-maven-plugin/src/it-repo/dummy-aggregate-child-1.0.1-SNAPSHOT.pom
new file mode 100644
index 00000000..d2358bef
--- /dev/null
+++ b/versions-maven-plugin/src/it-repo/dummy-aggregate-child-1.0.1-SNAPSHOT.pom
@@ -0,0 +1,38 @@
+<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>localhost</groupId>
+    <artifactId>dummy-aggregate-parent</artifactId>
+    <version>1.0.1-SNAPSHOT</version>
+  </parent>
+
+  <groupId>localhost</groupId>
+  <artifactId>dummy-aggregate-child</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <properties>
+    <version.dummy-lib>2.0.0.0</version.dummy-lib>
+  </properties>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>test.bigversion</groupId>
+        <artifactId>dummy-lib</artifactId>
+        <version>${version.dummy-lib}</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <dependencies>
+    <dependency>
+      <groupId>test.package</groupId>
+      <artifactId>module</artifactId>
+      <version>0.0.2.19</version>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/versions-maven-plugin/src/it-repo/dummy-aggregate-parent-1.0.1-SNAPSHOT.pom b/versions-maven-plugin/src/it-repo/dummy-aggregate-parent-1.0.1-SNAPSHOT.pom
new file mode 100644
index 00000000..43659cde
--- /dev/null
+++ b/versions-maven-plugin/src/it-repo/dummy-aggregate-parent-1.0.1-SNAPSHOT.pom
@@ -0,0 +1,33 @@
+<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>
+
+  <groupId>localhost</groupId>
+  <artifactId>dummy-aggregate-parent</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <properties>
+    <version.maven-clean-plugin>3.0.0</version.maven-clean-plugin>
+  </properties>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <artifactId>maven-clean-plugin</artifactId>
+          <version>${version.maven-clean-plugin}</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-deploy-plugin</artifactId>
+          <version>3.0.0-M1</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+
+  <reporting>
+    <excludeDefaults>true</excludeDefaults>
+  </reporting>
+
+</project>
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/CompareDependenciesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/CompareDependenciesMojo.java
index 43b5c171..43c9e0b0 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/CompareDependenciesMojo.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/CompareDependenciesMojo.java
@@ -26,6 +26,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
@@ -52,6 +53,7 @@ import org.codehaus.mojo.versions.utils.DependencyBuilder;
 import org.eclipse.aether.RepositorySystem;
 
 import static java.util.Collections.singletonList;
+import static java.util.Optional.ofNullable;
 
 /**
  * Compare dependency versions of the current project to dependencies or dependency management of a remote repository
@@ -296,7 +298,7 @@ public class CompareDependenciesMojo extends AbstractVersionsDependencyUpdaterMo
             Dependency remoteDep = remoteDependencies.get(dep.getManagementKey());
             if (remoteDep != null) {
                 String remoteVersion = remoteDep.getVersion();
-                if (!dep.getVersion().equals(remoteVersion)) {
+                if (!Objects.equals(remoteVersion, dep.getVersion())) {
                     StringBuilder buf = writeDependencyDiffMessage(dep, remoteVersion);
                     updates.add(buf.toString());
                     if (!reportMode) {
@@ -414,7 +416,10 @@ public class CompareDependenciesMojo extends AbstractVersionsDependencyUpdaterMo
      */
     private StringBuilder writeDependencyDiffMessage(Dependency dep, String remoteVersion) {
         String id = dep.getGroupId() + ":" + dep.getArtifactId();
-        return writeDiffMessage(id, dep.getVersion(), remoteVersion);
+        return writeDiffMessage(
+                id,
+                ofNullable(dep.getVersion()).orElse("(no version)"),
+                ofNullable(remoteVersion).orElse("(no version)"));
     }
 
     private StringBuilder writeDiffMessage(String id, String originalVersion, String targetVersion) {


Test patch:
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/CompareDependenciesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/CompareDependenciesMojoTest.java
new file mode 100644
index 00000000..917b45d3
--- /dev/null
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/CompareDependenciesMojoTest.java
@@ -0,0 +1,59 @@
+package org.codehaus.mojo.versions;
+
+import java.io.File;
+import java.util.Collections;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Model;
+import org.apache.maven.plugin.testing.AbstractMojoTestCase;
+import org.apache.maven.plugin.testing.MojoRule;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuilder;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.project.ProjectBuildingResult;
+import org.codehaus.mojo.versions.utils.DependencyBuilder;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class CompareDependenciesMojoTest extends AbstractMojoTestCase {
+
+    @Rule
+    public final MojoRule mojoRule = new MojoRule(this);
+
+    @Test
+    public void testCompareVersionlessDependencies() throws Exception {
+        CompareDependenciesMojo mojo = (CompareDependenciesMojo) mojoRule.lookupConfiguredMojo(
+                new File("src/test/resources/org/codehaus/mojo/compare-dependencies/versionless"),
+                "compare-dependencies");
+        ProjectBuildingResult result = mock(ProjectBuildingResult.class);
+        when(result.getProblems()).thenReturn(Collections.emptyList());
+        when(result.getProject()).thenReturn(new MavenProject(new Model() {
+            {
+                setDependencyManagement(new DependencyManagement() {
+                    {
+                        setDependencies(Collections.singletonList(DependencyBuilder.newBuilder()
+                                .withGroupId("defaultGroup")
+                                .withArtifactId("artifactA")
+                                .withScope("test")
+                                .withVersion("1.0.0")
+                                .build()));
+                    }
+                });
+            }
+        }));
+
+        ProjectBuilder projectBuilder = mock(ProjectBuilder.class);
+        when(projectBuilder.build(any(Artifact.class), anyBoolean(), any(ProjectBuildingRequest.class)))
+                .thenReturn(result);
+        setVariableValueToObject(mojo, "projectBuilder", projectBuilder);
+        setVariableValueToObject(mojo, "remotePom", "defaultGroup:other-artifact:1.0.0");
+
+        mojo.execute();
+    }
+}
diff --git a/versions-maven-plugin/src/test/resources/org/codehaus/mojo/compare-dependencies/versionless/pom.xml b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/compare-dependencies/versionless/pom.xml
new file mode 100644
index 00000000..1e8dbe8d
--- /dev/null
+++ b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/compare-dependencies/versionless/pom.xml
@@ -0,0 +1,18 @@
+<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>
+  <groupId>default-group</groupId>
+  <artifactId>default-artifact</artifactId>
+  <version>1.0.0</version>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>defaultGroup</groupId>
+        <artifactId>artifactA</artifactId>
+        <scope>test</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+</project>