Migrated project to Java 17 and use JavaDowngrader gradle plugin to target Java 8

This commit is contained in:
RaphiMC 2023-09-04 19:36:24 +02:00
parent bb471009f4
commit 1fbfc2765f
No known key found for this signature in database
GPG Key ID: 0F6BB0657A03AC94
8 changed files with 84 additions and 150 deletions

View File

@ -1,25 +1,37 @@
import net.raphimc.javadowngrader.gradle.task.DowngradeJarTask
buildscript {
repositories {
maven {
name = "Lenni0451 Releases"
url "https://maven.lenni0451.net/releases"
}
maven {
name = "Lenni0451 Snapshots"
url "https://maven.lenni0451.net/snapshots"
}
}
dependencies {
classpath "net.raphimc.javadowngrader:gradle-plugin:1.0.0"
}
}
plugins {
id "java"
id "application"
id "maven-publish"
id "net.kyori.blossom" version "2.0.1"
id "net.kyori.blossom" version "1.3.1"
}
sourceSets {
java17compat
}
base {
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
compileJava.options.encoding = compileTestJava.options.encoding = javadoc.options.encoding = "UTF-8"
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
[compileJava, compileTestJava, compileJava17compatJava].each {
it.options.encoding = "UTF-8"
it.sourceCompatibility = JavaVersion.VERSION_1_8
it.targetCompatibility = JavaVersion.VERSION_1_8
group = project.maven_group ?: rootProject.maven_group
archivesName = project.maven_name ?: rootProject.maven_name
version = project.maven_version ?: rootProject.maven_version
}
javadoc.options.encoding = "UTF-8"
group = project.maven_group
archivesBaseName = project.maven_name
version = project.maven_version
configurations {
include
@ -35,7 +47,7 @@ repositories {
url = "https://jitpack.io"
}
maven {
name = "Lenni0451"
name = "Lenni0451 Releases"
url "https://maven.lenni0451.net/releases"
}
maven {
@ -58,24 +70,9 @@ repositories {
name = "Minecraft Libraries"
url "https://libraries.minecraft.net"
}
ivy { // This workaround is needed as gradle does not allow to include Java 17 dependencies in a Java 8 project
name = "Mojang"
url "https://libraries.minecraft.net"
patternLayout {
artifact MAVEN_ARTIFACT_PATTERN
}
metadataSources {
it.artifact()
}
content {
includeGroup "com/mojang"
}
}
}
dependencies {
compileOnly sourceSets.java17compat.output
include "com.viaversion:viaversion:4.8.0-23w35a-SNAPSHOT"
include("com.viaversion:viabackwards-common:4.8.0-23w35a-SNAPSHOT") {
exclude group: "com.viaversion", module: "viaversion"
@ -102,10 +99,12 @@ dependencies {
include "net.sf.jopt-simple:jopt-simple:5.0.4"
include "org.apache.logging.log4j:log4j-core:2.20.0"
include "org.apache.logging.log4j:log4j-slf4j-impl:2.20.0"
include "com/mojang:authlib:3.16.29"
include "net.lenni0451.classtransform:mixinstranslator:1.10.1"
include "net.lenni0451.classtransform:mixinsdummy:1.10.1"
include "net.lenni0451.classtransform:additionalclassprovider:1.10.1"
include("com.mojang:authlib:3.16.29") {
exclude group: "org.slf4j", module: "slf4j-api"
}
include "net.lenni0451.classtransform:mixinstranslator:1.11.0-SNAPSHOT"
include "net.lenni0451.classtransform:mixinsdummy:1.11.0-SNAPSHOT"
include "net.lenni0451.classtransform:additionalclassprovider:1.11.0-SNAPSHOT"
include "net.lenni0451:Reflect:1.2.4"
include "net.lenni0451:LambdaEvents:2.2.0"
include "net.raphimc.netminecraft:all:2.3.6-SNAPSHOT"
@ -113,9 +112,9 @@ dependencies {
exclude group: "com.google.code.gson", module: "gson"
exclude group: "org.slf4j", module: "slf4j-api"
}
include("net.raphimc.javadowngrader:core:1.0.0-SNAPSHOT") {
exclude group: "org.slf4j", module: "slf4j-api"
include("net.raphimc.javadowngrader:impl-classtransform:1.0.0") {
exclude group: "org.ow2.asm", module: "asm-commons"
exclude group: "net.lenni0451.classtransform", module: "core"
}
include("org.cloudburstmc.netty:netty-transport-raknet:1.0.0.CR1-SNAPSHOT") {
exclude group: "io.netty", module: "netty-common"
@ -153,12 +152,12 @@ jar {
attributes(
"Main-Class": application.mainClass,
"Multi-Release": "true",
"Launcher-Agent-Class": "net.raphimc.viaproxy.ViaProxy"
"Launcher-Agent-Class": application.mainClass
)
}
from("LICENSE") {
rename { "${it}_${project.archivesBaseName}" }
rename { "${it}_${project.name ?: rootProject.name}" }
}
}
@ -206,3 +205,11 @@ publishing {
}
}
}
tasks.register("java8Jar", DowngradeJarTask) {
input = tasks.jar.archiveFile.get().asFile
outputSuffix = "+java8"
compileClassPath = sourceSets.main.compileClasspath
copyRuntimeClasses = false
}.get().dependsOn("build")
build.finalizedBy("java8Jar")

View File

@ -1,9 +1,7 @@
# Gradle properties
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
# Project properties
maven_name=ViaProxy
maven_group=net.raphimc
maven_name=ViaProxy
maven_version=3.0.21-SNAPSHOT

View File

@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -1,37 +0,0 @@
/*
* This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy
* Copyright (C) 2023 RK_01/RaphiMC and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package java.lang;
/**
* Dummy class to make IntelliJ able to access records in Java 8 code.
*/
public abstract class Record {
protected Record() {
}
@Override
public abstract boolean equals(Object obj);
@Override
public abstract int hashCode();
@Override
public abstract String toString();
}

View File

@ -35,7 +35,6 @@ import net.raphimc.netminecraft.constants.MCPipeline;
import net.raphimc.netminecraft.netty.connection.NetServer;
import net.raphimc.viaproxy.cli.ConsoleHandler;
import net.raphimc.viaproxy.cli.options.Options;
import net.raphimc.viaproxy.injection.Java17ToJava8;
import net.raphimc.viaproxy.plugins.PluginManager;
import net.raphimc.viaproxy.plugins.events.Client2ProxyHandlerCreationEvent;
import net.raphimc.viaproxy.plugins.events.ProxyStartEvent;
@ -74,7 +73,6 @@ public class ViaProxy {
final IClassProvider classProvider = new GuavaClassPathProvider();
final TransformerManager transformerManager = new TransformerManager(classProvider);
transformerManager.addTransformerPreprocessor(new MixinsTranslator());
transformerManager.addBytecodeTransformer(new Java17ToJava8(transformerManager).addWhitelistedPackage("com.mojang"));
transformerManager.addTransformer("net.raphimc.viaproxy.injection.transformer.**");
transformerManager.addTransformer("net.raphimc.viaproxy.injection.mixins.**");
if (instrumentation != null) {
@ -103,6 +101,14 @@ public class ViaProxy {
Logger.LOGGER.info("Available memory (bytes): " + Runtime.getRuntime().maxMemory());
if (System.getProperty("ignoreSystemRequirements") == null) {
if ("32".equals(System.getProperty("sun.arch.data.model")) && Runtime.getRuntime().maxMemory() < 256 * 1024 * 1024) {
Logger.LOGGER.fatal("ViaProxy is not able to run on 32bit Java.");
if (hasUI) {
JOptionPane.showMessageDialog(null, "ViaProxy is not able to run on 32bit Java. Please install 64bit Java", "ViaProxy", JOptionPane.ERROR_MESSAGE);
}
System.exit(1);
}
if (Runtime.getRuntime().maxMemory() < 256 * 1024 * 1024) {
Logger.LOGGER.fatal("ViaProxy is not able to run with less than 256MB of RAM.");
if (hasUI) {

View File

@ -19,68 +19,21 @@ package net.raphimc.viaproxy.injection;
import net.lenni0451.classtransform.TransformerManager;
import net.lenni0451.classtransform.transformer.IBytecodeTransformer;
import net.lenni0451.classtransform.utils.ASMUtils;
import net.lenni0451.classtransform.utils.tree.ClassTree;
import net.lenni0451.classtransform.utils.tree.IClassProvider;
import net.raphimc.javadowngrader.JavaDowngrader;
import org.objectweb.asm.tree.ClassNode;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
/**
* This class should not be used anymore. ViaProxy does now automatically downgrade all plugins to the current java version.
*/
@Deprecated
public class Java17ToJava8 implements IBytecodeTransformer {
private final ClassTree classTree;
private final IClassProvider classProvider;
private final int nativeClassVersion;
private final List<String> whitelistedPackages = new ArrayList<>();
public Java17ToJava8(final ClassTree classTree, final IClassProvider classProvider) {
this.classTree = classTree;
this.classProvider = classProvider;
final String classVersion = System.getProperty("java.class.version");
final String[] versions = classVersion.split("\\.");
final int majorVersion = Integer.parseInt(versions[0]);
final int minorVersion = Integer.parseInt(versions[1]);
this.nativeClassVersion = minorVersion << 16 | majorVersion;
}
@Deprecated
public Java17ToJava8(final TransformerManager transformerManager) {
this(transformerManager.getClassTree(), transformerManager.getClassProvider());
}
public Java17ToJava8 addWhitelistedPackage(final String packageName) {
this.whitelistedPackages.add(packageName);
return this;
}
@Deprecated
@Override
public byte[] transform(final String className, final byte[] bytecode, final boolean calculateStackMapFrames) {
if (ByteBuffer.wrap(bytecode, 4, 4).getInt() <= this.nativeClassVersion) {
return null;
}
if (!this.whitelistedPackages.isEmpty()) {
int dotIndex = className.lastIndexOf('.');
if (dotIndex == -1 && !this.whitelistedPackages.contains("")) return null;
String pkg = className.substring(0, dotIndex);
while (!this.whitelistedPackages.contains(pkg)) {
dotIndex = pkg.lastIndexOf('.');
if (dotIndex == -1) return null;
pkg = pkg.substring(0, dotIndex);
}
}
final ClassNode classNode = ASMUtils.fromBytes(bytecode);
JavaDowngrader.downgrade(classNode, this.nativeClassVersion);
if (calculateStackMapFrames) {
return ASMUtils.toBytes(classNode, this.classTree, this.classProvider);
} else {
return ASMUtils.toStacklessBytes(classNode);
}
public byte[] transform(String className, byte[] bytecode, boolean calculateStackMapFrames) {
return null;
}
}

View File

@ -25,6 +25,7 @@ import net.lenni0451.classtransform.utils.tree.IClassProvider;
import net.lenni0451.lambdaevents.LambdaManager;
import net.lenni0451.lambdaevents.generator.LambdaMetaFactoryGenerator;
import net.lenni0451.reflect.stream.RStream;
import net.raphimc.javadowngrader.impl.classtransform.JavaDowngraderTransformer;
import net.raphimc.viaproxy.ViaProxy;
import net.raphimc.viaproxy.util.URLClassProvider;
import net.raphimc.viaproxy.util.logging.Logger;
@ -90,6 +91,7 @@ public class PluginManager {
private static void loadAndScanJar(final File file) throws Throwable {
final URL url = file.toURI().toURL();
final TransformerManager transformerManager = new TransformerManager(new URLClassProvider(ROOT_CLASS_PROVIDER, url));
transformerManager.addBytecodeTransformer(new JavaDowngraderTransformer(transformerManager));
final InjectionClassLoader loader = new InjectionClassLoader(transformerManager, PluginManager.class.getClassLoader(), url);
final InputStream viaproxyYml = loader.getResourceAsStream("viaproxy.yml");
if (viaproxyYml == null) throw new IllegalStateException("Plugin '" + file.getName() + "' does not have a viaproxy.yml");

View File

@ -75,11 +75,12 @@ public class UpdateCheckTask implements Runnable {
if (updateAvailable) {
Logger.LOGGER.warn("You are running an outdated version of ViaProxy! Latest version: " + latestVersion);
if (this.hasUI) {
final boolean runsJava8 = System.getProperty("java.version").startsWith("1.8");
JsonArray assets = object.getAsJsonArray("assets");
boolean found = false;
for (JsonElement asset : assets) {
JsonObject assetObject = asset.getAsJsonObject();
if (this.isViaProxyJar(object, assetObject)) {
if ((this.isMainViaProxyJar(object, assetObject) && !runsJava8) || this.isJava8ViaProxyJar(object, assetObject) && runsJava8) {
found = true;
SwingUtilities.invokeLater(() -> this.showUpdateQuestion(assetObject.get("name").getAsString(), assetObject.get("browser_download_url").getAsString(), latestVersion));
break;
@ -100,18 +101,16 @@ public class UpdateCheckTask implements Runnable {
int chosen = JOptionPane.showConfirmDialog(ViaProxy.ui, "You are running an outdated version of ViaProxy!\nCurrent version: " + VERSION + "\nLatest version: " + latestVersion + "\n\nDo you want to update?", "ViaProxy", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (chosen == JOptionPane.YES_OPTION) {
File f = new File(name);
new DownloadPopup(ViaProxy.ui, downloadUrl, f, () -> {
SwingUtilities.invokeLater(() -> {
JOptionPane.showMessageDialog(ViaProxy.ui, "Downloaded the latest version of ViaProxy!\nPress OK to restart.", "ViaProxy", JOptionPane.INFORMATION_MESSAGE);
try {
Runtime.getRuntime().exec(new String[]{System.getProperty("java.home") + "/bin/java", "-jar", f.getAbsolutePath()});
System.exit(0);
} catch (IOException e) {
Logger.LOGGER.error("Could not start the new ViaProxy jar", e);
ViaProxy.ui.showException(e);
}
});
}, t -> {
new DownloadPopup(ViaProxy.ui, downloadUrl, f, () -> SwingUtilities.invokeLater(() -> {
JOptionPane.showMessageDialog(ViaProxy.ui, "Downloaded the latest version of ViaProxy!\nPress OK to restart.", "ViaProxy", JOptionPane.INFORMATION_MESSAGE);
try {
Runtime.getRuntime().exec(new String[]{System.getProperty("java.home") + "/bin/java", "-jar", f.getAbsolutePath()});
System.exit(0);
} catch (IOException e) {
Logger.LOGGER.error("Could not start the new ViaProxy jar", e);
ViaProxy.ui.showException(e);
}
}), t -> {
if (t != null) {
Logger.LOGGER.error("Could not download the latest version of ViaProxy", t);
ViaProxy.ui.showException(t);
@ -120,8 +119,12 @@ public class UpdateCheckTask implements Runnable {
}
}
private boolean isViaProxyJar(final JsonObject root, final JsonObject assetObject) {
private boolean isMainViaProxyJar(final JsonObject root, final JsonObject assetObject) {
return assetObject.get("name").getAsString().equals(root.get("name").getAsString() + ".jar");
}
private boolean isJava8ViaProxyJar(final JsonObject root, final JsonObject assetObject) {
return assetObject.get("name").getAsString().equals(root.get("name").getAsString() + "+java8.jar");
}
}