I need to change a string constant in a deployed Java program, i.e. the value inside the compiled .class
-files. It can be restarted, but not easily recompiled (though it's an inconvenient option if this question yields no answers). Is this possible?
Update: I just looked at the file with a hex editor and it looks like I can easily change the string there. Would that work, i.e. won't that invalidate some kind of signature of the file? The old and new string are both alphanumeric, and can be the same length if needed.
Update 2: I fixed it. Because the specific class I needed to change is very small and didn't change in the new version of the project, I could just compile that and take the new class from there. Still interested in an answer that doesn't involve compilation though, for educational purposes.
If you have the sources for this class, then my approach is:
-source
and -target
.jar u
or an Ant taskExample for an Ant task:
<jar destfile="${jar}"
compress="true" update="true" duplicate="preserve" index="true"
manifest="tmp/META-INF/MANIFEST.MF"
>
<fileset dir="build/classes">
<filter />
</fileset>
<zipfileset src="${origJar}">
<exclude name="META-INF/*"/>
</zipfileset>
</jar>
Here I also update the manifest. Put the new classes first and then add all the files from the original JAR. duplicate="preserve"
will make sure that the new code will not be overwritten.
If the code isn't signed, you can also try to replace the bytes if the new string has the exact same length as the old one. Java does some checks on the code but there is no checksum in the .class files.
You must preserve the length; otherwise the class loader will get confused.