-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MCOMPILER-542] Clean JDK patch version in module-info.class
Signed-off-by: Jorge Solórzano <jorsol@gmail.com>
- Loading branch information
Showing
8 changed files
with
233 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,58 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
~ 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. | ||
--> | ||
|
||
<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/maven-v4_0_0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>org.apache.maven.plugins.compiler.it</groupId> | ||
<artifactId>MCOMPILER-542</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
<name>${java.specification.version}</name> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<project.build.outputTimestamp>2023-08-14T15:12:12Z</project.build.outputTimestamp> | ||
</properties> | ||
|
||
<build> | ||
<pluginManagement> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>@project.version@</version> | ||
<configuration> | ||
<release>${java.specification.version}</release> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</pluginManagement> | ||
</build> | ||
</project> | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
~ 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. | ||
--> | ||
|
||
<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/maven-v4_0_0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>org.apache.maven.plugins.compiler.it</groupId> | ||
<artifactId>MCOMPILER-542</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
<name>${java.specification.version}</name> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<project.build.outputTimestamp>2023-08-14T15:12:12Z</project.build.outputTimestamp> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-jdk-platform-logging</artifactId> | ||
<version>2.0.9</version> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<pluginManagement> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>@project.version@</version> | ||
<configuration> | ||
<release>${java.specification.version}</release> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</pluginManagement> | ||
</build> | ||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,61 @@ | ||
/* | ||
* 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 proc = 'javap -v target/classes/module-info.class'.execute(null,basedir) | ||
def sout = new StringBuilder(), serr = new StringBuilder() | ||
proc.consumeProcessOutput(sout, serr) | ||
proc.waitForOrKill(1000) | ||
def out = sout.toString() | ||
println "javap -v target/classes/module-info.class>\n$out\nerr> $serr" | ||
|
||
def module = out.substring(out.indexOf('Module:')) | ||
def javaVersion = System.getProperty('java.version') | ||
assert module.contains('// "java.base" ACC_MANDATED') | ||
assert !module.contains(javaVersion) | ||
/* | ||
* 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. | ||
*/ | ||
|
||
// Check if the javap tool is available | ||
def javapTool = java.util.spi.ToolProvider.findFirst("javap") | ||
assert javapTool.isPresent() : "javap tool not found. Make sure you have the JDK installed." | ||
|
||
def moduleDescriptor = new File(basedir, "target/classes/module-info.class") | ||
// Create a list of arguments to pass to the javap tool | ||
String[] args = ["-v", moduleDescriptor] | ||
|
||
def swout = new StringWriter(), swerr = new StringWriter() | ||
// Execute the javap tool with args | ||
def result = javapTool.get().run(new PrintWriter(swout), new PrintWriter(swerr), args) | ||
println swerr.toString().isEmpty() ? "javap output:\n$swout" : "javap error:\n$swerr" | ||
assert (result == 0) : "javap run failed" | ||
|
||
// Assertions of module content | ||
def out = swout.toString() | ||
assert out.contains('// "java.base" ACC_MANDATED') : "module not found in module-info.class" | ||
assert out.contains('// "java.logging"') : "module not found in module-info.class" | ||
assert out.contains('// "jdk.zipfs"') : "module not found in module-info.class" | ||
assert out.contains('// "org.slf4j.jdk.platform.logging"') : "module not found in module-info.class" | ||
assert out.contains('// 2.0.9') : "version of org.slf4j.jdk.platform.logging module not found" | ||
|
||
// Validation that the module-info should not contain the full java version but the spec version. | ||
def javaVersion = System.getProperty('java.version') | ||
def javaSpecVersion = System.getProperty('java.specification.version') | ||
if (javaVersion != javaSpecVersion) { // handle the case when is the first release | ||
assert !out.contains('// ' + javaVersion) : "full java version found in module descriptor" | ||
} | ||
assert out.contains('// ' + javaSpecVersion) : "java specification version not found in module descriptor" | ||
|
||
// Additional validation that the checksum is always the same | ||
def checksumMap = [ | ||
'21': 'SHA-256 checksum ccc6515c8fc1bf4e675e205b2a5200d02545b06014b304c292eeddc68cffee8d', | ||
'17': 'SHA-256 checksum 102f24c71aff97210d66ef791b7d56f8a25ff8692d2c97b21682bc7170aaca9c', | ||
'11': 'MD5 checksum 5779cc6044dcba6ae4060e5a2f8a32c8' | ||
] | ||
|
||
def expectedChecksum = checksumMap[javaSpecVersion] | ||
if (expectedChecksum) { | ||
println "Java version: $javaVersion" | ||
assert out.contains(expectedChecksum) : "checksum doesn't match expected output" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
src/main/java/org/apache/maven/plugin/compiler/ModuleInfoTransformer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* 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.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.apache.maven.plugin.logging.Log; | ||
import org.objectweb.asm.ClassReader; | ||
import org.objectweb.asm.ClassVisitor; | ||
import org.objectweb.asm.ClassWriter; | ||
import org.objectweb.asm.ModuleVisitor; | ||
import org.objectweb.asm.Opcodes; | ||
|
||
final class ModuleInfoTransformer { | ||
|
||
private ModuleInfoTransformer() {} | ||
|
||
static byte[] transform(byte[] originalBytecode, String javaVersion, Log log) { | ||
List<String> modulesModified = new ArrayList<>(); | ||
ClassReader reader = new ClassReader(originalBytecode); | ||
ClassWriter writer = new ClassWriter(0); | ||
|
||
ClassVisitor classVisitor = new ClassVisitor(Opcodes.ASM9, writer) { | ||
@Override | ||
public ModuleVisitor visitModule(String name, int access, String version) { | ||
ModuleVisitor originalModuleVisitor = super.visitModule(name, access, version); | ||
return new ModuleVisitor(Opcodes.ASM9, originalModuleVisitor) { | ||
@Override | ||
public void visitRequire(String module, int access, String version) { | ||
// Check if the module name matches the java/jdk modules | ||
if (module.startsWith("java.") || module.startsWith("jdk.")) { | ||
// Patch the version from the java.* and jdk.* modules | ||
// with the --release N version. | ||
super.visitRequire(module, access, javaVersion); | ||
modulesModified.add(module); | ||
} else { | ||
// Keep the original require statement | ||
super.visitRequire(module, access, version); | ||
} | ||
} | ||
}; | ||
} | ||
}; | ||
|
||
reader.accept(classVisitor, 0); | ||
|
||
log.info(String.format("Patch module-info.class %s with version %s", modulesModified, javaVersion)); | ||
return writer.toByteArray(); | ||
} | ||
} |