- Get a list of all jar files in X_Folder
- for each jar file, get all classes encased.
- for each class file, search for any instance of Y_STRING and replace it with Z_STRING.
- make sure everything gets put back into the jar files correctly.
- done.
1) This is basic file manipulation. Look into java.io.File#listFiles()
or its overloads.
2) a JAR file is a ZIP file with specific contents. Look into java.util.jar.JarFile
or java.util.zip.ZipInputStream
; Iterate over its entries (JarFile#entries()
) and decompress each class file within (JarFile#getInputStream(ZipEntry)
).
3) The class file is a binary format but it's documented very well. The general layout is documented on wikipedia: http://en.wikipedia.org/wiki/Java_class_file#General_layout
Of special interest is the Constant pool, which starts at byte 10 of the class file and enumerates all constants referred to from within the class file. It is, again, documented on Wikipedia: http://en.wikipedia.org/wiki/Java_class_file#The_constant_pool . Its number of entries is stored in bytes 8 and 9 (big-endian).
Of special interest within the constant pool are strings and class references.
Strings are identified by the first byte being 1
. The next two bytes are the byte length of the string, and the remaining bytes are in UTF-8 (almost). Unlike UTF-8, higher planes are stored as surrogate pairs (6 bytes instead of 4) and the code point 0 is stored denormalised.
A class reference is nothing but a pointer to the constant pool, pointing to the class' fully qualified name. The fully qualified name is stored with forward slashes instead of dots to separate the fully qualified name (java/lang/Object
). It's marked as the type 7.
Other entries in the constant pool: types 3,4,9-12 are four-byte, types 7 and 8 are two-byte. Types 5 and 6 are eight-byte but they also take up two slots in the constant pool.
The rest of the class file doesn't seem to mind if the byte length of the constant pool changes. Adding entries at the end of the constant pool seems safe as well (be sure to update the constant pool length).
4) Since a jar file is just a zip file, all you need is to repackage the original file with the updated contents. I don't expect this to be possible in-place, so you might need some file shuffling. Look into java.util.zip.ZipOutputStream
for the implementation.