I have a web-app which I want to work roughly as follows:
Someone uploads a jar (say myjar.jar
) along with the name of class to analyze (say test.Test
). The exact purpose of analysis is irrelevant so assume that the web-app does some static analysis on it.
I am able to upload the jar and load the class in Java using the hacks described here and here (MultiClassLoader).
If I know the methods inside the class, I can invoke them using reflection. Following assumes a method with signature foo(String)
Class c = jarLoader.loadClass("test.Test", true);
Object instance = c.newInstance();
Method foo = instance.getClass().getDeclaredMethod("foo", new Class[]{String.class});
// foo takes one para String
foo.setAccessible(true);
foo.invoke(instance, (Object) "hello");
Now, suppose, I need to find out what methods are there inside test.Test
. To do this, I use the ASM framework , which needs the class as a stream . This is where I am running into a problem. I am unable to do getResourceAsStream
or its equivalents. This is what I tried:
Type t = org.objectweb.asm.Type.getType(c); // uses asm library
String url = t.getInternalName() + ".class";
c.getClassLoader().getResourceAsStream(url); // gives null
Same problem if I use:
c.getClassLoader().getResourceAsStream(c.getSimpleName() + ".class");
etc.
What is the right way to get resource as stream, where the resource is a class file loaded from a jar NOT in the class path. Note that the entire thing is done via a web-app.
EDIT: Getting methods is just an example. What I really want is to get the class as a stream. I need to use ASM because it gives me other information (such as parameter names), which I cannot get via getDeclaredMethods
or getMethods
.
Re: "Now I need to find out what methods are there inside test.Test"
You get the class via Class c = jarLoader.loadClass("test.Test", true);
. Class
also has getDeclaredMethods()
and getMethods()
.
EDIT: @Jus12, from your second link Java Tip 70: Create objects from jar files! :
protected byte[] loadClassBytes (String className)
ASM has a ClassReader(byte[] b)
constructor.
I don't know if Java offers a way to do this programmatically, but I can suggest a hack: spawn a new process with:
jar xf myjar.jar test/Test.class | javap -cp test -c Test
This should output the bytecode. Then simply redirect the output to a stream you can read from.
You can use a URLClassLoader
, which takes a List
of URL
s in its constructor. You can then load the class by invoking the loadClass
method on the URLClassLoader
instance to get the Class<?>
object for the class that you are after. Once you have that, you can then use reflection to create instances, and/or get general information about the class.
I have not tried, but the URLClassLoader
does also have a getResourceAsStream
method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.