Skip to content

Commit

Permalink
optimize imports and reformat code
Browse files Browse the repository at this point in the history
  • Loading branch information
wagyourtail committed May 23, 2024
1 parent db1938b commit c129a73
Show file tree
Hide file tree
Showing 213 changed files with 1,438 additions and 1,607 deletions.
6 changes: 3 additions & 3 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
JvmDowngrader
Copyright (C) 2024 William Gray <william.gray@wagyourtail.xyz>
Copyright (C) 2024 William Gray <william.gray@wagyourtail.xyz>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
Expand All @@ -8,12 +8,12 @@ version 2.1 of the License, or (at your option) any later version.

This library 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
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA

===============================================================================
Expand Down
34 changes: 24 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ downgrades modern java bytecode to older versions. at either compile or runtime.
## Gradle Plugin

This downgrades the output of a jar task using another task.
Note that certain things like reflection and dynamic class definition downgrading will not work without runtime downgrading.
Note that certain things like reflection and dynamic class definition downgrading will not work without runtime
downgrading.
dynamic class definitions being things like `MethodHandles$Lookup#defineClass` and classloader shenanigans.

add my maven in `settings.gradle`:

```gradle
pluginManagement {
repositories {
Expand All @@ -26,6 +28,7 @@ pluginManagement {
```

in `build.gradle`:

```gradle
// add the plugin
plugins {
Expand All @@ -44,10 +47,13 @@ jvmdg.asmVersion = "9.7" // default
```

This will create a default downgrade task for `jar` (or `shadowJar` if present) called `downgradeJar` that will downgrade the output to java 8 by default.
as well as a `shadeDowngradedApi` to then insert the required classes for not having a runtime dependency on the api jar.
This will create a default downgrade task for `jar` (or `shadowJar` if present) called `downgradeJar` that will
downgrade the output to java 8 by default.
as well as a `shadeDowngradedApi` to then insert the required classes for not having a runtime dependency on the api
jar.

you can change the downgrade version by doing:

```gradle
downgradeJar {
downgradeVersion = JavaVersion.VERSION_1_11
Expand All @@ -61,11 +67,13 @@ shadeDowngradedApi {
```

Optionally, you can also depend on the sahdeDowngradedApi task when running build.

```gradle
assemble.dependsOn shadeDowngradedApi
```

you can create a custom task by doing:

```gradle
task customDowngrade(type: xyz.wagyourtail.jvmdg.gradle.task.DowngradeJar) {
inputFile = tasks.jar.archiveFile
Expand Down Expand Up @@ -93,7 +101,8 @@ task customShadeDowngradedApi(type: xyz.wagyourtail.jvmdg.gradle.task.ShadeApi)
### Zip/Path Downgrading

Downgrades the contents of a zip file or path to an older version.
you can specify multiple targets for bulk operations. (and they will include eachother in classpath searches during downgrading)
you can specify multiple targets for bulk operations. (and they will include eachother in classpath searches during
downgrading)

ex. `java -jar JvmDowngrader-all.jar -c 52 downgrade -t input.jar output.jar -cp classpath.jar -cp classpath2.jar`

Expand All @@ -110,48 +119,53 @@ The class version can be replaced with a path to the pre-downgraded api jar to s

Some people think that shading would mean they're bound by the stricter GPL license. I don't belive this to be the case.

For the purpose of Licensing, the produced jar from this task, or the downgrading task, should be considered a "Combined Work",
For the purpose of Licensing, the produced jar from this task, or the downgrading task, should be considered a "Combined
Work",
as it contains the original code from the input jar and the shaded code from jvmdowngrader's api.

And this does, usually, mean that you shouldn't need to use the *exact* same license.
Running this tool, should be a thing the end-user is capable of doing, thus section 6.a should be satisfied as long as
your project provides the unshaded/undowngraded jar as well, or alternatively provides source code to build said jar, or the post-shaded jar.
your project provides the unshaded/undowngraded jar as well, or alternatively provides source code to build said jar, or
the post-shaded jar.

## Runtime Downgrading

This is basically only here so I can take funny screenshots of minecraft running on java 8.
I recommend the agent method, as it's most reliable.

### Agent Downgrading

Uses the java agent to downgrade at runtime.

ex. `java -javaagent:JvmDowngrader-all.jar -jar myapp.jar`

### Bootstrap Downgrading

Uses the bootstrap main class

ex. `java -jar JvmDowngrader-all.jar bootstrap -cp myapp.jar;classpath.jar;classpath2.jar --main mainclass args`


## From Code

### Downgrading ClassLoader

This is what the bootstrap downgrader essentially uses internally.

```groovy
// add jar to default downgrading classloader
ClassDowngrader.getCurrentVersionDowngrader().getClassLoader().addDelegate(new URL[] { new File("jarname.jar").toURI().toURL() });
ClassDowngrader.getCurrentVersionDowngrader().getClassLoader().addDelegate(new URL[]{new File("jarname.jar").toURI().toURL()});
// call main method
ClassDowngrader.getCurrentVersionDowngrader().getClassLoader().loadClass("mainclass").getMethod("main", String[].class).invoke(null, new Object[] { new String[] { "args" } });
ClassDowngrader.getCurrentVersionDowngrader().getClassLoader().loadClass("mainclass").getMethod("main", String[].class).invoke(null, new Object[]{new String[]{"args"}});
```

You can also create your own downgrading classloader, for more complicated environments.

```groovy
DowngradingClassLoader loader = new DowngradingClassLoader(ClassDowngrader.getCurrentVersionDowngrader(), parent);
// adding jars
loader.addDelegate(new URL[] { new File("jarname.jar").toURI().toURL() });
loader.addDelegate(new URL[]{new File("jarname.jar").toURI().toURL()});
```

### inspired by
Expand Down
3 changes: 2 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ allprojects {
}
}

version = if (project.hasProperty("version_snapshot")) "${project.properties["version"]}-SNAPSHOT" else project.properties["version"] as String
version =
if (project.hasProperty("version_snapshot")) "${project.properties["version"]}-SNAPSHOT" else project.properties["version"] as String
group = project.properties["maven_group"] as String

base {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,15 @@ abstract class GenerateCtSymTask : ConventionTask() {
val toolchain = project.extensions.getByType(JavaToolchainService::class.java)


ZipArchiveOutputStream(ctSym.toPath().outputStream(StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)).use { zos ->
ZipArchiveOutputStream(
ctSym.toPath().outputStream(StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)
).use { zos ->
val prevJava = mutableMapOf<String, ClassInfo>()
for (java in (JavaVersion.VERSION_1_6..JavaVersion.VERSION_22).reversed()) {
val home = toolchain.getJavaHome(java)
project.logger.lifecycle("[ct.sym] Processing $java at $home")
for (path in home.walk().filter { it.exists() && it.isRegularFile() && it.extension in setOf("jar", "jmod") }) {
for (path in home.walk()
.filter { it.exists() && it.isRegularFile() && it.extension in setOf("jar", "jmod") }) {
if (path.extension == "jar" && path.nameWithoutExtension != "rt") continue
// for each jar/jmod list its contents
project.logger.info("[ct.sym] Found ${path.fileName}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.FilterReader
import java.io.Reader
import java.nio.CharBuffer
import java.nio.charset.StandardCharsets

class PackageRelocateReader(input: Reader): FilterReader(input) {
class PackageRelocateReader(input: Reader) : FilterReader(input) {

var remapper: PackageRelocator by MustSet()

Expand All @@ -22,7 +21,7 @@ class PackageRelocateReader(input: Reader): FilterReader(input) {
input.close()
out.toByteArray()
}

val changedContents: Reader by lazy {
val reader = ClassReader(contents)
val writer = ClassWriter(0)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package xyz.wagyourtail.downgradetest;

import java.util.function.Function;
import java.util.function.Supplier;

public class TestException {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@ static void main(String[] args) {
test3();
}

default void test2() {
test();
}

private void test() {
System.out.println("test");
}

static void test3() {
System.out.println("test3" + 4);

Expand All @@ -40,4 +32,12 @@ static void test3() {
}
}

default void test2() {
test();
}

private void test() {
System.out.println("test");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,47 @@ public class TestStream {
public static void main(String[] args) {

DoubleStream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.mapMulti((d, dc) -> {
dc.accept(d);
dc.accept(d * 2);
dc.accept(d * 3);
}).mapToObj(Double::toString)
.forEach(System.out::print);
.mapMulti((d, dc) -> {
dc.accept(d);
dc.accept(d * 2);
dc.accept(d * 3);
}).mapToObj(Double::toString)
.forEach(System.out::print);
System.out.println();

IntStream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.mapMulti((d, dc) -> {
dc.accept(d);
dc.accept(d * 2);
dc.accept(d * 3);
}).mapToObj(Integer::toString)
.forEach(System.out::print);
.mapMulti((d, dc) -> {
dc.accept(d);
dc.accept(d * 2);
dc.accept(d * 3);
}).mapToObj(Integer::toString)
.forEach(System.out::print);
System.out.println();

LongStream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.mapMulti((d, dc) -> {
dc.accept(d);
dc.accept(d * 2);
dc.accept(d * 3);
}).mapToObj(Long::toString)
.forEach(System.out::print);
.mapMulti((d, dc) -> {
dc.accept(d);
dc.accept(d * 2);
dc.accept(d * 3);
}).mapToObj(Long::toString)
.forEach(System.out::print);
System.out.println();

DoubleStream.of(1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
.takeWhile(d -> d % 10 < 4)
.mapToObj(Double::toString)
.forEach(System.out::print);
.takeWhile(d -> d % 10 < 4)
.mapToObj(Double::toString)
.forEach(System.out::print);
System.out.println();

IntStream.of(1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
.dropWhile(d -> d % 10 < 4)
.mapToObj(Integer::toString)
.forEach(System.out::print);
.dropWhile(d -> d % 10 < 4)
.mapToObj(Integer::toString)
.forEach(System.out::print);
System.out.println();

DoubleStream.iterate(0, d -> d < 10, d -> d + 1)
.mapToObj(Double::toString)
.forEach(System.out::print);
.mapToObj(Double::toString)
.forEach(System.out::print);
System.out.println();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ public static void main(String[] args) {
System.out.println(a + b + "ccc");

System.out.println("""
This is a test
\t \tof the new multiline
string literal
""".stripIndent());
This is a test
\t \tof the new multiline
string literal
""".stripIndent());

System.out.println("this is a \\t test \\\" \\n ".translateEscapes());
System.out.println("test %s".formatted("test2"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import org.gradle.jvm.tasks.Jar
import org.jetbrains.annotations.ApiStatus
import xyz.wagyourtail.jvmdg.ClassDowngrader
import xyz.wagyourtail.jvmdg.cli.Flags
import xyz.wagyourtail.jvmdg.compile.ApiShader
import xyz.wagyourtail.jvmdg.compile.ZipDowngrader
import xyz.wagyourtail.jvmdg.gradle.task.DowngradeJar
import xyz.wagyourtail.jvmdg.gradle.task.ShadeAPI
Expand All @@ -15,10 +14,6 @@ import xyz.wagyourtail.jvmdg.util.LazyMutable
import xyz.wagyourtail.jvmdg.util.defaultedMapOf
import xyz.wagyourtail.jvmdg.util.toOpcode
import java.io.File
import java.nio.file.StandardOpenOption
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
import kotlin.io.path.outputStream

abstract class JVMDowngraderExtension(val project: Project) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package xyz.wagyourtail.jvmdg.gradle
import org.gradle.api.Plugin
import org.gradle.api.Project

class JVMDowngraderPlugin: Plugin<Project> {
class JVMDowngraderPlugin : Plugin<Project> {

override fun apply(project: Project) {
project.extensions.create("jvmdg", JVMDowngraderExtension::class.java, project)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import xyz.wagyourtail.jvmdg.compile.PathDowngrader
import xyz.wagyourtail.jvmdg.gradle.JVMDowngraderExtension
import xyz.wagyourtail.jvmdg.util.*
import java.nio.file.FileSystem
import kotlin.io.path.*
import kotlin.io.path.exists
import kotlin.io.path.isDirectory
import kotlin.io.path.name

abstract class DowngradeFiles : ConventionTask() {
private val jvmdg by lazy {
Expand Down Expand Up @@ -73,17 +75,21 @@ abstract class DowngradeFiles : ConventionTask() {

outputs.files.forEach { it.deleteRecursively() }

val downgraded = toDowngrade.map { temporaryDir.resolve(it.name) }.map { if (it.extension == "jar" || it.extension == "zip") {
val fs = Utils.openZipFileSystem(it.toPath(), mapOf("create" to "true"))
fileSystems.add(fs)
fs.getPath("/")
} else it.toPath() }

toDowngrade = toDowngrade.map { if (it.isDirectory()) it else run {
val fs = Utils.openZipFileSystem(it, mapOf())
fileSystems.add(fs)
fs.getPath("/")
} }
val downgraded = toDowngrade.map { temporaryDir.resolve(it.name) }.map {
if (it.extension == "jar" || it.extension == "zip") {
val fs = Utils.openZipFileSystem(it.toPath(), mapOf("create" to "true"))
fileSystems.add(fs)
fs.getPath("/")
} else it.toPath()
}

toDowngrade = toDowngrade.map {
if (it.isDirectory()) it else run {
val fs = Utils.openZipFileSystem(it, mapOf())
fileSystems.add(fs)
fs.getPath("/")
}
}
ClassDowngrader.downgradeTo(flags).use {
PathDowngrader.downgradePaths(it, toDowngrade, downgraded, classpath.map { it.toURI().toURL() }.toSet())
}
Expand Down
Loading

0 comments on commit c129a73

Please sign in to comment.