0

I need to patch an old version of some Java software. The problem is that reconstructing the whole package at the old version would be very difficult because it is a very complex program.

I have the corrected source file. Is there any way to compile just this one file to a class file and then insert it into the jar, or do I have to have every single source file?

UPDATE - How to do a Java Patch

Using Elliott Frisch's answer I was able to make the patch. Here is the command line:

javac -target 1.5 -source 1.5 -cp original.jar;otherlib.jar CorrectedSource.java

So, to sum up. You specify the target version of Java and set the source to match, include the original jar (and any libs) as the classpath, then finally name the source code you want to compile. You can then take the resultant class files and insert them into the jar, replacing the old class files.

To find out the target version of your class file

Community
  • 1
  • 1
Tyler Durden
  • 11,156
  • 9
  • 64
  • 126
  • Let me ask a question back: when you use a jar library in your application, do you need the source files of that jar to be able to compile java code that uses classes from that jar? – Gimby Oct 21 '14 at 20:24

2 Answers2

3

It should work if you recompile just that one file as long as

  1. You use the same -target <release>, per javac -help that will Generate class files for specific VM version and I believe you need to match the original version.
  2. You replace the version of the old class in the jar file with the new class file you generated in 1. Please, backup the original Jar file first.
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • It is not working. I get lots of "cannot find symbol" errors for symbols which are defined in other source code files. Note from my question: trying to assemble the original set of source files would be very difficult. I need to compile/modify this ONE file without having all the source files in the project. – Tyler Durden Oct 21 '14 at 20:24
  • Add the original (compiled) jar to your `-cp` argument to `javac`. – Elliott Frisch Oct 21 '14 at 20:25
  • ... and it works (complete solution in updated question) – Tyler Durden Oct 21 '14 at 21:00
  • Also, **assuming you don't have any changes which break binary compatibility**. For example, if you change the value of a static final field, the old classes won't see the new value. Same with method overloads. – Antimony Oct 22 '14 at 02:35
  • @Elliott They may as well be. static final fields with primitive or string constants are inlined wherever they are accessed at compile time. Try it yourself if you don't believe me. Or read the Java specifications. – Antimony Oct 22 '14 at 04:30
1
  1. Compile source file using target <release> to make sure it's the same version as the old jar was compiled to.
  2. Rename filename.jar to filename.zip
  3. Unzip .zip file
  4. Replace .class file with new file
  5. Rezip archive. It is okay to use compression. Make sure directory structure is the same as it was, and that you include the META-INF directory.
  6. Rename file to filename.jar again.

Note: The checksum will be different. Some executable jars check for this, others don't. YMMV

durron597
  • 31,968
  • 17
  • 99
  • 158