Skip to content

Instantly share code, notes, and snippets.

@DinisCruz
Created September 5, 2016 10:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DinisCruz/b738f0679404c59795e46cfee14a7e5f to your computer and use it in GitHub Desktop.
Save DinisCruz/b738f0679404c59795e46cfee14a7e5f to your computer and use it in GitHub Desktop.
Here is an experiment with javap to extract the methods programatically. It looks like javassit will be a better way to do this (specially since it is native)
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Created by diniscruz on 01/09/2016.
*/
public class JavapHelper {
public static String pathToClass(Class clazz)
{
return clazz.getResource("/" + clazz.getName().replace(".","/") + ".class").toString();
}
public static String decompileClass(Class clazz) {
String path = pathToClass(clazz);
System.out.println(path);
String[] args = new String[] {"-v", path};
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
com.sun.tools.javap.Main.run(args, printWriter);
printWriter.close();
return stringWriter.toString();
}
public static HashMap<String,List<String>> constantPool(Class clazz)
{
String rawData = decompileClass(clazz);
String[] lines = rawData.split("\n");
HashMap<String,List<String>> results = new HashMap<String,List<String>>();
boolean insideConstantPool = false;
for (String line :lines) {
if(line.equals("Constant pool:")) // start of Constant pool data
{
System.out.println(line);
insideConstantPool = true;
continue;
}
if(insideConstantPool)
{
//System.out.println("> " + line);
if (line.equals("{"))
break;
String[] data = line.split("=",2) // extract the data to the right of the first =
[1].trim() // [0] is the id [1] is the rest of the line
.split(" ", 2); // split the constant pool name and its value
if (data.length == 2) {
String key = data[0]; // constant pool name
String value = data[1]; // constant pool value
if (!results.containsKey(key)) // if it is the first time we see this key
results.put(key, new ArrayList<>());
results.get(key).add(value.trim()); // add key's value to key's list<String>
}
}
//System.out.print(line == "Constant pool:");
//System.out.println(" - " + line);
}
//System.out.println(lines);
//3System.out.println(lines.length);
return results;
}
}
@Test
public void constantPool() throws Exception {
Context context = new Context();
String pathToClass = JavapHelper.pathToClass(JavapHelper.class);
JavapTask javapTask = new JavapTask();
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
javapTask.setLog(printWriter);
//Object methods = javapTask.getClass().getMethods();
//Object declared_methods = javapTask.getClass().getDeclaredMethods();
//JavapHelper.constantPool(JavapHelper.class);
Method method_Open = javapTask.getClass().getDeclaredMethod("open", String.class);
Method method_Run = javapTask.getClass().getDeclaredMethod("run", String[].class);
method_Open.setAccessible(true);
method_Run.setAccessible(true);
String[] args = new String[] {"-v", pathToClass};
method_Run.invoke(javapTask,new Object[] { args });
System.out.println(stringWriter.toString());
System.out.println("Done");
JavaFileObject openData = (JavaFileObject)method_Open.invoke(javapTask, new Object[] { pathToClass });
JavapTask.ClassFileInfo classFileInfo = javapTask.read(openData);
//System.out.println(openData);
//System.out.println(classFileInfo);
ConstantPool constantPool = classFileInfo.cf.constant_pool;
for (ConstantPool.CPInfo entry : constantPool.entries())
{
if(entry instanceof com.sun.tools.classfile.ConstantPool.CONSTANT_Methodref_info)
{
ConstantPool.CONSTANT_NameAndType_info nameAndType = ((ConstantPool.CONSTANT_Methodref_info)entry).getNameAndTypeInfo();
System.out.println(String.format("%s.%s", nameAndType.getType(), nameAndType.getName()));
}
}
//((com.sun.tools.classfile.ConstantPool.CONSTANT_Methodref_info)classFileInfo.cf.constant_pool.get(8)).getNameAndTypeInfo().getType()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment