You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用ProGuard混淆多个Jar包并保留目录结构?

混淆主Jar包与Plugins目录下Jar包并保留结构的方案

当然可以实现!这种对主应用和插件Jar包同时混淆且保留目录结构的需求,在Java应用场景里挺常见的,我给你梳理下可行的方案和注意事项:

推荐工具与实现方案

ProGuard(开源主流选择)

ProGuard是Java生态中最常用的开源混淆工具,完全支持多Jar包输入并保留原始目录结构,你只需要在配置文件中做好以下设置:

  1. 指定输入与输出路径
    在ProGuard配置文件(比如proguard.cfg)中,同时声明主Jar包和plugins目录下的所有Jar包作为输入,并指定输出目录来保留结构:

    # 指定主应用Jar包,排除签名文件避免混淆后失效
    -injars {filename}-jar-with-dependencies.jar(!META-INF/**)
    # 指定plugins目录下的所有Jar包,保留相对路径
    -injars plugins/*.jar(!META-INF/**)
    # 输出到obfuscated目录,自动保留原始目录结构
    -outjars ./obfuscated/
    # 基于当前目录解析相对路径
    -basedirectory .
    
  2. 保留必要的入口与公共接口
    混淆会重命名类、方法和变量,所以必须明确保留那些不能被混淆的部分:

    • 对于JavaFX主应用,要保留启动类和入口方法:
      -keep class com.yourpackage.YourFXMainClass {
          public static void main(java.lang.String[]);
          public void start(javafx.stage.Stage);
      }
      
    • 对于插件,要保留插件的公共接口和必要的加载方法(比如主应用用来识别插件的接口):
      # 保留插件接口的所有内容
      -keep interface com.yourplugin.api.PluginInterface { *; }
      # 保留实现该接口的类的构造方法和初始化方法
      -keep class * implements com.yourplugin.api.PluginInterface {
          public <init>();
          public void init();
      }
      
  3. 添加依赖库
    别忘了加入JavaFX库和JDK核心库作为参考,避免ProGuard误混淆系统类:

    # JavaFX库路径根据你的环境调整
    -libraryjars /path/to/javafx-sdk/lib/*.jar
    # JDK核心库(模块化环境下可改用-modulepath)
    -libraryjars ${java.home}/lib/rt.jar
    

Allatori(配置更直观的商业工具)

如果你觉得ProGuard的配置有点繁琐,Allatori是个不错的替代选择,它的XML配置文件可以直接指定每个输入Jar对应的输出路径,完美保留目录结构:

<config>
    <input>
        <!-- 主应用Jar的输入输出 -->
        <jar in="{filename}-jar-with-dependencies.jar" out="obfuscated/{filename}-jar-with-dependencies.jar"/>
        <!-- Plugins目录下的Jar,直接映射到输出目录的对应位置 -->
        <jar in="plugins/plugin-1.jar" out="obfuscated/plugins/plugin-1.jar"/>
        <jar in="plugins/plugin-2.jar" out="obfuscated/plugins/plugin-2.jar"/>
    </input>

    <!-- 保留规则,和ProGuard逻辑一致 -->
    <keep>
        <class name="com.yourpackage.YourFXMainClass" methods="public static void main(java.lang.String[])"/>
        <class name="com.yourpackage.YourFXMainClass" methods="public void start(javafx.stage.Stage)"/>
        <class name="com.yourplugin.api.PluginInterface" all="true"/>
    </keep>
</config>

关键注意事项

  • 备份原始文件:混淆前一定要备份所有原始Jar包,避免混淆过程中出现错误导致文件损坏。
  • 充分测试:混淆完成后,务必测试主应用能否正常加载混淆后的插件,检查所有功能是否正常运行,重点排查ClassNotFoundExceptionNoSuchMethodError这类因混淆导致的错误。
  • 重新签名:如果你的Jar包需要数字签名,混淆后必须重新签名,因为混淆会修改字节码,原签名会失效。
  • 依赖一致性:确保主Jar包和插件Jar包的依赖版本一致,避免混淆后出现依赖冲突。

内容的提问来源于stack exchange,提问作者Regina Shavaleeva

火山引擎 最新活动