Skip to content
Permalink
Browse files
8278205: jlink plugins should dump .class file in debug mode
Reviewed-by: jlaskey
  • Loading branch information
sundararajana committed Dec 3, 2021
1 parent 18c54b4 commit ba2a8e5a496799451095362279b9dd4b6df20b67
Showing 5 changed files with 41 additions and 6 deletions.
@@ -78,7 +78,7 @@
* ## Should use jdk.joptsimple some day.
*/
public class JlinkTask {
static final boolean DEBUG = Boolean.getBoolean("jlink.debug");
public static final boolean DEBUG = Boolean.getBoolean("jlink.debug");

// jlink API ignores by default. Remove when signing is implemented.
static final boolean IGNORE_SIGNING_DEFAULT = true;
@@ -26,10 +26,16 @@
package jdk.tools.jlink.internal.plugins;

import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.internal.JlinkTask;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import jdk.internal.org.objectweb.asm.ClassReader;

public abstract class AbstractPlugin implements Plugin {

@@ -61,6 +67,35 @@ protected AbstractPlugin(String name, ResourceBundle bundle) {
this.name = name;
this.pluginsBundle = bundle;
}

private void dumpClassFile(String path, byte[] buf) {
try {
String fullPath = String.format("%d-%s%s%s",
ProcessHandle.current().pid(),
getName(), File.separator,
path.replace('/', File.separatorChar));
System.err.printf("Dumping class file %s\n", fullPath);
new File(fullPath.substring(0, fullPath.lastIndexOf('/'))).mkdirs();
Files.write(Paths.get(fullPath), buf);
} catch (IOException ioExp) {
System.err.println("writing " + path + " failed");
ioExp.printStackTrace();
}
}

protected ClassReader newClassReader(String path, byte[] buf) {
try {
return new ClassReader(buf);
} catch (IllegalArgumentException iae) {
if (JlinkTask.DEBUG) {
System.err.printf("Failed to parse class file: %s\n", path);
iae.printStackTrace();
dumpClassFile(path, buf);
}
throw iae;
}
}

@Override
public String getName() {
return name;
@@ -158,7 +158,7 @@ public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
if (resource != null &&
resource.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
byte[] bytes = resource.contentBytes();
ClassReader cr = new ClassReader(bytes);
ClassReader cr = newClassReader(path, bytes);
if (Arrays.stream(cr.getInterfaces())
.anyMatch(i -> i.contains(METAINFONAME)) &&
stripUnsupportedLocales(bytes, cr)) {
@@ -59,7 +59,7 @@ public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
if (path.endsWith("module-info.class")) {
// XXX. Do we have debug info? Is Asm ready for module-info?
} else {
ClassReader reader = new ClassReader(resource.contentBytes());
ClassReader reader = newClassReader(path, resource.contentBytes());
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
reader.accept(writer, ClassReader.SKIP_DEBUG);
byte[] content = writer.toByteArray();
@@ -96,9 +96,9 @@ public void configure(Map<String, String> config) {

private boolean redefined = false;

private byte[] redefine(byte[] classFile) {
private byte[] redefine(String path, byte[] classFile) {

var cr = new ClassReader(classFile);
var cr = newClassReader(path, classFile);
var cw = new ClassWriter(0);

cr.accept(new ClassVisitor(Opcodes.ASM7, cw) {
@@ -189,7 +189,7 @@ public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
in.transformAndCopy(res -> {
if (res.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
if (res.path().equals(VERSION_PROPS_CLASS)) {
return res.copyWithContent(redefine(res.contentBytes()));
return res.copyWithContent(redefine(res.path(), res.contentBytes()));
}
}
return res;

1 comment on commit ba2a8e5

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on ba2a8e5 Dec 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.