Skip to content

Commit

Permalink
use a flag if should use multi-release classes for downgrading
Browse files Browse the repository at this point in the history
  • Loading branch information
wagyourtail committed Oct 29, 2024
1 parent 4b9d180 commit be279ac
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,12 @@ interface DowngradeFlags: TransformParameters {
@get:Optional
val multiReleaseVersions: SetProperty<JavaVersion>

/**
* sets if should downgrade classess from the multi-release folder, instead of selecting the normal one
* @since 1.2.1
*/
@get:Input
@get:Optional
val downgradeFromMultiReleases: Property<Boolean>

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ fun DowngradeFlags.toFlags(): Flags {
flags.debugDumpClasses = debugDumpClasses.getOrElse(false)
flags.multiReleaseOriginal = multiReleaseOriginal.getOrElse(false)
flags.multiReleaseVersions = multiReleaseVersions.getOrElse(emptySet()).map { it.toOpcode() }.toSet()
flags.downgradeFromMultiReleases = downgradeFromMultiReleases.getOrElse(false)
if (this is ShadeFlags) {
flags.shadeInlining = shadeInlining.get()
}
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ kotlin.code.style=official
org.gradle.jvmargs=-Xmx4G
org.gradle.parallel=true

version=1.2.0
version=1.2.1

asm_version=9.7
asm_version=9.7.1

mainVersion=7
testVersion=21
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,11 @@ public byte[] apply(String s) {

@Override
protected int maxClassVersionSupported() {
return holder.maxVersion();
if (!holder.flags.downgradeFromMultiReleases) {
return Utils.getCurrentClassVersion();
} else {
return holder.maxVersion();
}
}

@Override
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/xyz/wagyourtail/jvmdg/cli/Flags.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ public class Flags {
*/
public Set<Integer> multiReleaseVersions = new HashSet<>(getMultiReleaseVersions());

/**
* if should downgrade classes from the multi-release folder, instead of selecting the normal one
*
* @since 1.2.1
*/
public boolean downgradeFromMultiReleases = false;

public Flags() {
getIgnoreWarnings();
}
Expand All @@ -124,6 +131,7 @@ public Flags copy() {
flags.debugDumpClasses = debugDumpClasses;
flags.multiReleaseOriginal = multiReleaseOriginal;
flags.multiReleaseVersions = new HashSet<>(multiReleaseVersions);
flags.downgradeFromMultiReleases = downgradeFromMultiReleases;
return flags;
}

Expand Down
110 changes: 69 additions & 41 deletions src/main/java/xyz/wagyourtail/jvmdg/compile/PathDowngrader.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ protected int maxClassVersionSupported() {
return downgrader.maxVersion();
}

@Override
protected List<String> multiVersionPrefixes() {
if (downgrader.flags.downgradeFromMultiReleases) {
return super.multiVersionPrefixes();
} else {
return Collections.singletonList("");
}
}

}) {
// zip input and output
for (int i = 0; i < inputRoots.size(); i++) {
Expand All @@ -76,6 +85,7 @@ protected int maxClassVersionSupported() {
for (int j = downgrader.maxVersion(); j >= 52; j--) {
multiReleasePaths.add("META-INF/versions/" + Utils.classVersionToMajorVersion(j));
}
final Set<Path> visitedClasses = new HashSet<>();

AsyncUtils.visitPathsAsync(in, new IOFunction<Path, Boolean>() {

Expand All @@ -92,27 +102,45 @@ public void accept(Path path) throws IOException {
Path relativized = in.relativize(path);
Path outFile = out.resolve(relativized.toString());
if (path.getFileName().toString().endsWith(".class")) {
if (!relativized.startsWith("META-INF/versions")) {
// prefer multi-release over normal

if (relativized.startsWith("META-INF/versions")) {
if (downgrader.flags.downgradeFromMultiReleases) {
relativized = relativized.subpath(3, relativized.getNameCount());
outFile = out.resolve(relativized);
} else {
return;
}
}

// dont if already visited
if (visitedClasses.contains(outFile)) {
return;
}

if (downgrader.flags.downgradeFromMultiReleases) {
// prefer highest multi-release
for (String pth : multiReleasePaths) {
if (Files.exists(in.resolve(pth).resolve(relativized))) {
path = in.resolve(pth).resolve(relativized);
break;
}
}
}

try {
String relativizedName = relativized.toString();
if (relativized.getFileSystem().getSeparator().equals("\\")) {
relativizedName = relativizedName.replace('\\', '/');
}
String internalName = relativizedName.substring(0, relativizedName.length() - 6);
byte[] bytes = Files.readAllBytes(path);
Map<String, byte[]> outputs = downgrader.downgrade(new AtomicReference<>(internalName), bytes, false, new Function<String, byte[]>() {
@Override
public byte[] apply(String s) {
try {
// multi-version
try {
String relativizedName = relativized.toString();
if (relativized.getFileSystem().getSeparator().equals("\\")) {
relativizedName = relativizedName.replace('\\', '/');
}
String internalName = relativizedName.substring(0, relativizedName.length() - 6);
byte[] bytes = Files.readAllBytes(path);
Map<String, byte[]> outputs = downgrader.downgrade(new AtomicReference<>(internalName), bytes, false, new Function<String, byte[]>() {
@Override
public byte[] apply(String s) {
try {

// multi-version
if (downgrader.flags.downgradeFromMultiReleases) {
for (String pth : multiReleasePaths) {
for (Path in : inputRoots) {
Path p = in.resolve(pth).resolve(s + ".class");
Expand All @@ -121,41 +149,41 @@ public byte[] apply(String s) {
}
}
}
}

// main version
for (Path in : inputRoots) {
Path p = in.resolve(s + ".class");
if (Files.exists(p)) {
return Files.readAllBytes(p);
}
// main version
for (Path in : inputRoots) {
Path p = in.resolve(s + ".class");
if (Files.exists(p)) {
return Files.readAllBytes(p);
}
}

URL url = extraClasspath.getResource(s + ".class");
if (url == null) return null;
try (InputStream is = url.openStream()) {
return Utils.readAllBytes(is);
}
} catch (IOException e) {
throw new RuntimeException(e);
URL url = extraClasspath.getResource(s + ".class");
if (url == null) return null;
try (InputStream is = url.openStream()) {
return Utils.readAllBytes(is);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
});
if (outputs == null) {
Files.copy(path, outFile, StandardCopyOption.REPLACE_EXISTING);
} else {
for (Map.Entry<String, byte[]> entry : outputs.entrySet()) {
String internal = entry.getKey();
Path p = out.resolve(internal + ".class");
Path parent = p.getParent();
if (parent != null) {
Files.createDirectories(parent);
}
Files.write(p, entry.getValue(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
}
});
if (outputs == null) {
Files.copy(path, outFile, StandardCopyOption.REPLACE_EXISTING);
} else {
for (Map.Entry<String, byte[]> entry : outputs.entrySet()) {
String internal = entry.getKey();
Path p = out.resolve(internal + ".class");
Path parent = p.getParent();
if (parent != null) {
Files.createDirectories(parent);
}
Files.write(p, entry.getValue(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
}
} catch (IllegalClassFormatException e) {
throw new IOException("Failed to downgrade " + path, e);
}
} catch (IllegalClassFormatException e) {
throw new IOException("Failed to downgrade " + path, e);
}
} else if (relativized.toString().equals("META-INF/MANIFEST.MF")) {
// add version number to manifest
Expand Down

0 comments on commit be279ac

Please sign in to comment.