This is an automated email from the ASF dual-hosted git repository.

hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new 2126d18fec Issue #8426 : Register ECJ on Debian/Ubuntu Maven without a 
committed jar (#8427)
2126d18fec is described below

commit 2126d18fec47d3cc0a3b646a2bd3f1cf021f8d54
Author: Matt Casters <[email protected]>
AuthorDate: Wed Sep 16 20:33:58 2026 +0200

    Issue #8426 : Register ECJ on Debian/Ubuntu Maven without a committed jar 
(#8427)
    
    Replace the Groovy + systemPath hint-jar hack with a javac helper that
    writes the Plexus descriptor, install-file's it as a normal GAV, and
    attaches the Lombok ECJ agent once per Maven JVM. apt Maven 3.8.7 on
    Ubuntu keeps compiling; no binary is stored in git.
---
 pom.xml                                            | 183 ++++++++++-----------
 .../org/apache/hop/tools/ecj/AttachLombokEcj.java  | 142 ++++++++++++++++
 2 files changed, 230 insertions(+), 95 deletions(-)

diff --git a/pom.xml b/pom.xml
index 44f956a4e0..a7c07a8bba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -126,8 +126,6 @@
         
<gib.forceBuildModules>org.eclipse.tm4e.core,org.eclipse.swtbot.swt.finder</gib.forceBuildModules>
         <gib.referenceBranch>refs/remotes/origin/main</gib.referenceBranch>
         <gib.skipTestsForUpstreamModules>true</gib.skipTestsForUpstreamModules>
-        <gmavenplus-plugin.version>4.3.1</gmavenplus-plugin.version>
-        <groovy.version>4.0.28</groovy.version>
         <grpc.version>1.83.1</grpc.version>
         <hadoop.thirdparty.version>1.4.0</hadoop.thirdparty.version>
         <hadoop.version>3.4.2</hadoop.version>
@@ -403,20 +401,40 @@
                     </execution>
                 </executions>
             </plugin>
+            <!--
+                 Debian/Ubuntu Maven never indexes plexus-compiler-eclipse 
2.17.0 (Sisu
+                 0.3.x ASM stops at Java 14 class files). inherited so `cd 
<module> &&
+                 mvn` and `-pl <module>` still attach Lombok and install the 
Eclipse
+                 compiler Plexus descriptor into the local repo (no committed 
jar, no
+                 systemPath). javac + exec:java avoids the Groovy-per-module 
startup tax.
+                 Phases are split so sortPom cannot run the helper before it 
is compiled.
+            -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-antrun-plugin</artifactId>
+                <version>3.1.0</version>
+                <executions>
+                    <execution>
+                        <id>compile-lombok-ecj-helper</id>
+                        <goals>
+                            <goal>run</goal>
+                        </goals>
+                        <phase>validate</phase>
+                        <configuration>
+                            <target>
+                                <property name="hop.root" 
value="${maven.multiModuleProjectDirectory}"></property>
+                                <mkdir 
dir="${hop.root}/tools/ecj-helper/target/classes"></mkdir>
+                                <javac 
destdir="${hop.root}/tools/ecj-helper/target/classes" encoding="UTF-8" 
includeDestClasses="true" includeantruntime="false" release="21" 
srcdir="${hop.root}/tools/ecj-helper/src/main/java"></javac>
+                            </target>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
             <plugin>
-                <groupId>org.codehaus.gmavenplus</groupId>
-                <artifactId>gmavenplus-plugin</artifactId>
-                <version>${gmavenplus-plugin.version}</version>
-                <!-- inherited so `cd <module> && mvn` and `-pl <module>` 
still attach
-                     Lombok and materialize the Eclipse compiler Plexus 
descriptor.
-                     Debian/Ubuntu Maven never indexes plexus-compiler-eclipse 
2.17.0
-                     (Sisu 0.3.x ASM stops at Java 14 class files). -->
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>3.5.0</version>
                 <dependencies>
-                    <dependency>
-                        <groupId>org.apache.groovy</groupId>
-                        <artifactId>groovy</artifactId>
-                        <version>${groovy.version}</version>
-                    </dependency>
                     <dependency>
                         <groupId>org.projectlombok</groupId>
                         <artifactId>lombok</artifactId>
@@ -427,77 +445,53 @@
                     <execution>
                         <id>attach-lombok-ecj-agent</id>
                         <goals>
-                            <goal>execute</goal>
+                            <goal>java</goal>
                         </goals>
-                        <phase>validate</phase>
+                        <phase>initialize</phase>
                         <configuration>
-                            <!-- The Plexus descriptor jar below is always 
(re)built; only the
-                                 agent attach honours lombok.ecj.agent.skip. 
-->
-                            <properties>
-                                <property>
-                                    <name>lombokEcjAgentSkip</name>
+                            
<mainClass>org.apache.hop.tools.ecj.AttachLombokEcj</mainClass>
+                            
<includeProjectDependencies>false</includeProjectDependencies>
+                            
<includePluginDependencies>true</includePluginDependencies>
+                            <additionalClasspathElements>
+                                
<additionalClasspathElement>${maven.multiModuleProjectDirectory}/tools/ecj-helper/target/classes</additionalClasspathElement>
+                            </additionalClasspathElements>
+                            <systemProperties>
+                                <systemProperty>
+                                    <key>lombok.ecj.agent.skip</key>
                                     <value>${lombok.ecj.agent.skip}</value>
-                                </property>
-                            </properties>
-                            <scripts>
-                                <script><![CDATA[
-import com.sun.tools.attach.VirtualMachine
-import java.nio.file.Files
-import java.nio.file.StandardCopyOption
-import java.util.zip.ZipEntry
-import java.util.zip.ZipOutputStream
-
-def projectDir = new 
File(System.getProperty('maven.multiModuleProjectDirectory'))
-synchronized (System.getProperties()) {
-    def hintXml = new File(projectDir, 
'.mvn/plexus-eclipse-hint/META-INF/plexus/components.xml')
-    def hintJar = new File(projectDir, '.mvn/plexus-eclipse-hint.jar')
-    if (hintXml.isFile() && (!hintJar.isFile() || hintJar.lastModified() < 
hintXml.lastModified())) {
-        hintJar.withOutputStream { fos ->
-            def zos = new ZipOutputStream(fos)
-            zos.putNextEntry(new ZipEntry('META-INF/plexus/components.xml'))
-            hintXml.withInputStream { it.transferTo(zos) }
-            zos.closeEntry()
-            zos.close()
-        }
-        log.info('Wrote Eclipse compiler Plexus descriptor jar: ' + hintJar)
-    }
-
-    if (String.valueOf(lombokEcjAgentSkip) != 'true'
-            && System.getProperty('lombok.ecj.agent.attached') == null) {
-        def lombokJar = null
-        try {
-            def loc = 
Class.forName('lombok.launch.Agent').protectionDomain.codeSource.location
-            if (loc != null && loc.protocol == 'file') {
-                lombokJar = new File(loc.toURI())
-            }
-        } catch (ClassNotFoundException ignored) {
-            // fall through to .mvn/lombok-*.jar
-        }
-        if (lombokJar == null || !lombokJar.isFile()) {
-            lombokJar = new File(projectDir, '.mvn/lombok-' + 
project.properties['lombok.version'] + '.jar')
-        }
-        if (!lombokJar.isFile() || lombokJar.length() < 1000000L) {
-            throw new IllegalStateException('Lombok jar missing or incomplete 
for the ECJ agent attach, expected ' + lombokJar)
-        }
-        def agentJar = Files.createTempFile('lombok-ecj-agent-', 
'.jar').toFile()
-        agentJar.deleteOnExit()
-        Files.copy(lombokJar.toPath(), agentJar.toPath(), 
StandardCopyOption.REPLACE_EXISTING)
-        try {
-            def vm = 
VirtualMachine.attach(String.valueOf(ProcessHandle.current().pid()))
-            try {
-                vm.loadAgent(agentJar.absolutePath, 'ECJ')
-            } finally {
-                vm.detach()
-            }
-            System.setProperty('lombok.ecj.agent.attached', 'true')
-            log.info('Lombok ECJ agent attached (source: ' + lombokJar + ')')
-        } catch (Throwable t) {
-            throw new IllegalStateException('Unable to self-attach the Lombok 
ECJ agent, ensure -Djdk.attach.allowAttachSelf=true is in .mvn/jvm.config and 
the environment allows self-attach, or skip it with 
-Dlombok.ecj.agent.skip=true', t)
-        }
-    }
-}
-                                ]]></script>
-                            </scripts>
+                                </systemProperty>
+                                <systemProperty>
+                                    <key>lombok.version</key>
+                                    <value>${lombok.version}</value>
+                                </systemProperty>
+                            </systemProperties>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <!--
+                 initialize wrote .mvn/plexus-eclipse-hint.jar. 
generate-sources installs
+                 it as a real GAV so maven-compiler-plugin can depend on it 
without
+                 systemPath. generate-sources is after initialize, so plugin 
sort order
+                 cannot invert this.
+            -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-install-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>install-plexus-eclipse-hint</id>
+                        <goals>
+                            <goal>install-file</goal>
+                        </goals>
+                        <phase>generate-sources</phase>
+                        <configuration>
+                            <groupId>org.apache.hop</groupId>
+                            <artifactId>plexus-eclipse-hint</artifactId>
+                            <version>1.0</version>
+                            <packaging>jar</packaging>
+                            
<file>${maven.multiModuleProjectDirectory}/.mvn/plexus-eclipse-hint.jar</file>
+                            <generatePom>true</generatePom>
                         </configuration>
                     </execution>
                 </executions>
@@ -513,6 +507,17 @@ synchronized (System.getProperties()) {
                     </compilerArgs>
                 </configuration>
                 <dependencies>
+                    <!-- Plexus XML registration of compilerId=eclipse. 
Required for
+                         Debian/Ubuntu Maven, whose Sisu 0.3.x cannot 
ASM-index the
+                         Java 17 EclipseJavaCompiler class. The jar is NOT 
tracked in git:
+                         initialize writes it from .mvn/plexus-eclipse-hint/ 
and
+                         generate-sources install-file's it as this GAV, 
before compile
+                         loads this plugin. -->
+                    <dependency>
+                        <groupId>org.apache.hop</groupId>
+                        <artifactId>plexus-eclipse-hint</artifactId>
+                        <version>1.0</version>
+                    </dependency>
                     <dependency>
                         <groupId>org.codehaus.plexus</groupId>
                         <artifactId>plexus-compiler-eclipse</artifactId>
@@ -523,19 +528,6 @@ synchronized (System.getProperties()) {
                         <artifactId>lombok</artifactId>
                         <version>${lombok.version}</version>
                     </dependency>
-                    <!-- Plexus XML registration of compilerId=eclipse. 
Required for
-                         Debian/Ubuntu Maven, whose Sisu 0.3.x cannot 
ASM-index the
-                         Java 17 EclipseJavaCompiler class. The jar is NOT 
tracked in git
-                         (binaries stay out of the repository): the gmavenplus 
execution
-                         above writes it from .mvn/plexus-eclipse-hint/ during 
validate,
-                         which runs before this plugin is resolved in every 
module. -->
-                    <dependency>
-                        <groupId>org.apache.hop</groupId>
-                        <artifactId>plexus-eclipse-hint</artifactId>
-                        <version>1.0</version>
-                        <scope>system</scope>
-                        
<systemPath>${maven.multiModuleProjectDirectory}/.mvn/plexus-eclipse-hint.jar</systemPath>
-                    </dependency>
                 </dependencies>
             </plugin>
             <plugin>
@@ -701,6 +693,7 @@ synchronized (System.getProperties()) {
                     <java>
                         <includes>
                             <include>src/**/*.java</include>
+                            <include>tools/ecj-helper/src/**/*.java</include>
                         </includes>
                         <googleJavaFormat></googleJavaFormat>
                         <importOrder></importOrder>
diff --git 
a/tools/ecj-helper/src/main/java/org/apache/hop/tools/ecj/AttachLombokEcj.java 
b/tools/ecj-helper/src/main/java/org/apache/hop/tools/ecj/AttachLombokEcj.java
new file mode 100644
index 0000000000..fd8031780e
--- /dev/null
+++ 
b/tools/ecj-helper/src/main/java/org/apache/hop/tools/ecj/AttachLombokEcj.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.tools.ecj;
+
+import com.sun.tools.attach.VirtualMachine;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * Build-time helper invoked from exec-maven-plugin (same JVM as Maven).
+ *
+ * <p>Writes {@code .mvn/plexus-eclipse-hint.jar} from the XML descriptor so 
Debian/Ubuntu Maven
+ * (Sisu 0.3.x) can register {@code compilerId=eclipse} without ASM-indexing 
the Java 17 Eclipse
+ * compiler class, then self-attaches the Lombok ECJ agent once per Maven JVM.
+ */
+public final class AttachLombokEcj {
+
+  private AttachLombokEcj() {}
+
+  public static void main(String[] args) throws Exception {
+    String rootPath = System.getProperty("maven.multiModuleProjectDirectory");
+    if (rootPath == null || rootPath.isEmpty()) {
+      throw new IllegalStateException("maven.multiModuleProjectDirectory is 
not set");
+    }
+    File root = new File(rootPath);
+    synchronized (System.getProperties()) {
+      writeHintJar(root);
+      attachLombok(root);
+    }
+  }
+
+  private static void writeHintJar(File root) throws IOException {
+    File hintXml = new File(root, 
".mvn/plexus-eclipse-hint/META-INF/plexus/components.xml");
+    File hintJar = new File(root, ".mvn/plexus-eclipse-hint.jar");
+    if (!hintXml.isFile()) {
+      throw new IllegalStateException("Eclipse compiler Plexus descriptor 
missing: " + hintXml);
+    }
+    if (hintJar.isFile() && hintJar.lastModified() >= hintXml.lastModified()) {
+      return;
+    }
+    File parent = hintJar.getParentFile();
+    if (parent != null && !parent.isDirectory() && !parent.mkdirs()) {
+      throw new IllegalStateException("Unable to create " + parent);
+    }
+    try (FileOutputStream fos = new FileOutputStream(hintJar);
+        ZipOutputStream zos = new ZipOutputStream(fos);
+        FileInputStream in = new FileInputStream(hintXml)) {
+      zos.putNextEntry(new ZipEntry("META-INF/plexus/components.xml"));
+      byte[] buffer = new byte[4096];
+      int n;
+      while ((n = in.read(buffer)) >= 0) {
+        zos.write(buffer, 0, n);
+      }
+      zos.closeEntry();
+    }
+    System.out.println("Wrote Eclipse compiler Plexus descriptor jar: " + 
hintJar);
+  }
+
+  private static File agentMarker() {
+    return new File(
+        System.getProperty("java.io.tmpdir"),
+        "hop-lombok-ecj-agent-" + ProcessHandle.current().pid());
+  }
+
+  private static void attachLombok(File root) throws Exception {
+    if 
("true".equals(String.valueOf(System.getProperty("lombok.ecj.agent.skip")))) {
+      return;
+    }
+    // exec:java restores System properties after main() returns, and loads 
this
+    // class in a new classloader per module, so a pid-scoped file is the 
durable
+    // "already attached" flag for this Maven JVM.
+    if (System.getProperty("lombok.ecj.agent.attached") != null || 
agentMarker().isFile()) {
+      return;
+    }
+    File lombokJar = findLombokJar(root);
+    if (!lombokJar.isFile() || lombokJar.length() < 1_000_000L) {
+      throw new IllegalStateException(
+          "Lombok jar missing or incomplete for the ECJ agent attach, expected 
" + lombokJar);
+    }
+    File agentJar = Files.createTempFile("lombok-ecj-agent-", ".jar").toFile();
+    agentJar.deleteOnExit();
+    Files.copy(lombokJar.toPath(), agentJar.toPath(), 
StandardCopyOption.REPLACE_EXISTING);
+    try {
+      VirtualMachine vm = 
VirtualMachine.attach(String.valueOf(ProcessHandle.current().pid()));
+      try {
+        vm.loadAgent(agentJar.getAbsolutePath(), "ECJ");
+      } finally {
+        vm.detach();
+      }
+    } catch (Throwable t) {
+      throw new IllegalStateException(
+          "Unable to self-attach the Lombok ECJ agent, ensure 
-Djdk.attach.allowAttachSelf=true is"
+              + " in .mvn/jvm.config and the environment allows self-attach, 
or skip it with"
+              + " -Dlombok.ecj.agent.skip=true",
+          t);
+    }
+    File marker = agentMarker();
+    marker.createNewFile();
+    marker.deleteOnExit();
+    System.setProperty("lombok.ecj.agent.attached", "true");
+    System.out.println("Lombok ECJ agent attached (source: " + lombokJar + 
")");
+  }
+
+  private static File findLombokJar(File root) {
+    try {
+      URL loc =
+          
Class.forName("lombok.launch.Agent").getProtectionDomain().getCodeSource().getLocation();
+      if (loc != null && "file".equals(loc.getProtocol())) {
+        File fromAgent = new File(loc.toURI());
+        if (fromAgent.isFile()) {
+          return fromAgent;
+        }
+      }
+    } catch (Exception ignored) {
+      // fall through to .mvn/lombok-*.jar
+    }
+    String version = System.getProperty("lombok.version", "");
+    return new File(root, ".mvn/lombok-" + version + ".jar");
+  }
+}

Reply via email to