V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
liubsyy
V2EX  ›  Java

一键修改 JAR 包内文件: JarEditor 插件详细指南

  •  
  •   liubsyy · 144 天前 · 1822 次点击
    这是一个创建于 144 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    在开发中我们有时会遇到这样的场景,需要修改 jar 包内某个 class ,常见的方法就是先解压缩,然后反编译这个 class ,新建 java 修改再编译,最后再打包,整个过程是非常耗时的。

    这里向大家介绍一款 IDEA 插件:JarEditor ,可以一键修改 JAR 包内文件,无需解压。

    插件安装

    首先在插件商城搜索 JarEditor ,可直接安装插件

    JarEditor_install.png

    插件使用

    1. 修改 class 文件

    安装完后,任意打开一个 jar 的 class ,可以看到反编译后的 class 内容,选中 Jar Editor 的 tab 页签,就可以直接编辑 class 了

    image.png

    修改完代码后先点击 Save,这个过程会编译 class ,编译成功后点击Build Jar就修改 jar 完成了,是不是很简单?下面是一个修改的例子。

    Jul-06-2024 15-25-13.gif

    SDK 可以选择需要的 JDK 或者其他 SDK ,Target 为编译 class 的目标版本,默认是和反编译的 class 前的版本保持一致。

    附:修改外部 jar

    选择 File->Project Structure->Libraries ,然后添加工程外的 jar 即可打开 jar 内文件修改

    image.png

    也可以将 jar 包粘贴到本项目中,然后右键->Add as Library...

    image.png

    2. 修改配置文件

    操作流程同修改 class 文件,不需要选择 Compile

    image.png

    3. JAR 包内新增文件

    在工程视图 jar 包内某个文件夹上右键->JarEditor->New,可以新建 Class/Kotlin/File/Directory

    image.png

    选择后输入文件名即可在 jar 内新增文件,默认是空文件

    image.png

    新增后打开可以写入内容,Class 和 Kotlin 新建完文件是有模版的,无需后缀名,如果是 JarEditor->New->File 则需要写文件后缀名。

    image.png

    3. 删除 JAR 包内文件

    在工程视图 jar 包内某个文件或者文件夹上右键->JarEditor->Delete,则会删除选择的目录或者文件,支持多选。

    image.png

    4. 重命名文件

    在工程视图 jar 包内某个文件或者文件夹上右键->JarEditor->Rename,输入名字后即可将原来的名字修改为新的名字,修改完立即生效。

    image.png

    5. 拷贝 JAR 包内文件到外部文件夹

    在工程视图 jar 包内某个文件或者文件夹上右键->JarEditor->Copy,可以将 jar 包内文件拷贝到剪切板(支持多选)

    image.png

    然后在外部任意一个文件夹内,使用 Ctrl+V ,即可将刚才复制的文件拷贝到这个目录

    image.png

    6. 粘贴外部文件到 JAR 包内

    外部文件使用 Ctrl+C 复制后,在 jar 内某个文件夹上右键->JarEditor->Paste(不能直接用 Ctrl+V ,Ctrl+V 被 IDEA 默认占用了),即可将剪切板的文件粘贴到 jar 包内,一气呵成。

    image.png

    7. JAR 包内搜索字符串

    工具栏有一个搜索图标,点击后输入需要搜索的字符串,可搜索到 jar 包内的文件,包括 class 和普通文件。

    image.png

    点击搜索后的文件列表,可跳转到具体的文件

    image.png

    搜索的 class 如果是 class jar 的话取决于反编译的内容,如果是 source jar 取决于 java 文本。

    8. source jar 的支持

    IDEA 内打开的 jar 分两种,class jar 和 source jar ,如果下载了源码的话,打开的是 source jar ,即打开的是一个 java 文件,而不是 class 文件,这里一定要注意

    image.png

    此时如果修改代码的话,生效的是 source jar ,比如这里改的是 FindInstancesOfClass-1.0.3-sources.jar 。

    image.png

    那如何修改 class jar 呢?

    点击 JarEditor Tools 上面的跳转链接:Click hear to open class jar 即可跳转到 class 文件

    image.png

    此时展示的 class 为反编译的代码,可修改 class 文件,按 修改 class 文件 的流程操作即可。

    也可以从 source jar 中导入代码:Import from source jar

    image.png

    Import from source jar 和直接在 souce jar 中的 java 修改的区别是:前者修改的是 class jar 后者是 source jar 。

    一些机制和原理

    SDK 的选择

    目前支持 java 和 kotlin 两种文件编译,后续可能会增加更多的编译文件支持。

    选择 SDK Default 时,是使用的 IDEA 运行时自带编译器,即 javax.tools.JavaCompiler,详细可阅读源码。

    选择其他 JDK 时,默认使用的是 javac 外部命令编译。

    image.png

    编译时选择的 Target 的范围是 1.1~所有 JDK 的版本最大值。

    Save ( Compile )

    考虑到可能会修改多个文件,会将当前修改的内容(编译)保存到所在 jar 包目录的临时目录 jar 名_temp/jar_edit_out 下,当点击 Build Jar 将增量文件写入 jar 后,会删除临时目录,也可手动清理临时目录。

    image.png

    编译依赖

    在编译时,依赖的 jar 为当前工程的 Libraries ,如果编译时提示依赖包找不到,可以添加依赖即可。

    另外 class 文件的内容取决于反编译的结果,如果混淆的代码则不太方便修改和编译。

    SDK Default

    当选择 SDK Default 编译时,对应的 JDK 版本如下:

    IDEA JDK
    IDEA 2020.3 ~ IDEA 2022.1 JDK 11
    IDEA 2022.2 ~ IDEA 2024.1 JDK 17
    IDEA 2024.2 及更高版本 JDK 21

    总结

    本文主要介绍了使用 JarEditor 直接对 jar 包文件进行增删改查操作,简化了修改 jar 的流程,感兴趣的朋友可以去试试。

    本文篇幅有限,具体原理和实现细节可阅读源码

    源码: https://github.com/Liubsyy/JarEditor

    13 条回复    2024-07-20 12:58:22 +08:00
    wxw752
        1
    wxw752  
       144 天前
    从业八年没有遇到过这么改的场景😅
    designer
        2
    designer  
       144 天前 via iPhone
    想起了以前诺基亚手机玩 java 游戏,修改 QQ jar class 文件
    kandaakihito
        3
    kandaakihito  
       143 天前
    @wxw752 一些依赖在特定环境下会遇到奇葩的 bug ,比如 jco3 ,每次都得打包完进去改点东西
    Aresxue
        4
    Aresxue  
       143 天前
    蛮不错的插件,就是编译可以再扩充一些,一个是可以指定电脑本地的其它 jdk ,甚至一些三方的反编译和编译库像 cfr 、Procyon;另一个是我没看到对三方库的处理,指原不在我当前应用中的三方包但我本次修改需要使用的三方库,这块处理也确实会比较麻烦但在这个魔改 jar 的场景里面出现的概率却并不低。
    liubsyy
        5
    liubsyy  
    OP
       143 天前
    @Aresxue 指定 JDK 是有的,最新版 SDK 可以添加和选择其他 JDK 。现在反编译是 IDEA 默认的 Fernflower ,后续可以考虑其他反编译库的支持。第三方库是指的不在项目中的 jar 但是需要依赖的么?可以手动添加外部 Libraries 就能在 External Libraries 看到了
    Nitsuya
        6
    Nitsuya  
       143 天前
    @designer 怀念啊, 一晃都是 15 年前的事情了
    Aresxue
        7
    Aresxue  
       143 天前
    @liubsyy 我的意思是你的发布物是什么样的,原先不依赖的新三方库我理解就是导出一个新的 jar 包就叫它 newbiz.jar 好了,把这个 jar 包在容器里面替换掉原有的 biz.jar 然后重启 java 进程就生效了,新依赖三方包的话新的三方包你是会直接打到 newbiz.jar 中还是说是分开的,除了替换原有的 biz.jar 以外还需要再上传一个 third.jar ,值得注意的是这个 third.jar 可能以前已经有低版本的了这里再引入一个会面临业务里面会遇到的钻石依赖问题。
    nikelei
        8
    nikelei  
       143 天前
    bd
    liubsyy
        9
    liubsyy  
    OP
       143 天前
    @Aresxue 修改 biz.jar 后 Build Jar 直接修改了 biz.jar ,不会生成新的 jar ,至于怎么部署依赖不在本插件范畴内
    lovedoing
        10
    lovedoing  
       143 天前
    试了下挺好用的
    ppooqq
        11
    ppooqq  
       137 天前
    挺好的,不知道能不能实现以下功能:

    1 、有项目二开的,一部分 jar 没有源码,希望支持全局在 idea 里搜索这些 jar 包的内容。通过插件是可以对单个 jar 进行搜索,但前提要猜到想找的方法,关键字在哪个 jar 包里。
    2 、能批量将依赖中的多个无源码的 jar 包反编译并生成-source.jar ,并存放在相同目录,这样 idea 就认为是有源码可以搜索了。
    liubsyy
        12
    liubsyy  
    OP
       136 天前
    @ppooqq 实现应该不难,就是不知道全局搜索快不快,可关注项目的后续更新,合理方便的功能都可以考虑加上
    ppooqq
        13
    ppooqq  
       131 天前
    @liubsyy #12 居然这么快都给实现了,大大你真棒
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1744 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 213ms · UTC 16:39 · PVG 00:39 · LAX 08:39 · JFK 11:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.