From a4a78f2c69e125af428429e479b3e3d5eaf890fd Mon Sep 17 00:00:00 2001
From: "INT\\aubelm" <Martin.Aubele.ext@msg.group>
Date: Wed, 6 Oct 2021 12:03:08 +0200
Subject: [PATCH] Cannot invoke method hashCode() on null object in complex CI
 Friendly Project #128

added Check to thunkModelBuilder
---
 .gitattributes                                |  6 ++
 .../civersion-tiletest-workspace-pom/pom.xml  | 22 +++++
 .../projectAParent/pom.xml                    | 52 +++++++++++
 .../projectAParent/projectA/pom.xml           | 44 ++++++++++
 .../projectBParent/pom.xml                    | 52 +++++++++++
 .../projectBParent/projectB/pom.xml           | 34 ++++++++
 .../readme.md                                 | 86 +++++++++++++++++++
 .../tile-tile1/pom.xml                        | 24 ++++++
 .../tile-tile1/tile.xml                       |  7 ++
 .../verify.bsh                                | 12 +++
 .../TilesMavenLifecycleParticipant.groovy     | 17 ++++
 11 files changed, 356 insertions(+)
 create mode 100644 .gitattributes
 create mode 100644 src/it/civersion-tiletest-workspace-pom/pom.xml
 create mode 100644 src/it/civersion-tiletest-workspace-pom/projectAParent/pom.xml
 create mode 100644 src/it/civersion-tiletest-workspace-pom/projectAParent/projectA/pom.xml
 create mode 100644 src/it/civersion-tiletest-workspace-pom/projectBParent/pom.xml
 create mode 100644 src/it/civersion-tiletest-workspace-pom/projectBParent/projectB/pom.xml
 create mode 100644 src/it/civersion-tiletest-workspace-pom/readme.md
 create mode 100644 src/it/civersion-tiletest-workspace-pom/tile-tile1/pom.xml
 create mode 100644 src/it/civersion-tiletest-workspace-pom/tile-tile1/tile.xml
 create mode 100644 src/it/civersion-tiletest-workspace-pom/verify.bsh

diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..fa8e44a
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,6 @@
+*             text=auto
+.*            text eol=lf
+*.sh          eol=lf
+*.ksh         eol=lf
+*.list        eol=lf
+mvnw          eol=lf
\ No newline at end of file
diff --git a/src/it/civersion-tiletest-workspace-pom/pom.xml b/src/it/civersion-tiletest-workspace-pom/pom.xml
new file mode 100644
index 0000000..01a30c1
--- /dev/null
+++ b/src/it/civersion-tiletest-workspace-pom/pom.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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>com.test</groupId>
+  <artifactId>civersion-workspace-test</artifactId>
+  <version>SNAPSHOT</version>
+
+  <packaging>pom</packaging>
+
+  <name>CI Friendly Build Version Maven Tiles Test</name>
+
+
+  <modules>
+    <module>tile-tile1</module>
+    <module>projectBParent</module>
+    <module>projectAParent</module>
+    
+  </modules>
+
+</project>
diff --git a/src/it/civersion-tiletest-workspace-pom/projectAParent/pom.xml b/src/it/civersion-tiletest-workspace-pom/projectAParent/pom.xml
new file mode 100644
index 0000000..df6a62a
--- /dev/null
+++ b/src/it/civersion-tiletest-workspace-pom/projectAParent/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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>com.test</groupId>
+  <artifactId>civersion-tiletest-projectAParent</artifactId>
+  <version>${revision}</version>
+
+  <packaging>pom</packaging>
+
+  <properties>
+    <revision>SNAPSHOT-1</revision>
+  </properties>
+
+  <name>CI Friendly Build Version Maven Tiles Test - ProjectAParent</name>
+
+  <modules>
+    <module>projectA</module>
+  </modules>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>flatten-maven-plugin</artifactId>
+        <version>1.1.0</version>
+        <configuration>
+          <updatePomFile>true</updatePomFile>
+          <flattenMode>resolveCiFriendliesOnly</flattenMode>
+        </configuration>
+        <executions>
+          <execution>
+            <id>flatten</id>
+            <phase>process-resources</phase>
+            <goals>
+              <goal>flatten</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>flatten.clean</id>
+            <phase>clean</phase>
+            <goals>
+              <goal>clean</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/src/it/civersion-tiletest-workspace-pom/projectAParent/projectA/pom.xml b/src/it/civersion-tiletest-workspace-pom/projectAParent/projectA/pom.xml
new file mode 100644
index 0000000..8ce7222
--- /dev/null
+++ b/src/it/civersion-tiletest-workspace-pom/projectAParent/projectA/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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>com.test</groupId>
+    <artifactId>civersion-tiletest-projectAParent</artifactId>
+    <version>${revision}</version>
+  </parent>
+
+  <groupId>com.test</groupId>
+  <artifactId>civersion-tiletest-projectA</artifactId>
+
+  <packaging>jar</packaging>
+
+  <name>CI Friendly Build Version Maven Tiles Test - ProjectA</name>
+
+  <dependencies>
+    <dependency>
+      <artifactId>civersion-tiletest-projectB</artifactId>
+      <groupId>com.test</groupId>
+      <version>SNAPSHOT-1</version>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>io.repaint.maven</groupId>
+        <artifactId>tiles-maven-plugin</artifactId>
+        <version>@project.version@</version>
+        <configuration>
+          <tiles>
+            <tile>com.test:civersion-tiletest-workspace-tile1:1</tile>
+          </tiles>
+        </configuration>
+      </plugin>
+
+    </plugins>
+  </build>
+</project>
diff --git a/src/it/civersion-tiletest-workspace-pom/projectBParent/pom.xml b/src/it/civersion-tiletest-workspace-pom/projectBParent/pom.xml
new file mode 100644
index 0000000..dcd5f92
--- /dev/null
+++ b/src/it/civersion-tiletest-workspace-pom/projectBParent/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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>com.test</groupId>
+  <artifactId>civersion-tiletest-projectBParent</artifactId>
+  <version>${revision}</version>
+
+  <packaging>pom</packaging>
+
+  <properties>
+    <revision>SNAPSHOT-1</revision>
+  </properties>
+
+  <name>CI Friendly Build Version Maven Tiles Test - ProjectBParent</name>
+
+  <modules>
+    <module>projectB</module>
+  </modules>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>flatten-maven-plugin</artifactId>
+        <version>1.1.0</version>
+        <configuration>
+          <updatePomFile>true</updatePomFile>
+          <flattenMode>resolveCiFriendliesOnly</flattenMode>
+        </configuration>
+        <executions>
+          <execution>
+            <id>flatten</id>
+            <phase>process-resources</phase>
+            <goals>
+              <goal>flatten</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>flatten.clean</id>
+            <phase>clean</phase>
+            <goals>
+              <goal>clean</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/src/it/civersion-tiletest-workspace-pom/projectBParent/projectB/pom.xml b/src/it/civersion-tiletest-workspace-pom/projectBParent/projectB/pom.xml
new file mode 100644
index 0000000..2cc19dc
--- /dev/null
+++ b/src/it/civersion-tiletest-workspace-pom/projectBParent/projectB/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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>com.test</groupId>
+    <artifactId>civersion-tiletest-projectBParent</artifactId>
+    <version>${revision}</version>
+  </parent>
+  
+  <groupId>com.test</groupId>
+  <artifactId>civersion-tiletest-projectB</artifactId>
+  
+
+  <packaging>jar</packaging>
+
+  <name>CI Friendly Build Version Maven Tiles Test - ProjectB</name>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>io.repaint.maven</groupId>
+        <artifactId>tiles-maven-plugin</artifactId>
+        <version>@project.version@</version>
+        <configuration>
+          <tiles>
+            <tile>com.test:civersion-tiletest-workspace-tile1:1</tile>
+          </tiles>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/src/it/civersion-tiletest-workspace-pom/readme.md b/src/it/civersion-tiletest-workspace-pom/readme.md
new file mode 100644
index 0000000..4f6abbf
--- /dev/null
+++ b/src/it/civersion-tiletest-workspace-pom/readme.md
@@ -0,0 +1,86 @@
+Setup is:
+ProjectA is built by ProjectAParent
+ProjectB is built by ProjectBParent
+Both use ${revision]
+
+
+ProjectA has a dependency to ProjectB
+
+We use a "workspace pom" for Eclipse the references these modules.
+
+
+To reproduce the error:
+ run mvn install on pom.xml
+
+
+
+The error log is:
+
+[INFO] Scanning for projects...
+[WARNING] 
+[WARNING] Some problems were encountered while building the effective model for com.test:civersion-workspace-test:pom:SNAPSHOT
+[WARNING] 'version' uses an unsupported snapshot version format, should be '*-SNAPSHOT' instead. @ line 8, column 12
+[WARNING] 
+[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
+[WARNING] 
+[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
+[WARNING] 
+[INFO] --- tiles-maven-plugin: Injecting 1 tiles as intermediary parent artifacts for com.test:civersion-tiletest-projectB...
+[INFO] Mixed 'com.test:civersion-tiletest-projectB:null' with tile 'com.test:civersion-tiletest-workspace-tile1:1' as its new parent.
+[INFO] Explicitly set version to 'null' from original parent 'com.test:civersion-tiletest-projectBParent:null'.
+[INFO] Mixed 'com.test:civersion-tiletest-workspace-tile1:1' with original parent 'com.test:civersion-tiletest-projectBParent:null' as its new top level parent.
+[INFO] 
+[ERROR] Internal error: java.lang.NullPointerException: Cannot invoke method hashCode() on null object -> [Help 1]
+org.apache.maven.InternalErrorException: Internal error: java.lang.NullPointerException: Cannot invoke method hashCode() on null object
+    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:120)
+    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:972)
+    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
+    at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
+    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: Cannot invoke method hashCode() on null object
+    at org.codehaus.groovy.runtime.NullObject.hashCode (NullObject.java:174)
+    at org.codehaus.groovy.runtime.NullObject$hashCode.call (Unknown Source)
+    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall (CallSiteArray.java:47)
+    at org.codehaus.groovy.runtime.callsite.NullCallSite.call (NullCallSite.java:34)
+    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall (CallSiteArray.java:47)
+    at java_lang_String$hashCode.call (Unknown Source)
+    at io.repaint.maven.tiles.NotDefaultModelCache$Key.<init> (NotDefaultModelCache.groovy:54)
+    at io.repaint.maven.tiles.NotDefaultModelCache.get (NotDefaultModelCache.groovy:29)
+    at org.apache.maven.model.building.DefaultModelBuilder.getCache (DefaultModelBuilder.java:1363)
+    at org.apache.maven.model.building.DefaultModelBuilder.readParent (DefaultModelBuilder.java:852)
+    at org.apache.maven.model.building.DefaultModelBuilder.build (DefaultModelBuilder.java:344)
+    at org.apache.maven.model.building.DefaultModelBuilder.build (DefaultModelBuilder.java:252)
+    at org.apache.maven.model.building.ModelBuilder$build.call (Unknown Source)
+    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall (CallSiteArray.java:47)
+    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call (AbstractCallSite.java:125)
+    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call (AbstractCallSite.java:139)
+    at io.repaint.maven.tiles.TilesMavenLifecycleParticipant.thunkModelBuilder (TilesMavenLifecycleParticipant.groovy:518)
+    at io.repaint.maven.tiles.TilesMavenLifecycleParticipant.orchestrateMerge (TilesMavenLifecycleParticipant.groovy:424)
+    at io.repaint.maven.tiles.TilesMavenLifecycleParticipant.afterProjectsRead (TilesMavenLifecycleParticipant.groovy:322)
+    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:264)
+    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:972)
+    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
+    at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
+    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)
+[ERROR] 
+[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
+[ERROR] Re-run Maven using the -X switch to enable full debug logging.
+[ERROR] 
+[ERROR] For more information about the errors and possible solutions, please read the following articles:
+[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/InternalErrorException
diff --git a/src/it/civersion-tiletest-workspace-pom/tile-tile1/pom.xml b/src/it/civersion-tiletest-workspace-pom/tile-tile1/pom.xml
new file mode 100644
index 0000000..3d78787
--- /dev/null
+++ b/src/it/civersion-tiletest-workspace-pom/tile-tile1/pom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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>com.test</groupId>
+    <artifactId>civersion-tiletest-workspace-tile1</artifactId>
+    <version>1</version>
+
+    <packaging>tile</packaging>
+
+    <name>CI Friendly Build Version Maven Tiles Test - Tile1</name>
+
+   
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>io.repaint.maven</groupId>
+                <artifactId>tiles-maven-plugin</artifactId>
+                <version>@project.version@</version>
+                <extensions>true</extensions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/src/it/civersion-tiletest-workspace-pom/tile-tile1/tile.xml b/src/it/civersion-tiletest-workspace-pom/tile-tile1/tile.xml
new file mode 100644
index 0000000..79c07f8
--- /dev/null
+++ b/src/it/civersion-tiletest-workspace-pom/tile-tile1/tile.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+    <modelVersion>4.0.0</modelVersion>
+    <properties>
+        <foo.bar.tile1>tile1</foo.bar.tile1>
+    </properties>
+</project>
\ No newline at end of file
diff --git a/src/it/civersion-tiletest-workspace-pom/verify.bsh b/src/it/civersion-tiletest-workspace-pom/verify.bsh
new file mode 100644
index 0000000..a8071a6
--- /dev/null
+++ b/src/it/civersion-tiletest-workspace-pom/verify.bsh
@@ -0,0 +1,12 @@
+import java.io.*;
+
+File file = new File( basedir, "build.log" );
+if ( !file.isFile() ) {
+    throw new FileNotFoundException( "Could not find build log: " + file );
+}
+
+String content = new Scanner(file).useDelimiter("\\Z").next();
+
+if (!content.contains("BUILD SUCCESS")) {
+  throw new Exception("Error found.");
+}
diff --git a/src/main/groovy/io/repaint/maven/tiles/TilesMavenLifecycleParticipant.groovy b/src/main/groovy/io/repaint/maven/tiles/TilesMavenLifecycleParticipant.groovy
index 4fa366d..db14ea6 100644
--- a/src/main/groovy/io/repaint/maven/tiles/TilesMavenLifecycleParticipant.groovy
+++ b/src/main/groovy/io/repaint/maven/tiles/TilesMavenLifecycleParticipant.groovy
@@ -469,7 +469,24 @@ public class TilesMavenLifecycleParticipant extends AbstractMavenLifecyclePartic
 			@Override
 			Model read(InputStream input, Map<String, ?> options) throws IOException, ModelParseException {
 				Model model = modelProcessor.read(input, options)
+				
+					 
+				
 				use(GavUtil) {
+		
+					// when we reference a submodule of a CI Friendly module in a pom (i.e. a workspace pom in Eclipse)
+					// we have no version in the submodule.
+					// I.E. module A1 has parent A. Both use CI Friendly version ${revision}. A has a property "revision" with value "MAIN-SNAPSHOT".
+					// we have a pom for our Eclipse workspace that includes A1. 
+					// If the workspace pom includes only A1 it works. But if it contains B and B has a dependency to A1 it 
+					// fails with NPE.
+					// Here we have to ask the project for its version
+					// 
+					if (model.version == null && '${revision}'.equals(model.realVersion)) {
+						model.parent.version = project.version;
+					}
+			
+					
 					// evaluate the model version to deal with CI friendly build versions.
 					// "0-SNAPSHOT" indicates an undefined property.
 					if (model.artifactId == project.artifactId && model.realGroupId == project.groupId