Skip to content

Commit

Permalink
reformat code
Browse files Browse the repository at this point in the history
  • Loading branch information
wagyourtail committed Sep 19, 2024
1 parent 8cdaed4 commit 0715739
Show file tree
Hide file tree
Showing 274 changed files with 2,251 additions and 2,054 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build_snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
with:
name: gradle
path: gradle-plugin/build/libs

- uses: actions/upload-artifact@v4
with:
name: test-downgrade
Expand Down
7 changes: 2 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ build/
!**/src/test/**/build/

### IntelliJ IDEA ###
.idea/
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
.idea/**/*.xml
!.idea/codeStyles/*.xml
*.iws
*.iml
*.ipr
Expand Down
28 changes: 28 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/codeStyles/codeStyleConfig.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 11 additions & 5 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
## JvmDowngrader

Copyright (C) 2024 William Gray <[email protected]>

This program is provided under 2 licenses:

* [The GNU Lesser General Public License version 2.1](license/LGPLv2.1.md)
* [A Commercial And Support License Agreement](license/COMMERCIAL.md)

If you are a non-commercial user, it is recommended to use the LGPLv2.1 license, as it is more permissive and allows you to use the software for free.
If you are a commercial user, or need support with your use of the product, a commercial and support license is available for purchase by contacting me at the email address above.
If you are a non-commercial user, it is recommended to use the LGPLv2.1 license, as it is more permissive and allows you
to use the software for free.
If you are a commercial user, or need support with your use of the product, a commercial and support license is
available for purchase by contacting me at the email address above.

If you are a non-commercial user, or your usecase is covered by the LGPLv2.1 license,
If you are a non-commercial user, or your usecase is covered by the LGPLv2.1 license,
I would appreciate it if you would consider donating to support the project, but it is in no way required.

### LGPLv2.1 License Concerns

Some people think that shading would mean they're bound by the stricter GPL license due to the inclusion of jvmdowngrader's java class files. I don't believe this to be the case.
Some people think that shading would mean they're bound by the stricter GPL license due to the inclusion of
jvmdowngrader's java class files. I don't believe 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.
Expand Down
22 changes: 13 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ Downgrades modern java bytecode to older versions. at either compile or runtime.

This is currently capable of downgrading from Java 22 to Java 8. Java 7 may come in the future.

Currently attempting to downgrade to Java 7 will produce valid class files, but some of the API stubs are broken, and many common ones dont exist.
Currently attempting to downgrade to Java 7 will produce valid class files, but some of the API stubs are broken, and
many common ones dont exist.

### After downgrading you must either shade, or add the api jar to the classpath at runtime.

**It is recommended to use the shade task/cli as documented below, as it will only include necessary methods in your jar.**
**It is recommended to use the shade task/cli as documented below, as it will only include necessary methods in your
jar.**

alternatively, you can add the api jar in its entirety to the classpath when running the jar.

The api jar can be found at `xyz.wagyourtail.jvmdowngrader:jvmdowngrader-java-api:0.9.0:downgraded-8`
there is also a `downgraded-11` jar there.
there is also a `downgraded-11` jar there.

alternatively, to produce other versions you can generate one yourself using the cli:
`java -jar JvmDowngrader-all.jar -c 53 debug downgradeApi ./java-api-9.jar`
Expand Down Expand Up @@ -72,7 +74,8 @@ jvmdg.multiReleaseOriginal = false
jvmdg.multiReleaseVersions = [].toSet()
```

You can see more of what these values mean by [checking the docs on the flags classes](gradle-plugin/src/main/kotlin/xyz/wagyourtail/jvmdg/gradle/flags)
You can see more of what these values mean
by [checking the docs on the flags classes](gradle-plugin/src/main/kotlin/xyz/wagyourtail/jvmdg/gradle/flags)

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.
Expand All @@ -91,10 +94,11 @@ shadeDowngradedApi {
}
```

The tasks have all the same flags as the extension, so you can change them separately,
The tasks have all the same flags as the extension, so you can change them separately,
their default value is to use the global one from the extension.

If you are merging multiple downgraded jars, please merge from the downgradeJar tasks, and then shade on the resulting mono-jar.
If you are merging multiple downgraded jars, please merge from the downgradeJar tasks, and then shade on the resulting
mono-jar.
otherwise some API stubs may be missing, due to how shade only includes what is used.

Optionally, you can also depend on the shadeDowngradedApi task when running build.
Expand Down Expand Up @@ -147,7 +151,6 @@ it's computed from the `toDowngrade` files.

To depend on more modern jars on a lower java version you can downgrade the configuration.


```gradle
configurations {
downgrade
Expand All @@ -172,7 +175,7 @@ This is the expected usage of these functions.
running `shadeDowngradedApi`, as otherwise there may be duplicate jvmdg-api classes.
ie. `jvmdg.dg(configurations.downgrade, false)`

you may have to include whatever configuration you're downgrading in ShadowJar yourself.
you may have to include whatever configuration you're downgrading in ShadowJar yourself.
I do not automatically make the configuration shadowed into your output.

#### Including newer dependencies on lower java version building
Expand All @@ -186,6 +189,7 @@ you can disable this by setting `mavenPom` and `artifact` in the `metadataSource
to explicitly disable gradle metadata.

for example:

```gradle
repositories {
mavenCentral {
Expand Down Expand Up @@ -253,7 +257,7 @@ You can also create your own downgrading classloader, for more complicated envir
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ 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

@CacheableTask
abstract class CoverageRunTask : JavaExec() {
abstract class CoverageRunTask: JavaExec() {

@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
Expand Down Expand Up @@ -53,5 +51,4 @@ abstract class CoverageRunTask : JavaExec() {
super.exec()
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import java.nio.file.StandardOpenOption
import java.util.zip.ZipFile
import kotlin.io.path.*

abstract class GenerateCtSymTask : ConventionTask() {
abstract class GenerateCtSymTask: ConventionTask() {

@get:Optional
@get:OutputFile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import java.io.FilterReader
import java.io.Reader
import java.nio.charset.StandardCharsets

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

var remapper: PackageRelocator by MustSet()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package xyz.wagyourtail.gradle.shadow

import org.objectweb.asm.commons.Remapper

class PackageRelocator(val map: Map<String, String>) : Remapper() {
class PackageRelocator(val map: Map<String, String>): Remapper() {

override fun map(internalName: String): String {
for ((from, to) in map) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import org.gradle.api.tasks.TaskAction
import org.gradle.jvm.tasks.Jar
import java.nio.charset.StandardCharsets

abstract class ShadowJar : Jar() {
abstract class ShadowJar: Jar() {

@get:Internal
abstract val shadowContents: ListProperty<FileCollection>
Expand Down
78 changes: 49 additions & 29 deletions docs/Bytecode Manipulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,55 @@ This document describes the way in which JvmDowngrader manipulates the bytecode

## Overview

JvmDowngrader starts by initializing a [VersionProvider](/src/main/java/xyz/wagyourtail/jvmdg/version/VersionProvider.java) which is used to provide a downgrade between 2 sequential java versions.
This process is then chained until the desired version is reached.

The VersionProvider loads "Stubs", "Adapter" and "Modify" transforms which are used in the process of downgrading the bytecode.
The "Stubs" are simple method replacements, that replace either a method call or a field access with a call to a static method.
The "Modify" transforms allow for more complex changes to the bytecode, such as replacing InvokeDynamic calls with a newly constructed private
JvmDowngrader starts by initializing
a [VersionProvider](/src/main/java/xyz/wagyourtail/jvmdg/version/VersionProvider.java) which is used to provide a
downgrade between 2 sequential java versions.
This process is then chained until the desired version is reached.

The VersionProvider loads "Stubs", "Adapter" and "Modify" transforms which are used in the process of downgrading the
bytecode.
The "Stubs" are simple method replacements, that replace either a method call or a field access with a call to a static
method.
The "Modify" transforms allow for more complex changes to the bytecode, such as replacing InvokeDynamic calls with a
newly constructed private
method in the target class.
The "Adapter" transform replaces all class references with the target class.

## Version Provider

Classes can be added for processing in the VersionProvider's init method by calling `stub(Class<?>)` this will parse them for
Classes can be added for processing in the VersionProvider's init method by calling `stub(Class<?>)` this will parse
them for
`@Stub`, `@Modify` and `@Adapter` annotations and add them to the appropriate lists.

Additionally, the version provider allows for other wider scale transforms that need to be done in order to downgrade the bytecode by extending the
Additionally, the version provider allows for other wider scale transforms that need to be done in order to downgrade
the bytecode by extending the
`otherTransforms` method.

### Stubs

To create a stub, a method must be `public static` and annotated with [`@Stub`](/src/shared/java/xyz/wagyourtail/jvmdg/version/Stub.java).
the `@Stub` annotation by default will use the first argument of the method as the target class and treat it as a instance method replacement.
If the method is static, the `@Stub` annotation must be provided with an `@Ref` argument that specifies the target class, this will treat the method as a static method replacement.
To create a stub, a method must be `public static` and annotated with [
`@Stub`](/src/shared/java/xyz/wagyourtail/jvmdg/version/Stub.java).
the `@Stub` annotation by default will use the first argument of the method as the target class and treat it as a
instance method replacement.
If the method is static, the `@Stub` annotation must be provided with an `@Ref` argument that specifies the target
class, this will treat the method as a static method replacement.

In some rare circumstances the target class should be different from the first argument, in that case (or when any argument is needed to have it's type changed), the argument
In some rare circumstances the target class should be different from the first argument, in that case (or when any
argument is needed to have it's type changed), the argument
may be annotated with `@Coerce` which will change the type of the argument to the specified type.

Stubs have several other fields that change their behavior:

* `abstractDefault` indicates if a method was abstract in the target version but now has a default implementation,
this is used to determine if classes extending the target class need to also insert a reference to the stub.
references to this method will not be replaced with the stub, and are handled specially as described below.
this is used to determine if classes extending the target class need to also insert a reference to the stub.
references to this method will not be replaced with the stub, and are handled specially as described below.
* `requiresRuntime` indicates if the stub requires the JVMDowngrader runtime in order to work as intended,
mostly for things like reflection and runtime class definition.
mostly for things like reflection and runtime class definition.
* `noSpecial` indicates that the stub should not be used for `INVOKESPECIAL` calls.
* `downgradeVersion` adds an extra argument to the stub for the original version of the class, this is useful for multi-version stubs, such as reflection.
* `excludeChild` prevent a stub from being applied to a child-class of the target. for example, `String#isEmpty` is since java 6, but `CharSequence#isEmpty` is since java 15.
* `downgradeVersion` adds an extra argument to the stub for the original version of the class, this is useful for
multi-version stubs, such as reflection.
* `excludeChild` prevent a stub from being applied to a child-class of the target. for example, `String#isEmpty` is
since java 6, but `CharSequence#isEmpty` is since java 15.

### Modify

Expand All @@ -47,22 +61,26 @@ The `@Modify` annotation is provided with a `@Ref` argument that specifies the t
the method must be `public static` and have 1-4 arguments, matching these:
`MethodNode mnode, int i, ClassNode cnode, Set<ClassNode> extra`.

This is used to replace `INVOKEDYNAMIC` calls and to stub constructor calls, as `@Stub` would be unable to handle the super call within constructors.
This is used to replace `INVOKEDYNAMIC` calls and to stub constructor calls, as `@Stub` would be unable to handle the
super call within constructors.

### Adapter

The `@Adapter` annotation is used to replace all references to a class with a different class.
By default, it replaces the `value` class with the one it's annotated on, but it can be provided with a `target` class.
there is also a `keepInterface` field, if the stub is an interface, it can optionally be completely removed from classes referencing it.
there is also a `keepInterface` field, if the stub is an interface, it can optionally be completely removed from classes
referencing it.

### RequiresResource

This annotation is a hint to the Shading Api task that the class or method requires a resource from the api jar in order to operate.
This annotation is a hint to the Shading Api task that the class or method requires a resource from the api jar in order
to operate.
such as emoji data in the java 21 `Character` class.

### InvokeDynamic Method Insertion

If a stub does not exactly match the method descriptor of an invokedynamic method it is replacing, it may be necessary to wrap it with another method to adapt the types.
If a stub does not exactly match the method descriptor of an invokedynamic method it is replacing, it may be necessary
to wrap it with another method to adapt the types.
This is done automatically while stubbing handles in InvokeDynamic arguments.

### Abstract Method Insertion
Expand All @@ -73,18 +91,20 @@ already implement the stubbed method themselves, or in a super class.

### Other Transforms

The `otherTransforms` method is used to apply wider scale transforms to the bytecode, such as replacing all references to a class with a different class.
The `otherTransforms` method is used to apply wider scale transforms to the bytecode, such as replacing all references
to a class with a different class.
the current list of transforms is:

* Java 17->16
* Add a `@PermittedSubClasses` annotation to sealed classes
* Add a `@PermittedSubClasses` annotation to sealed classes
* Java 16->15
* Remove ACC_RECORD
* Remove ACC_RECORD
* Java 11->10
* Add a `@NestHost` annotation to nest members
* Add a `@NestMembers` annotation to nest hosts
* Insert sythetic "bridge" methods so that private fields/methods can be called from nest members.
* Add a `@NestHost` annotation to nest members
* Add a `@NestMembers` annotation to nest hosts
* Insert sythetic "bridge" methods so that private fields/methods can be called from nest members.
* Java 9->8
* Make private interface methods use `INVOKESPECIAL` instead of `INVOKEINTERFACE`.
* Make private interface methods use `INVOKESPECIAL` instead of `INVOKEINTERFACE`.
* Java 8->7
* Move private/default methods in interfaces to a `$jvmdg$StaticDefaults` inner class.
* Move private/default methods in interfaces to a `$jvmdg$StaticDefaults` inner class.

Loading

0 comments on commit 0715739

Please sign in to comment.