This is fairly straight forward. The small amount of javascript code calls into a helper method already written in JSJavaScriptEngine.java, so mostly it's just moving this java code to CommandProcessor.java, and reworking it a bit:
From sa.js:
this.dclass = function(clazz, dir) {
if (!clazz) {
writeln("Usage: dumpclass { address | name } [ directory ]");
} else {
if (!dir) { dir = "."; }
dumpClass(clazz, dir);
}
}
registerCommand("dumpclass", "dumpclass { address | name } [ directory ]", "dclass");
From JSJavaScriptEngine.java:
public Object dumpClass(Object[] args) {
if (args.length == 0) {
return Boolean.FALSE;
}
Object clazz = args[0];
if (clazz == null) {
return Boolean.FALSE;
}
InstanceKlass ik = null;
if (clazz instanceof String) {
String name = (String) clazz;
if (name.startsWith("0x")) {
// treat it as address
VM vm = VM.getVM();
Address addr = vm.getDebugger().parseAddress(name);
Metadata metadata = Metadata.instantiateWrapperFor(addr.addOffsetTo(0));
if (metadata instanceof InstanceKlass) {
ik = (InstanceKlass) metadata;
} else {
return Boolean.FALSE;
}
} else {
ik = SystemDictionaryHelper.findInstanceKlass((String) clazz);
}
} else if (clazz instanceof JSJavaClass) {
JSJavaKlass jk = ((JSJavaClass)clazz).getJSJavaKlass();
if (jk != null && jk instanceof JSJavaInstanceKlass) {
ik = ((JSJavaInstanceKlass)jk).getInstanceKlass();
}
} else {
return Boolean.FALSE;
}
if (ik == null) return Boolean.FALSE;
StringBuffer buf = new StringBuffer();
if (args.length > 1) {
buf.append(args[1].toString());
} else {
buf.append('.');
}
buf.append(File.separatorChar);
buf.append(ik.getName().asString().replace('/', File.separatorChar));
buf.append(".class");
String fileName = buf.toString();
File file = new File(fileName);
try {
int index = fileName.lastIndexOf(File.separatorChar);
File dir = new File(fileName.substring(0, index));
dir.mkdirs();
FileOutputStream fos = new FileOutputStream(file);
ClassWriter cw = new ClassWriter(ik, fos);
cw.write();
fos.close();
} catch (IOException exp) {
printError(exp.toString(), exp);
return Boolean.FALSE;
}
return Boolean.TRUE;
}
From sa.js:
this.dclass = function(clazz, dir) {
if (!clazz) {
writeln("Usage: dumpclass { address | name } [ directory ]");
} else {
if (!dir) { dir = "."; }
dumpClass(clazz, dir);
}
}
registerCommand("dumpclass", "dumpclass { address | name } [ directory ]", "dclass");
From JSJavaScriptEngine.java:
public Object dumpClass(Object[] args) {
if (args.length == 0) {
return Boolean.FALSE;
}
Object clazz = args[0];
if (clazz == null) {
return Boolean.FALSE;
}
InstanceKlass ik = null;
if (clazz instanceof String) {
String name = (String) clazz;
if (name.startsWith("0x")) {
// treat it as address
VM vm = VM.getVM();
Address addr = vm.getDebugger().parseAddress(name);
Metadata metadata = Metadata.instantiateWrapperFor(addr.addOffsetTo(0));
if (metadata instanceof InstanceKlass) {
ik = (InstanceKlass) metadata;
} else {
return Boolean.FALSE;
}
} else {
ik = SystemDictionaryHelper.findInstanceKlass((String) clazz);
}
} else if (clazz instanceof JSJavaClass) {
JSJavaKlass jk = ((JSJavaClass)clazz).getJSJavaKlass();
if (jk != null && jk instanceof JSJavaInstanceKlass) {
ik = ((JSJavaInstanceKlass)jk).getInstanceKlass();
}
} else {
return Boolean.FALSE;
}
if (ik == null) return Boolean.FALSE;
StringBuffer buf = new StringBuffer();
if (args.length > 1) {
buf.append(args[1].toString());
} else {
buf.append('.');
}
buf.append(File.separatorChar);
buf.append(ik.getName().asString().replace('/', File.separatorChar));
buf.append(".class");
String fileName = buf.toString();
File file = new File(fileName);
try {
int index = fileName.lastIndexOf(File.separatorChar);
File dir = new File(fileName.substring(0, index));
dir.mkdirs();
FileOutputStream fos = new FileOutputStream(file);
ClassWriter cw = new ClassWriter(ik, fos);
cw.write();
fos.close();
} catch (IOException exp) {
printError(exp.toString(), exp);
return Boolean.FALSE;
}
return Boolean.TRUE;
}
- relates to
-
JDK-8242152 SA does not include StackMapTables when dumping .class files
- Resolved