1

使用 java 1.6 设置编译的类文件有两个字段,我需要将它们设置为更高的值。

private Integer days = 7;
private Integer running = 30;

不幸的是,我无法再访问正确版本的代码,只能拥有类文件。

这是我已经尝试过的:我一直在玩弄 BCEL、asm 和 javassist,但这似乎一点也不简单。我也找不到合适的字节码编辑器(jbe 看起来真的很混乱,类编辑器不显示 Integer 对象的值)。Eclipse 字节码类文件查看器在尝试保存时崩溃。使用十六进制编辑器来操作这些值是不可能的,因为它们将比现在有更多的数字。我还研究了 javap 并用 jasmin 重新编译它——这似乎是不可能的。

所以最终 - 拜托,哦,拜托 - 有没有人有一个很好的例子,如何以任何可以想象的方式做到这一点?

4

7 回答 7

2

您是否尝试过反编译、编辑然后重新编译?据我所知,京东做得很好。

http://java.decompiler.free.fr/

于 2011-05-05T23:36:11.583 回答
2

您可以使用反射来设置它们,就像前面的答案指出的那样。这是一个例子:

public class TestSetPrivateFields extends TestCase {

    public void testSetFields() throws Exception {
        Legacy legacyObj = new Legacy();
                    // get the fields using reflection
        Field[] fields = {
                          legacyObj.getClass().getDeclaredField("days"),
                          legacyObj.getClass().getDeclaredField("running")
                          }; 
        for (Field field : fields) {
            field.setAccessible(true);
            Integer value = (Integer) field.get(legacyObj);
            // set their value
            field.set(legacyObj, value+1);
        }

        Legacy expected = new Legacy();
        assertEquals(expected.getDays()+1, legacyObj.getDays()+0);
        assertEquals(expected.getRunning()+1, legacyObj.getRunning()+0);
    }

    public static class Legacy {
        private Integer days = 7;
        private Integer running = 30;

        public Integer getDays() {return days;}
        public Integer getRunning() { return running;}
    }

}
于 2011-05-06T00:03:57.617 回答
0

使用字节码编辑器非常简单。该字段将具有关联的 DefaultValue 属性,或者您会在 ()V 中找到类似的内容:

aload_0
bipush 7
invokestatic java/lang/Integer#valueOf (I)Ljava/lang/Integer;
putfield Blah#days Ljava/lang/Integer;

应该清楚这里要修复什么。

于 2011-07-19T16:21:56.740 回答
0

我无法想象你为什么没有来源。

我不会经历所有的痛苦。如果这很困难,也许这表明你不应该这样做。

我宁愿使用JAD,反编译 .class 文件,进行更改,然后继续。

于 2011-05-05T23:34:31.197 回答
0

就我个人而言,我会使用 ASMifier(或 Eclipse Bytecode Outline)来生成 java 类,当使用该类运行时java -cp asm-all.jar MyAsmClass会生成必要类的新版本。有问题的值必须在所有构造函数中更新,并将在visitLdcInsn()调用中。

于 2011-05-06T08:11:48.677 回答
0

这看起来很有希望:

http://classeditor.sourceforge.net/

于 2011-05-05T23:39:17.377 回答
0

看看京东核心。eclipse 的插件让我可以窥视一些未记录的库,以帮助我更好地理解它。它不适用于所有已编译的 java 类,但它几乎为我打开了所有东西。

于 2011-05-05T23:40:22.157 回答