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.
The best way is to store our string in a separate file instead of in a declared variable or constant. Of course, we could also introduce concatenation with our string, but such isn't recommended. If we have such a long string, our Java files are likely not the best home for it anyway.
To define a string constant in C++, you have to include the string header library, then create the string constant using this class and the const keyword.
Syntax to assign a constant value in java:static final datatype identifier_name = constant; The static modifier causes the variable to be available without an instance of it's defining class being loaded. The final modifier makes the variable unchangeable.
A String Literal, also known as a string constant or constant string, is a string of characters enclosed in double quotes, such as "To err is human - To really foul things up requires a computer." String literals are stored in C as an array of chars, terminted by a null byte.
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.
The only extra data required when modifying a string (technically a Utf8 item) in the constant pool is the length field (2 bytes big endian preceding the data). There are no additional checksums or offsets that require modification.
There are two caveats:
If you plan to do this a lot, it's better to get a class file editor tool, but the hex editor is useful for quick changes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With