Skip to content

Commit

Permalink
Rework logger, Warn on missing stubs
Browse files Browse the repository at this point in the history
  • Loading branch information
wagyourtail committed Jun 18, 2024
1 parent 12a317d commit 3514037
Show file tree
Hide file tree
Showing 20 changed files with 664 additions and 229 deletions.
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import xyz.wagyourtail.gradle.shadow.ShadowJar

plugins {
kotlin("jvm") version "1.9.22" apply false
java
`maven-publish`
`java-library`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package xyz.wagyourtail.gradle.coverage

import org.gradle.api.JavaVersion
import org.gradle.api.file.FileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.internal.ConventionTask
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.jvm.toolchain.JavaToolchainService

abstract class CoverageRunTask : ConventionTask() {

@get:InputFile
abstract val apiJar: RegularFileProperty

@get:Internal
abstract var classpath: FileCollection

@get:InputFile
abstract val ctSym: RegularFileProperty

@get:Input
abstract val javaVersion: Property<JavaVersion>

@get:OutputDirectory
@get:Optional
abstract var coverageReports: FileCollection


init {
group = "jvmdg"
coverageReports = project.files(temporaryDir.resolve("coverage"))
}

@TaskAction
fun run() {
val toolchains = project.extensions.getByType(JavaToolchainService::class.java)

project.javaexec { spec ->
spec.executable = toolchains.launcherFor {
it.languageVersion.set(JavaLanguageVersion.of(javaVersion.get().majorVersion))
}.get().executablePath.asFile.absolutePath

spec.workingDir = temporaryDir
spec.mainClass.set("xyz.wagyourtail.jvmdg.coverage.ApiCoverageChecker")
spec.classpath = classpath
spec.jvmArgs("-Djvmdg.java-api=${apiJar.get().asFile.absolutePath}", "-Djvmdg.quiet=true")
spec.args(ctSym.get().asFile.absolutePath)

}.assertNormalExitValue().rethrowFailure()

}


}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package xyz.wagyourtail.gradle.ctsym
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
import org.gradle.api.JavaVersion
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.internal.ConventionTask
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
Expand All @@ -22,9 +23,9 @@ import kotlin.io.path.*

abstract class GenerateCtSymTask : ConventionTask() {

@Optional
@OutputFile
var ctSym = temporaryDir.resolve("jvmdg").resolve("ct.sym")
@get:Optional
@get:OutputFile
abstract val ctSym: RegularFileProperty

@get:Input
@get:Optional
Expand All @@ -34,7 +35,7 @@ abstract class GenerateCtSymTask : ConventionTask() {
abstract val upperVersion: Property<JavaVersion>

init {
outputs.upToDateWhen { ctSym.exists() }
ctSym.set(temporaryDir.resolve("jvmdg").resolve("ct.sym"))
lowerVersion.convention(JavaVersion.VERSION_1_6).finalizeValueOnRead()
upperVersion.convention(JavaVersion.VERSION_22).finalizeValueOnRead()
}
Expand Down Expand Up @@ -72,7 +73,7 @@ abstract class GenerateCtSymTask : ConventionTask() {


ZipArchiveOutputStream(
ctSym.toPath().outputStream(StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)
ctSym.get().asFile.toPath().outputStream(StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)
).use { zos ->
val prevJava = mutableMapOf<String, ClassInfo>()
for (java in (lowerVersion.get()..upperVersion.get()).reversed()) {
Expand Down
2 changes: 1 addition & 1 deletion gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.util.*

plugins {
kotlin("jvm") version "1.9.22"
kotlin("jvm")
`java-gradle-plugin`
`java-library`
`maven-publish`
Expand Down
48 changes: 30 additions & 18 deletions java-api/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassWriter
import org.objectweb.asm.tree.ClassNode
import xyz.wagyourtail.gradle.coverage.CoverageRunTask
import xyz.wagyourtail.gradle.ctsym.GenerateCtSymTask
import xyz.wagyourtail.gradle.shadow.ShadowJar
import xyz.wagyourtail.jvmdg.util.plus
Expand Down Expand Up @@ -131,9 +132,38 @@ tasks.getByName<JavaCompile>("compileCoverageJava") {
configCompile(testVersion)
}

val coverageApiJar by tasks.registering(Jar::class) {
from(sourceSets.main.get().output)
from(*((fromVersion..toVersion).map { sourceSets["java${it.ordinal + 1}"].output }).toTypedArray())
from(rootProject.sourceSets.getByName("shared").output)

destinationDirectory = temporaryDir
}


val genCtSym by tasks.registering(GenerateCtSymTask::class) {
group = "jvmdg"
upperVersion = toVersion - 1
}

val coverageReport by tasks.registering(CoverageRunTask::class) {
group = "jvmdg"
dependsOn(coverageApiJar, genCtSym)
apiJar.set(coverageApiJar.get().archiveFile.get().asFile)
classpath = coverage.runtimeClasspath
ctSym.set(genCtSym.get().ctSym)
javaVersion.set(testVersion)
}

tasks.jar {
dependsOn(coverageReport)
from(*((fromVersion..toVersion).map { sourceSets["java${it.ordinal + 1}"].output }).toTypedArray())
from(rootProject.sourceSets.getByName("shared").output)
from(coverageReport.get().coverageReports) {
into("META-INF/coverage")
exclude("**/unmatched.txt")
exclude("**/parentOnly.txt")
}
from(projectDir.parentFile.resolve("LICENSE.md"))
from(projectDir.parentFile.resolve("license")) {
into("license")
Expand Down Expand Up @@ -253,24 +283,6 @@ val downgradeJar8 by tasks.registering(Jar::class) {
from(zipTree(tempFile8))
}

val genCySym by tasks.registering(GenerateCtSymTask::class) {
group = "jvmdg"
upperVersion = toVersion - 1
}

val coverageReport by tasks.registering(JavaExec::class) {
group = "jvmdg"
dependsOn(tasks.jar, genCySym)
javaLauncher.set(javaToolchains.launcherFor {
languageVersion.set(JavaLanguageVersion.of(testVersion.majorVersion))
})
mainClass = "xyz.wagyourtail.jvmdg.coverage.ApiCoverageChecker"
classpath = coverage.runtimeClasspath
jvmArgs("-Djvmdg.java-api=${tasks.jar.get().archiveFile.get().asFile.absolutePath}", "-Djvmdg.quiet=true")
args(genCySym.get().ctSym)
workingDir = project.layout.buildDirectory.get().asFile
}

tasks.assemble {
dependsOn(downgradeJar11)
dependsOn(downgradeJar8)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ public static void main(String[] args) throws IOException, URISyntaxException {
System.out.println("Checking version " + stubVersion);

var unmatchedStubs = versionProvider.stubMappings.values().stream().flatMap(value -> Stream.of(value.getMethodStubMap().values().stream(), value.getMethodModifyMap().values().stream()).flatMap(e -> e)).map(Pair::getFirst).collect(Collectors.toList());

try {
var requiredStubs = new ArrayList<MemberInfo>();
compare(versions.get(v), classes, requiredStubs);
Expand All @@ -106,7 +105,13 @@ public static void main(String[] args) throws IOException, URISyntaxException {
var stub = staticAndStub.fqm();

if (stub.getName() != null) {
var stubProvider = versionProvider.getStubMapper(stub.getOwner());
Set<String> warnings = new HashSet<>();
var stubProvider = versionProvider.getStubMapper(stub.getOwner(), warnings);
if (!warnings.isEmpty()) {
for (var warning : warnings) {
System.err.println(warning);
}
}
// map classes in desc
var desc = stub.getDesc();
var descArgs = desc.getArgumentTypes();
Expand Down Expand Up @@ -261,6 +266,11 @@ public static ClassNode findClass(String name, List<Path> mods) throws IOExcepti
return null;
}

private static final Set<String> excludedMods = Set.of(
"jdk.internal.vm.compiler",
"jdk.internal.vm.compiler.management"
);

public static void compare(List<Path> moduleHolders, Map<String, Pair<String, ClassNode>> currentVersion, List<MemberInfo> removed) throws IOException {
var mods = new ArrayList<Path>();
for (var mod : moduleHolders) {
Expand All @@ -276,6 +286,8 @@ public static void compare(List<Path> moduleHolders, Map<String, Pair<String, Cl
return;
}
var modName = mod.getFileName().toString();

if (excludedMods.contains(modName)) return;
try (var files = Files.find(mod, Integer.MAX_VALUE, (p, a) -> !a.isDirectory())) {
files.parallel().forEach(p -> {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import xyz.wagyourtail.jvmdg.j8.stub.*;
import xyz.wagyourtail.jvmdg.j8.stub.function.*;
import xyz.wagyourtail.jvmdg.j8.stub.stream.*;
import xyz.wagyourtail.jvmdg.logging.Logger;
import xyz.wagyourtail.jvmdg.util.Function;
import xyz.wagyourtail.jvmdg.util.Pair;
import xyz.wagyourtail.jvmdg.version.VersionProvider;
Expand All @@ -29,7 +30,7 @@ public Java8Downgrader() {
@Override
public void ensureInit(ClassDowngrader downgrader) {
if (!isInitialized()) {
if (!downgrader.flags.quiet) System.err.println("[WARNING] Java 8 -> 7 Stubs are VERY incomplete!");
if (!downgrader.flags.quiet) downgrader.logger.warn("Java 8 -> 7 Stubs are VERY incomplete!");
}
super.ensureInit(downgrader);
}
Expand Down Expand Up @@ -329,28 +330,28 @@ public void init() {
}

@Override
public ClassNode otherTransforms(ClassNode clazz, Set<ClassNode> extra, Function<String, ClassNode> getReadOnly) {
public ClassNode otherTransforms(ClassNode clazz, Set<ClassNode> extra, Function<String, ClassNode> getReadOnly, Set<String> warnings) {
List<ClassNode> classes = new ArrayList<>(extra);
classes.add(clazz);
for (ClassNode cls : classes) {
try {
downgradeInterfaces(cls, extra, getReadOnly);
downgradeInterfaces(cls, extra, getReadOnly, warnings);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return super.otherTransforms(clazz, extra, getReadOnly);
}

public void downgradeInterfaces(ClassNode clazz, Set<ClassNode> extra, Function<String, ClassNode> getReadOnly) throws IOException {
public void downgradeInterfaces(ClassNode clazz, Set<ClassNode> extra, Function<String, ClassNode> getReadOnly, Set<String> warnings) throws IOException {
if ((clazz.access & Opcodes.ACC_INTERFACE) != 0) {
downgradeInterfaceMethods(clazz, extra, getReadOnly);
downgradeInterfaceMethods(clazz, extra, getReadOnly, warnings);
} else {
downgradeInterfaceAccesses(clazz, extra, getReadOnly);
downgradeInterfaceAccesses(clazz, extra, getReadOnly, warnings);
}
}

private void downgradeInterfaceMethods(final ClassNode clazz, Set<ClassNode> extra, final Function<String, ClassNode> getReadOnly) throws IOException {
private void downgradeInterfaceMethods(final ClassNode clazz, Set<ClassNode> extra, final Function<String, ClassNode> getReadOnly, Set<String> warnings) throws IOException {
ClassNode interfaceStaticDefaults = new ClassNode();
boolean removed = false;
Iterator<MethodNode> mnodes = clazz.methods.iterator();
Expand Down Expand Up @@ -410,14 +411,14 @@ public ClassNode apply(String s) {
}
return getReadOnly.apply(s);
}
});
}, warnings);
}
}

private void downgradeInterfaceAccesses(ClassNode clazz, Set<ClassNode> extra, Function<String, ClassNode> getReadOnly) throws IOException {
private void downgradeInterfaceAccesses(ClassNode clazz, Set<ClassNode> extra, Function<String, ClassNode> getReadOnly, Set<String> warnings) throws IOException {
Map<MemberNameAndDesc, Type> members = new HashMap<>();
if (!clazz.name.endsWith("$jvmdg$StaticDefaults")) {
ClassMapping stubMapper = getStubMapper(Type.getObjectType(clazz.name), (clazz.access & Opcodes.ACC_INTERFACE) != 0);
ClassMapping stubMapper = getStubMapper(Type.getObjectType(clazz.name), (clazz.access & Opcodes.ACC_INTERFACE) != 0, warnings);
for (Map.Entry<MemberNameAndDesc, Pair<Boolean, Type>> member : stubMapper.getMembers().entrySet()) {
if (member.getValue().getFirst()) {
members.put(member.getKey(), member.getValue().getSecond());
Expand All @@ -435,7 +436,7 @@ private void downgradeInterfaceAccesses(ClassNode clazz, Set<ClassNode> extra, F
min.owner.startsWith("com/sun/")
) {
if (min.getOpcode() == Opcodes.INVOKESTATIC || min.getOpcode() == Opcodes.INVOKESPECIAL) {
System.err.println("[Java8 Interface Downgrader] Found java interface missing stub: " + FullyQualifiedMemberNameAndDesc.of(min));
warnings.add("Found java interface missing stub: " + FullyQualifiedMemberNameAndDesc.of(min));
}
continue;
}
Expand Down Expand Up @@ -466,7 +467,7 @@ private void downgradeInterfaceAccesses(ClassNode clazz, Set<ClassNode> extra, F
handle.getOwner().startsWith("jdk/") ||
handle.getOwner().startsWith("com/sun/")) {
if (handle.getTag() == Opcodes.H_INVOKESTATIC || handle.getTag() == Opcodes.H_INVOKESPECIAL) {
System.err.println("[Java8 Interface Downgrader] Found java interface missing stub: " + FullyQualifiedMemberNameAndDesc.of(handle));
warnings.add("Found java interface missing stub: " + FullyQualifiedMemberNameAndDesc.of(handle));
}
continue;
}
Expand Down Expand Up @@ -508,7 +509,7 @@ private void downgradeInterfaceAccesses(ClassNode clazz, Set<ClassNode> extra, F
internalName.startsWith("sun/") ||
internalName.startsWith("jdk/") ||
internalName.startsWith("com/sun/")) {
System.err.println("[Java8 Interface Downgrader] Found java interface default missing implementation: " + member.getKey().toFullyQualified(member.getValue()));
warnings.add("[Java8 Interface Downgrader] Found java interface default missing implementation: " + member.getKey().toFullyQualified(member.getValue()));
continue;
}
// create method redirecting to static default
Expand Down
2 changes: 1 addition & 1 deletion site/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import xyz.wagyourtail.gradle.shadow.ShadowJar

plugins {
kotlin("jvm") version "1.9.22"
kotlin("jvm")
application
}

Expand Down
35 changes: 19 additions & 16 deletions site/src/main/kotlin/xyz/wagyourtail/jvmdg/site/html/About.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,31 @@ class About : Template<HTML> {
head {
title("JvmDowngrader")
style {
+"""
body {
max-width: 800px;
margin:0 auto;
}
h1 {
text-align: center;
}
.user-del {
text-decoration: line-through;
}
""".trimIndent()
unsafe {
+"""
body {
max-width: 800px;
margin:0 auto;
}
h1 {
text-align: center;
}
.user-del {
text-decoration: line-through;
}
""".trimIndent()
}
}
link(rel = "stylesheet", href = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css")
script(src = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js") {}
script(src = "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/gradle.min.js") {}
// <script>hljs.highlightAll();</script>
script {
defer = true
+"""
hljs.highlightAll();
""".trimIndent()
unsafe {
+"""
hljs.highlightAll();
""".trimIndent()
}
}
}
body {
Expand Down
Loading

0 comments on commit 3514037

Please sign in to comment.