How to get the code of a method from its Class - java

I am working with this awesome little piece of code, and I need some help figuring it out.
Basically it has a big byte array, which is used to load a new class:
Class class = class1.loadClass(name, byteArray);
class.getMethod("run", new Class[0]).invoke(null, new Object[0]);
This is loadClass:
public Class<?> loadClass(String paramString, byte[] paramArrayOfByte) throws ClassNotFoundException
return defineClass(paramString, paramArrayOfByte, 0, paramArrayOfByte.length);
And then it calls the 'run' in this class. Now, besides this being an awesome way to hide your classes, how do I get a look into this class? I have the actual class in 'class', but I don't get further than the attributes and their values and the function names. I want to know what 'run' actually does. Is there any way to somehow print the content of this method or whatever? Or maybe I can transform the byte array containing the class in something readable?
Thanks!

What if you write this byteArray in a .class file and open it with a Java Decompiler tool (like jd-gui) ?

You are asking how to read a class file into something meaninful.So basically you are asking for it to be decompiled like JD-Decompiler .Also,the .class files are loaded in the memory by the classloader.
I would suggest you take a dump of the .class file and write it in the file using ByteArrayOutputStream and ObjectOutputStream .Then decompile it using any decompiler software.
Please note that this process does not guarantee any accuracy of the source file decompiled..

Related

How do I get a NetcdfFile out of a byte array?

I am relatively new to using the netcdf-java library, and I've immediately run into a problem when trying to load a file. The problem is that there doesn't seem to be a way to load a NetcdfFile from a byte array stored in memory, and that is the base form of my data. To elaborate a little, it is actually a .cdf file uploaded through a client, which the client then converts into a byte array for the server code to read. So the server, where my code is running, cannot see the uploaded file at all. I also cannot assume the server itself is writable, so essentially there is no "location" to pass into the typical NetcdfFile loading methods.
The FAQ on ucar.edu does mention the possibility of reading from a non-file source, here. It says I should write my own IOSP, which I am happy to do. However, there is very little guidance on how to do this.
I don't know how to implement isValidFile when the only thing passed into the function is a RandomAccessFile, which the FAQ says can be ignored.
I don't know how my IOSP will obtain the byte array in question for use in readData.
I don't know why the minimal example in the FAQ advises me to make a new NetcdfFile class, when it seems I could just use the default one but pass in my custom IOSP.
This question is a little vague, but I am truly lost without many clues on where to even begin. Any guidance would be appreciated.
EDIT: I'm using 5.4.2 of the netcdf-java library.
I found this answer in the support archives. The solution is to use InMemoryRandomAccessFile. The constructor takes a String location and a byte array containing the file's contents. From my testing, I think the location can be any arbitrary string. Here is the code that worked for me.
byte[] filebytes = retrieveFileBytes(clientFilepath);
InMemoryRandomAccessFile raf = new InMemoryRandomAccessFile(clientFilepath, filebytes);
NetcdfFile file = NetcdfFiles.open(raf, clientFilepath, null, null);
Variable peakRetentionTime = file.findVariable("peak_retention_time");
if (peakRetentionTime == null) {
displayWarning("peak_retention_time null!");
} else {
Array data = peakRetentionTime.read();
displayInfo(Ncdump.printArray(data));
}

How can i define method in file with extension .class?

I need to define another method in ITuple.class like
public Object getValue(int i);
but with Float
public Object getValue(float j);
How can i add it ?
I'm new to storm so Can I find the method that make the same job as I searched and couldn't find , isn't right?
I think you are misunderstanding what getValue(int) does. Here is the description from the javadocs:
Object getValue(int i)
Gets the field at position i in the tuple. Returns object since tuples are dynamically typed.
As you can see, the int argument is the position in the tuple; i.e. the index. Tuple position are inherently integers, so adding an alternative that takes a floating point argument doesn't make any sense.
Supposing (hypothetically) that it did make sense to add a getValue(float) overload, then the way to do it would be to:
download the source code (".java" files),
modify the interface in the ITuple.java source file
modify the source files for classes that implement the interface
build them all to produce new JAR files
use those JAR files in your application
... and repeat this patching procedure every time you upgraded your Apache Storm release. That is probably a bad idea, even if what you were doing made sense.
But attempting to modify ".class" files directly is an even worse idea.
.class files are compilated java files. I assume you found this file in a library.
I'm afraid to inform that this code isn't yours and you cannot edit it.
What you can do, however, is extends the ITuple interface in a MyITuple interface and add whatever you want in it.

Writing BitSet to output file without overhead?

I get a line of overhead ("java.util.BitSet") when writing a BitSet to an output file using ObjectOutputStream.writeObject().
Anyway around it?
That is not an "overhead", that't the marker that lets Java figure out what type it needs to create when deserializing the object from that file.
Since ObjectInputStream has no idea what you have serialized into a file, and has no way for you to provide a "hint", ObjectOutputStream must "embed" something for the input stream to be able to decide what class needs to be instantiated. That is why it places the "java.util.BitSet" string in front of the data of your BitSet.
You cannot get around writing this marker when you use serialization capabilities built into BitSet class. If you are serializing the object into a file by itself, with no other objects going in with it, you could write the result of toByteArray() call into a file, and call BitSet.valueOf(byteArray) after reading byteArray from the file.

Running a class with the name within in a variable at run-time in JAVA

I have been learning Java and over the last few weeks I have created a bunch of classes for practice purposes. It got into my head that it would be cool to create a class that allowed me to see a list of all the classes that I have created and run them by choosing the class I want.
The way I did it and how far I have gone:
I read into a HashMap<Integer,String> a list of all my classes with a SimpleFileVisitor.
From this list the user can chose a file by entering the number associated with the class.
A string is returned with the class name.
Now here comes the issue.
I end up for example with a string called Clock.class.
I want to run this. How?
Let's say that I knew the class I wanted to run. I could simple use Clock.main()
The issue here is that I will not know which class to run until run-time, so I am lost.
I have been toying around with the Reflection API. I am able to instantiate an object of the Clock.class but nothing happens.
Maybe I should not be using reflection at all? Maybe there is a simpler way?
This is where I am stuck, I hope someone can enlighten me. :)
You could use reflection to call the main method of the class:
Class<?> cls = Class.forName("package.path.yourClassName");
Method m = cls.getMethod("main", String[].class); //mandatory signature for main()
String[] params = null; // any params on the call?
m.invoke(null, (Object) params);
Note: The first parameter of invoke() would be the instance on which you'd like to invoke the call. But static mehtods don't belong to instances, therefore use null.
You have the File path to your class files from traversing via SimpleFileVisitor. Store the file name and path in a Map. When user chooses lets say Clock.class get path corresponding to it and start another java process.
Simply do
Process process = Runtime.getRuntime().exec("/pathToJDK/bin/java", pathToClassFile);
You can play around with I/O and Error streams like -
InputStream inputStream= process .getErrorStream();
//print this stream

How to dynamically decompile a Class Object on memory?

I'm making a tool to dynamically display the sourcecode of running java class. I need a tool to help me on dynamically decompile from a Class Object to String of sourcecode. I know some decompile tools like Jad, DJ decompiler can decompile a .class file but I expect a tool can:
Class<?> c = ..; // get from runtime environment
String sourcecode = **DecompileTool**.decompileClassObject(c);
return sourcecode;
I need such a DecompileTool, anyone knows? Thanks
I'm not aware of any decompiler that can be used like that.
Indeed, in the general case it is not possible to implement a decompiler that works like that:
The Class<?> object that you get from the runtime doesn't provide any way to get to the bytecodes.
In order to get hold of the bytecodes, you would need to redo what the classloader does when it locates the ".class" file from the classpath.
I don't think there's a way to find out what classloaders are in use ... if you include the possibility of dynamically instantiated classloaders. (And such classloaders are normal practice in (for example) web containers.)
In the general case, a classloader will do that in ways that you cannot reproduce ... without reverse engineering and hard-coding the same logic into your decompiler adapter code.
Besides, doing this on the fly is probably pointless, because there is a significant chance that the decompiler will produce source code that isn't compilable.
I don't think that any of these decompilers support this type of ugly interface.
First of all, most decompilers will represent any code in a similar format to the actual compiler, so, an Abstract Syntax Tree. If you are lucky, and the decompiler does have an interface, it will probably be of this type. Handing back a raw String is unlikely to be satisfactory, because how would the person writing the decompiler have any idea as to how you wanted the code formatted (one of the biggest challenges in decompilation is presenting the result to the user!).
Instead, what you should do, is write a little wrapper, that does this properly: on the fly generation of the files that need to be decompiled, sending them through the decompiler, and extracting the result into a String (which you can get immediately if you do clever forking and piping, etc..., but in reality you probably just want to format the output file of the decompiler..)
Try Cavaj Java Decomplier, it may be useful for you.If you aren't satisfied this, try JadClipse with eclipse IDE.
You can do the followin thing steps
1) You can use decompilers available to decompile the code like
Process p = Runtime.getRuntime().exec("jad /location/CompilesClass.class");
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
2) Now the Compiled class is converted into .jad extension (Source Code) in the path where the class file was there
3) Now you can read that .jad file by Scanner class of JDK6. Like
Scanner scanner = new Scanner(new File("locationOfJADFIle")).useDelimiter("\n");
while(scanner.hasNext()){
System.out.println(scanner.next());
}

Categories

Resources