1

Lets say I have a largish Java application's jar files but I am unable to re-generate from source. Lets also stipulate that I want to modify one aspect of the application's undesirable behavior by eliminating the enum value that causes that. Can I remove one of the enum's values from its corresponding .class file, re-create the jar it belongs to, and achieve the goal of a still functional application? What are ways to accomplish this and what are possible downsides?

Answers that require using only tools available in the JDK would be preferable to requiring extra tools such as those listed in this question. This similar question would be useful if it had answers.

Changes to the application to perform reflection, dynamic bytecode manipulation, or runtime modifications to the enum values ala this question are non-starters.

jwd630
  • 4,529
  • 1
  • 20
  • 22

1 Answers1

2

Most likely: not possible.

but I am unable to re-generate from source

In other words: you can't compile it as a "project". Thus you lack the essential tooling that such a project definition comes with (like: easy access to "usages", and easy refactoring).

Let's assume for a second that you somehow manage to compile that one Enum java file into a class file. When that works, of course, you can go in, remove the corresponding constant, build a new .class file, and manipulate your existing JAR file to make use of that.

But the big downside is: you have no idea how many other classes are using that specific constant. Maybe, using javap and grep and whatnot, you might be able to identify usages of that constant. But alas, that doesn't help. Because knowing that some class uses enum E.y doesn't tell you at all how you would have to manipulate that class so you can remove E.y safely!

On the other hand, you assume that this change will cause a large application to somehow avoid unwanted behavior. Conclusion: there seem to be many many usages of that constant. What do you think that code should do then in the future? Sure, switch cases just don't executed any more. But what about method invocations that pass your constant as argument?! And worse: what about "clever" people who used the ordinal() method with that specific enum, or reflection (to create enum constants from raw strings coming from God knows)?!

Long story short: sure, theoretically, you can drop an enum constant easily. But most likely, the result of doing so will not work reliably.

Instead: step back. Don't look at your application in terms of classes and heck enum constants. Think about its features and modules, and rather identify which "whole components" can be safely cut/replaced from/within that system.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Moreover, is there any guarantee that the compiled code for "switch (myEnumValue)" still works correctly if some values of the enum, not even used in the switch, have been removed? For all we know, the compiled code dispatches based on ordinal values - that seems to be a purely internal language concern. –  Apr 28 '19 at 17:40
  • @another-dave that’s not specified, but all common compilers generate code for `switch` statements that uses the ordinal number, but will remap the numbers if the `enum` has been modified since the compilation. So this would work. However, there’s a logical problem: if an enum constant causes problems, some code actively uses it, so it will break if that constant is not present anymore. But if you can change the code to not use the constant anymore, you don’t need to remove it from the declaration. – Holger Apr 29 '19 at 12:34