I have a jar, which contains a line of code which compares two doubles, one having the value of 0.7, but I need to be able to change that to 0.0.
I cannot use reflection or anything like that because of the fact that this is a compiled jar file (not open source) but changing this value is crucial, because if it stays at 0.7 there is a huge lag problem.
I was thinking of editing bytecode, but cannot find any good software to do so.
I appreciate any help with this.
Look into how to decompile the program Java classes, and then re-compile the software yourself.
How do I "decompile" Java class files?
From another similar question: (Change string constant in a compiled class)
If you have the sources for this class, then my approach is:
Get the JAR file
Get the source for the single class
Compile the source with the JAR on the classpath (that way, you don't have to compile anything else; it doesn't hurt that the JAR already contains the binary). You can use the latest Java version for this; just downgrade the compiler using -source and -target.
Replace the class file in the JAR with the new one using jar u or an Ant task
If you can decompile the class, you can make the change and recompile it. Then roll up the jarfile with your patched class. It depends on the class and the JDK used to compile it how easy this will be.
References: JAD (Wiki link because JAD is basically a dead project, though it continues to work when I need it to.) If you use Eclipse, you might have luck with JD-Eclipse. There is also the Procyon project, which I have had limited success with.
Besides using (Hex) Editor or decompiler, use can use a byte code manipulation lib like asm. You actually might even be able to use an pre-load agent to transform the code on the fly.
Related
I want use java code to run some clojure files dynamically which are in some zip files.
If the clj.p1.core.clj is on the class path, it can runs correctly.
require.invoke(Clojure.read("clj.p1.core"));
How to make it dynamically?That is, put clj.p1.core.clj in the a1.zip (maybe some files), the java program could select the zip and then run it?
Probably, you should unzip those files first and then specify a *.clj file when invoking Compile class; take a look at its sources.
What would be much better in your case is to compile a Java class from Clojure sources first and then load that class in Java as well. Just add a specific step into your build process that cares of it. In that case, your Java code will look much simpler and wont' waste time on loading Clojure code dynamically.
Creating a Java file would be easy; just wrap Clojure sources with additional namespace with gen-class declaration. Move its output into your Java project or specify classpath properly. See gen-class page for more examples.
I'm not sure why I can't process this right now, but I have four packages in one source folder:
./src/common
./src/server
./src/client
./src/unittest
Common uses no files from any of the others, but server and client use files from the common package. In each of the files in those packages I have import common.*. But when I run the compiler with javac ./src/server/*.java it can't find the common package.
The only info I can seem to find is for tree structured package hierarchies, but how do I reference something at the same folder height as me? Do I need to nest common inside both server and client? That seems likely to generate a lot of redundant code.
I'm sure this is probably a question someone has asked before, so I apologize, but I cannot find it anywhere.
If you want it to find those files automatically without having to specify them, you'll need to be in the package root, so run this from within src:
javac server/*.java
That would then work.
However, personally I would always specify all the code you want to build, rather than letting javac pick up extra bits. If you want to build the common code first, I'd do so and then add a classpath entry so that javac will pick up the compiled classes rather than the source code.
(Alternatively, I'd spend most of the time in an IDE where it's largely automatic, and then use a fuller build system such as Ant to do the actual building.)
I want to add some class files to rt.jar. How am I able to do that?
Your question indicates you have some misunderstanding of the java platform.
First of all you need to know what the rt.jar is and what it does:
rt.jar is the jar that contains all the classes necessary for the java runtime. Hence it's name rt.jar
Now that you know that, you need to know how your java program runs:
Your java program, all your jars and classes are executed by the java virtual machine.
So as you can see the code you write & the rt.jar which is used by the java run time are completely separate and should remain so.
If you need some functionality you should add it to your jar.
Do not update it. Why do you want to update it?
Well anyhow if you want to update it, I know one way, You can open jar file in winrar and paste updated .class files in archive. But your jar may get in inconsistent state. Do it at your own risk.
You can use this command:
jar uf jar-file input-file(s)
Refer the link for details:
java.sun.com/docs/books/tutorial/deployment/jar/update.html
The best way to update the rt.jar is to install a newer version for Java. ;)
If you want to add your own classes in new packages, you can add these to a jar which is in your class path. This is preferable to changing existing classes.
If the only option is to change existing classes, you can create a "patch" in a jar which you prepend to your boot class path, or you can add the jar to an lib/endorsed directory. I wouldn't do this for production code, only for your own testing.
I've tried jar.exe with the u and 0 (i.e. zero) options and that gets the closest to looking like the original rt.jar file but if I've updated the JDK's JRE's rt.jar I have problems with compiling and jarring after the update. No idea why! Simply running a program with the JRE seems to work.
I also tried -Xbootclasspath/p but couldn't get it to work.
Looking at Replace a class within the Java class library with a custom version I see that there are legal problems with distributing an altered rt.jar to your customers, even if you could figure out how to do it correctly. So I plan to take the advice in that page and create a java agent. That's apparently legal and works.
One reason a person might want to modify rt.jar is to add debugging information after compiling the source that comes with the JDK with the -g option. One may also want to patch something. These would be for one's own use, of course.
We have normal java files residing in the SVN. We have made some changes in those files , but it happens that , those files are lost (they are not in SVN). But we have the class files that are generated using the newly changed files.
Can we use the class files , decompile them and compare it against SVN. What is the easiest way to do it?
There are about 400 changed files. So comparing one by one is not feasible.
I am looking for any tool or scripts.
Also is there any decompiler , that would decompile a whole folder at one go?
Thanks
For decompiling use JAD, most commonly used tool. Comparing is a bit tricky though. I would suggest the following scenario:
Grab the latest source code from SVN
Build it
Decompile it (!)
Take your compiled classes that include some modifications but you don't have sources
Decompile them as well
Compare both decompiled sources directories
Why compiling and decompiling the original source codes? Because JAD produces pretty good results, but it will never generate the exact same sources that were used. So if you want to avoid headaches when comparing original sources and decompiled ones (and pinpoint the actual differences quickly), you have to compare two JAD outputs rather than original source and synthetic JAD output.
I hope having two directory structures to compare won't be a problem for you. You can use Total Commander on Windows or various utilities/scripts on Linux, like:
$ diff -r dir1 dir2
jad can decompile a whole folder but the result depends on a couple of factors. First, JAD only supports Java 4 well. Java 5 and up will contain odd byte code chunks that JAD didn't understand.
If the code is compiled with debug symbols, you can realign line numbers (the jadclipse plugin can do that) but JAD itself can't do it.
If you compiled the code with -g:source, then the class files contain the complete source code. At first glance, I don't know how to get at this but tools like javap (comes with the JDK) or ASM should allow you to get it.
It is possible to compare a decompiled source file with the orginal, provided you did not use obfuscation when generating class files. However, automated comparison will be difficult because the decompiled source is often slightly different than the original source due to compiler optimization for example.
Personally I use jad as a decompiler, but I'm not sure you can provide it with a whole folder at one go.
I used the below command(jad decompiler) to compile all the class files in a folder in one go.
jad -o -r -sjava -dsrc tree/**/*.class
Use jd-gui, very good decompiler, but the compering ... its going to be painful.
Right now im doing exactly that, using http://java.decompiler.free.fr/ to decompile and beyond compare (http://www.scootersoftware.com/) to compare packages and files. It looks like a great idea to make a fast compare against the actual version (svn) compiled and decompiled, to check which files (and which sections) are up to date.
Is it possible to convert a .class file to .java file?
How can this be done?
What about the correctness of the code extracted from this option?
It is possible. You need a Java Decompiler to do this.
You'll find mostly it'll do a surprisingly good job. What you'll get is a valid .java file which will compile to the .class file but this .java file won't necessarily be the same as the original source code. Things like looping constructs might come out differently, and anything that's compile time only such as generics and annotations won't be re-created.
You might have a problem if the code has been obfuscated. This is a process which alters the class files to make them hard to decompile. For example, class and variable names are changed to all be similar so you'll end up with code like aa.a(ab) instead of employee.setName(name) and it's very hard to work out what's going on.
I remember using JAD to do this but I don't think this is actively maintained so it may not work with never versions of Java. A Google search for java decompiler will give you plenty of options.
This is possible using one of the available Java decompilers. Since you are working from byte-code which may have been optimised by the compiler (inlining static variables, restructing control flow etc) what you get out may not be exactly the same as the code that was originally compiled but it will be functionally equivalent.
Adding to the previous answers: recently, a new wave of decompilers has been coming, namely Procyon, CFR, JD, Fernflower
Here's a list of modern decompilers as of March, 2015:
Procyon
CFR
JD
Fernflower
You may test above mention decompilers online, no installation required and make your own educated choice.
Java decompilers in the cloud: http://www.javadecompilers.com/
It is always possible. Search for "java disassembler".
But source code comments and temporary variables will not be available.
If you decompile a class and see the code is too complex with variable names and method names are like a,b,c... that means that the project is obfuscated.
Not exactly a decompiler, but the JDK contains javap, a disassembler:
javap -c org.example.MyClass
Depending on your usecase, it might still be interesting to know or use.
Note that results of class file decompilation depend on the included information within a class file. If I remember correctly, included debug information (see -g flag of javac) is important, especially for naming of variables and the like.
DJ is the easy to use java decompiler . Just open any .class file and it will show you its java code.
Also, you can use jadClipse plugin for eclipse to directly decompile the .class into .java
What about the correctness of the code extracted from this option?
In any case, the code which will be generated by any java decompiler will not be the same as it was written in orginal java class. As it just decodes the bytecode into java code. The only thing you can be sure is, that the output will be same as the output of orginal java code.