[英]How to remove a method from a compiled Java class/jar file?
I have a JAR file and there is a static class, I can't decompile it, it gets messed up. 我有一个JAR文件,有一个静态类,我无法反编译它,它搞砸了。 There is one method in it, that returns a class, that doesn't exist.
其中有一个方法,它返回一个不存在的类。 No idea how, but I'm getting
NoClassDefFoundError
. 不知道如何,但我得到
NoClassDefFoundError
。 Even though I'm not using that method, it still crashes. 即使我没有使用那种方法,它仍然会崩溃。 So I need to somehow just remove it and it should work fine.
所以我需要以某种方式删除它,它应该工作正常。 I know Reflection or Javassist could be used, but no idea how.
我知道可以使用Reflection或Javassist,但不知道如何使用。
Note, that this is obviously not for production release, just some white-hat hacking. 请注意,这显然不适用于生产版本,只是一些白帽黑客攻击。
I think you are mistaken: if that method would never be called, then the JVM would most likely not try to load that class. 我认为你错了:如果永远不会调用那个方法,那么JVM 很可能不会尝试加载该类。
You see, the whole point of class loading - it happens lazy ; 你看,班级加载的重点 - 它发生了懒惰 ; when you load class X, and X needs Y, Z ... then Y and Z are only loaded when some code is executed that requires Y, Z to be loaded.
当你加载类X,并且X需要Y,Z ...时,只有在执行需要加载Y,Z的代码时才加载Y和Z.
In other words: that NoClassDefFound error actually tells you that something (maybe a static init somewhere in your JAR) is calling that method. 换句话说:NoClassDefFound错误实际上告诉您某些东西 (可能是JAR中的某个静态init)正在调用该方法。
Thus, the solution is not to "cut out" that one method (that would simply lead to another exception, like MethodNotFound!). 因此,解决方案不是“删除”一个方法(这将导致另一个异常,如MethodNotFound!)。 Instead, you should try to create a dummy class to not run into that exception at all.
相反,您应该尝试创建一个虚拟类,以便根本不会遇到该异常。 Or: your JAR is missing at least one of its dependencies.
或者:您的JAR至少缺少一个依赖项。 You can try to resolve that dependency - maybe you can find the class somewhere, or, you "build" your own version of it (the second idea might be probably hard to get correct).
您可以尝试解决该依赖关系 - 也许您可以在某处找到该类,或者,您“构建”自己的版本(第二个想法可能很难得到正确)。
GhostCat already explained why your problem is not removing a method. GhostCat已经解释了为什么你的问题没有删除方法。 But I figured I should answer the original question in case anyone else was wondering.
但我想我应该回答原来的问题以防其他人在想。
The best way to remove a method from a classfile is to disassemble it with Krakatau , delete the method you want from the .j
file, and reassemble it. 从类文件中删除方法的最佳方法是使用Krakatau对其进行反汇编,从
.j
文件中删除所需的方法,然后重新组合它。 This method allows you to edit any classfile, no matter how strange. 这个方法允许你编辑任何类文件,无论多么奇怪。 (If you find any valid classfiles that the Krakatau disassembler can't handle, please file a bug).
(如果您发现Krakatau反汇编程序无法处理的任何有效类文件,请提交错误)。
When disassembling, you may also want to pass the -roundtrip
option. 在反汇编时,您可能还想传递
-roundtrip
选项。 This isn't required for correctness, but it prevents the constant pool from being rearranged, reducing the binary diff of the resulting classfile. 这不是正确性所必需的,但它可以防止重新排列常量池,从而减少生成的类文件的二进制差异。 On the other hand,
-roundtrip
also makes it a lot harder to locate the method you want in the .j
file. 另一方面,
-roundtrip
也使得在.j
文件中找到所需方法变得更加困难。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.