gnodet-bot commented on code in PR #1158:
URL: 
https://github.com/apache/maven-compiler-plugin/pull/1158#discussion_r4225022817


##########
src/it/MCOMPILER-1150/verify.groovy:
##########
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+def buildLog = new File(basedir, 'build.log')
+assert buildLog.isFile() : 'Expected the Maven Invoker build log'
+assert buildLog.text.contains('Cannot format compiler diagnostic; falling back 
to its string representation.') : 'Expected the diagnostic-formatting fallback 
to run'

Review Comment:
   ⚠️ **CI failure — assertion never fires on JDK 17:** This assertion fails in 
CI 
([run](https://github.com/apache/maven-compiler-plugin/actions/runs/37856171427/job/113581063504)):
   
   ```
   AssertionError: Expected the diagnostic-formatting fallback to run.
   Expression: buildLog.text.contains('Cannot format compiler diagnostic; 
falling back to its string representation.')
   ```
   
   The scenario doesn't trigger `CompletionFailure` on JDK 17 because `marker` 
is on the classpath as a `provided` dependency of `annotated-library` — javac 
can resolve `lombok.NonNull` when formatting the deprecation diagnostic, so 
`getMessage()` succeeds and the fallback is never reached.
   
   The IT needs to be structured so that `marker` is genuinely absent from the 
compilation classpath when `consumer` compiles against `annotated-library`. 
Options:
   - Remove `marker` from `consumer`'s transitive classpath entirely (e.g. use 
`optional` + explicit exclusion)
   - Or use a different mechanism (e.g. compile `annotated-library` without 
`marker` on classpath at all, forcing javac to encounter the unresolvable 
annotation type during the consumer build)



##########
src/test/java/org/apache/maven/plugin/compiler/ByteCodeTransformerTest.java:
##########
@@ -0,0 +1,167 @@
+/*
+ * 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.maven.plugin.compiler;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.spi.ToolProvider;
+
+import org.apache.maven.api.plugin.Log;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Tests for {@link ByteCodeTransformer#patchJdkModuleVersion}.
+ *
+ * <p>On JDK 24+, surefire prepends {@code META-INF/versions/24/} on the test 
classpath,
+ * so this test exercises the {@code java.lang.classfile}-backed 
implementation.
+ * On JDK 17-23, it exercises the ASM fallback.
+ *
+ * @see <a 
href="https://issues.apache.org/jira/browse/MCOMPILER-542";>MCOMPILER-542</a>
+ */
+class ByteCodeTransformerTest {
+
+    private static final Log LOG = mock(Log.class);
+
+    @Test
+    void returnsNullForNonModuleClass(@TempDir Path tempDir) throws Exception {
+        byte[] bytes = compileRegularClass(tempDir);
+        assertNull(
+                ByteCodeTransformer.patchJdkModuleVersion(bytes, "21", LOG),
+                "Regular class has no ModuleAttribute -> null");
+    }
+
+    @Test
+    void patchesJdkRequiresVersionToTarget(@TempDir Path tempDir) throws 
Exception {
+        byte[] bytes = compileModuleInfo(
+                tempDir, "jdkRequires", "module com.example { requires 
java.base; requires java.logging; }");
+        byte[] result = ByteCodeTransformer.patchJdkModuleVersion(bytes, "21", 
LOG);
+        // javac on JDK 25+ always emits requires version attributes for jdk 
modules.
+        assertNotNull(result, "javac on JDK 25+ should emit requires version 
attributes");
+        assertTrue(result.length > 0, "Patched result must be non-empty");
+        Map<String, String> versions = readRequiresVersions(result);
+        for (Map.Entry<String, String> entry : versions.entrySet()) {
+            String mod = entry.getKey();
+            if (mod.startsWith("java.") || mod.startsWith("jdk.")) {
+                assertEquals(
+                        "21", entry.getValue(), "JDK module " + mod + " 
requires version should be patched to '21'");
+            }
+        }
+    }
+
+    @Test
+    void patchedBytesAreValidClassFile(@TempDir Path tempDir) throws Exception 
{
+        byte[] bytes = compileModuleInfo(tempDir, "valid", "module com.example 
{ requires java.base; }");
+        byte[] result = ByteCodeTransformer.patchJdkModuleVersion(bytes, "21", 
LOG);
+        assertNotNull(result, "javac on JDK 25+ should emit requires version 
attributes");

Review Comment:
   💡 **Nit:** Same misleading message as above.
   
   ```suggestion
           assertNotNull(result, "javac should emit requires version attributes 
for java.*/jdk.* platform modules");
   ```



##########
src/test/java/org/apache/maven/plugin/compiler/ByteCodeTransformerTest.java:
##########
@@ -0,0 +1,167 @@
+/*
+ * 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.maven.plugin.compiler;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.spi.ToolProvider;
+
+import org.apache.maven.api.plugin.Log;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ModuleVisitor;
+import org.objectweb.asm.Opcodes;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+
+/**
+ * Tests for {@link ByteCodeTransformer#patchJdkModuleVersion}.
+ *
+ * <p>On JDK 24+, surefire prepends {@code META-INF/versions/24/} on the test 
classpath,
+ * so this test exercises the {@code java.lang.classfile}-backed 
implementation.
+ * On JDK 17-23, it exercises the ASM fallback.
+ *
+ * @see <a 
href="https://issues.apache.org/jira/browse/MCOMPILER-542";>MCOMPILER-542</a>
+ */
+class ByteCodeTransformerTest {
+
+    private static final Log LOG = mock(Log.class);
+
+    @Test
+    void returnsNullForNonModuleClass(@TempDir Path tempDir) throws Exception {
+        byte[] bytes = compileRegularClass(tempDir);
+        assertNull(
+                ByteCodeTransformer.patchJdkModuleVersion(bytes, "21", LOG),
+                "Regular class has no ModuleAttribute -> null");
+    }
+
+    @Test
+    void patchesJdkRequiresVersionToTarget(@TempDir Path tempDir) throws 
Exception {
+        byte[] bytes = compileModuleInfo(
+                tempDir, "jdkRequires", "module com.example { requires 
java.base; requires java.logging; }");
+        byte[] result = ByteCodeTransformer.patchJdkModuleVersion(bytes, "21", 
LOG);
+        // javac on JDK 25+ always emits requires version attributes for jdk 
modules.
+        assertNotNull(result, "javac on JDK 25+ should emit requires version 
attributes");

Review Comment:
   💡 **Nit:** The assertion message `"javac on JDK 25+ should emit requires 
version attributes"` is misleading — javac on JDK 17+ has always emitted 
`requires` version attributes for `java.*`/`jdk.*` platform modules. If this 
ever changes, the message would send future investigators in the wrong 
direction.
   
   ```suggestion
           assertNotNull(result, "javac should emit requires version attributes 
for java.*/jdk.* platform modules");
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to