【问题标题】:Can proguard leave out the unused classes of the libraries?proguard 可以省略库中未使用的类吗?
【发布时间】:2011-12-07 15:02:15
【问题描述】:

我有一个使用 pdfbox 库的 java 应用程序,它的大小为 10mb。我只使用了这个库的几个类。

我认为 ProGuard 会为我的应用程序生成一个独立的 jar。但是ProGuard生成的jar还是需要/lib文件夹下的pdfbox.jar才能运行。难道我做错了什么?我怎样才能实现我的目标? (省略了我不使用的 99% 的库类)。

cmets 后的注意事项: - 原始 jar 及其库是使用 Netbeans 生成的。我第一次使用 ProGuard GUI,但是在收到关于这个问题的 cmets 之后,我切换到了脚本。结果相同:只有当库位于 jar 旁边的 /lib 文件夹中时,该应用才能运行。

Proguard 脚本:

-injars       "C:\Users\C. Levallois\Documents\NetBeansProjects\ZoText\dist\ZoText.jar"
-outjars      "C:\Users\C. Levallois\Documents\NetBeansProjects\ZoText\dist\ZoText_short.jar"

-libraryjars  <java.home>/lib/rt.jar
-libraryjars  "C:\Users\C. Levallois\Documents\NetBeansProjects\ZoText\dist\lib\Boilerpipe_short.jar"
-libraryjars  "C:\Users\C. Levallois\Documents\NetBeansProjects\ZoText\dist\lib\commons-io-2.1.jar"
-libraryjars  "C:\Users\C. Levallois\Documents\NetBeansProjects\ZoText\dist\lib\commons-lang3-3.0.1.jar"
-libraryjars  "C:\Users\C. Levallois\Documents\NetBeansProjects\ZoText\dist\lib\guava-10.0.1.jar"
-libraryjars  "C:\Users\C. Levallois\Documents\NetBeansProjects\ZoText\dist\lib\nekohtml.jar"
-libraryjars  "C:\Users\C. Levallois\Documents\NetBeansProjects\ZoText\dist\lib\pdfbox-app-1.6.0.jar"
-libraryjars  "C:\Users\C. Levallois\Documents\NetBeansProjects\ZoText\dist\lib\xercesImpl.jar"


-printmapping proguard.map

-keep public class proguard.ProGuard {
    public static void main(java.lang.String[]);
}

-keepparameternames
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
                SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-keep public class * {
    public protected *;
}

-keepclassmembernames class * {
    java.lang.Class class$(java.lang.String);
    java.lang.Class class$(java.lang.String, boolean);
}

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

【问题讨论】:

  • Proguard 会这样做。你试过吗?你也可以只复制你想要的类并使用它们。
  • 我在我的问题中提到了 Proguard,但在您发表评论后,我对其进行了编辑以澄清。谢谢。
  • 你能发布你脚本的相关部分吗?
  • 我没有脚本,因为它都是基于 GUI 的。根据您的评论,我编辑了我的问题以显示我在 ProGuard 中选择的缩小选项(我基本上保留了默认值)。
  • 我从未使用过 Proguard 的 GUI,但我猜想相关位在输入/输出选项卡中。正如 Stephen C 建议的那样,如果您通过脚本运行它,您可能会更幸运地找到帮助(并跟踪未来的问题)。

标签: java proguard


【解决方案1】:

-libraryjars 包含假定在运行时可用于优化应用的代码。也就是说,Proguard 不会将它们包含在其输出中;它只需要它们作为参考,因为它正在处理-injars 中的代码。

暂时拿走 Proguard:如果没有这个库类,您原来的未优化 JAR 也无法工作,对吧? Proguard 不会改变这一点。

如果您希望将其打包到优化输出中,则它必须存在于输入中。您必须将这些额外的 jar 包含为 -injars,或者首先将 JAR 与输入一起添加,以便它们出现在输出中。

但是,是的:Proguard 可以删除未使用的类,包括您从其他库中内置的类,如果您将其配置为。

【讨论】:

    【解决方案2】:

    虽然对您来说为时已晚,但这里的工具正是您想要的:

    工具minimize-jar 删除未使用的类并根据verbose:class 信息创建一个超级jar。它只有 5KB 并且没有依赖关系。

    【讨论】:

      【解决方案3】:

      根据我对手册的阅读,ProGuard 确实为它处理的 JAR 文件省略了未使用的类。所以我怀疑你没有处理pdfbox.jar 文件;也就是说,您只需将它放在类路径中。


      我建议您从脚本而不是 GUI 运行 Proguard。这将允许您将混淆步骤合并到您的主要构建脚本中,对脚本进行版本控制并......向其他人展示脚本以获得他们的建议/帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-11
        • 1970-01-01
        • 1970-01-01
        • 2019-08-13
        • 2010-09-29
        • 2014-06-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多