【发布时间】:2022-01-24 18:17:27
【问题描述】:
我已经围绕第三方库(如 TestNG、Selenium 等)构建了一个相当大的框架。
作为一项要求,我需要在分发代码之前对其进行模糊处理。
要分发代码,我必须创建一个包含所有依赖项的单个 jar,我在使用 maven-shade 时没有问题。
当尝试使用 ProGuard 对其进行一些轻度混淆时,问题就开始了,我没有在没有依赖关系的情况下对 jar 进行混淆(省略阴影阶段)。
我在 POM 中使用以下设置。
阴影阶段
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformerimplementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.mycompany.main.Init</mainClass>
</transformer>
</transformers>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
<filter>
<artifact>com.google.inject:guice</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>org.apache.xmlbeans:xmlbeans</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>org.freemarker:freemarker</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>org.apache.poi:poi-ooxml-schemas</artifact>
<includes>
<include>**</include>
</includes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
ProGuard 阶段
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<injar>${project.build.finalName}.jar</injar>
<outjar>${project.build.finalName}-uber.jar</outjar>
<inFilter>!META-INF/versions/9/**.class</inFilter>
<options>
<option>-dontshrink</option>
<option>-keep class !com.mycompany.**,!com.mycompany.** { *; }</option>
<option>-keep class io.**</option>
<option>-keep class org.**</option>
<option>-keep class com.google.**</option>
<option>-keep class freemarker.**</option>
<option>-keep class javax.**</option>
<option>-keep class com.sun.**</option>
<option>-keep class com.jacob.**</option>
<option>-keep class net.**</option>
<option>-keep class com.google.**</option>
<option>-ignorewarnings</option>
<option>-keepdirectories</option>
<option>-dontnote</option>
<option>-dontwarn org.**</option>
<option>-dontwarn io.**</option>
<option>-dontwarn com.fasterxml.**</option>
<option>-dontwarn okio.**</option>
<option>-dontwarn okhttp3.**</option>
<option>-dontwarn freemarker.**</option>
<option>-dontwarn com.microsoft.**</option>
<option>-libraryjars ${java.home}/lib/rt.jar</option>
<option>-libraryjars ${java.home}/lib/jce.jar</option>
<option>-allowaccessmodification</option>
</options>
<obfuscate>true</obfuscate>
</configuration>
<dependencies>
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-base</artifactId>
<version>6.1.1</version>
</dependency>
</dependencies>
</plugin>
返回的 Stacktrace(部分)
[proguard] Warning: library class javax.mail.search.SearchException extends or implements program class javax.mail.MessagingException
[proguard] Warning: library class javax.mail.search.StringTerm extends or implements program class javax.mail.search.SearchTerm
[proguard] Warning: library class javax.mail.util.ByteArrayDataSource extends or implements program class javax.activation.DataSource
[proguard] Warning: library class javax.mail.util.SharedFileInputStream extends or implements program class javax.mail.internet.SharedInputStream
[proguard] Warning: there were 369 instances of library classes depending on program classes.
[proguard] You must avoid such dependencies, since the program classes will
[proguard] be processed, while the library classes will remain unchanged.
[proguard] (http://proguard.sourceforge.net/manual/troubleshooting.html#dependency)
[proguard] Unexpected error while performing partial evaluation:
[proguard] Class = [freemarker/ext/jsp/TagTransformModel]
[proguard] Method = [getWriter(Ljava/io/Writer;Ljava/util/Map;)Ljava/io/Writer;]
[proguard] Exception = [java.lang.IllegalArgumentException] (Can't find common super class of [freemarker/ext/jsp/JspWriterAdapter] (with 1 known super classes) and [java/io/Writer] (with 2 known super classes))
[proguard] Error: java.lang.IllegalArgumentException: Can't find common super class of [freemarker/ext/jsp/JspWriterAdapter] (with 1 known super classes) and [java/io/Writer] (with 2 known super classes)
我猜问题出在 ProGuard 试图从 .jar 外部获取依赖项,而不是仅使用内部的依赖项,但我不知道,如果有办法的话,也找不到让 ProGuard 使用 uberjar 上的库,或者,我试图混淆 jar 的方式可能是错误的
【问题讨论】:
-
我感觉 ProGuard 正在寻找包
javax.mail但找不到。要么将javax.mail放在你的类路径上,要么配置 ProGuard 以忽略该特定包。不过我猜,买者自负。 -
看来问题出在阴影阶段。当正确的是 freemarker 时,我指定了 org.freemarker。构建现在正确完成,但问题仍然存在¿当 uberjar 应该拥有所有库类时,为什么要寻找库类?另一个需要研究的谜团。
-
先混淆你的代码然后创建 uber jar,你在混淆库 jar 中没有任何收获
-
是的,这是我的第一个想法。但是因为我无法让它发挥作用,它把所有东西都打包了,就像从来没有发生过滥用行为一样。目前我忽略了使用
-keep class !com.mycompany.**,!com.mycompany.** { *; }的库jar。阶段持续时间约为 4 分钟,结果是 30mb 的 .jar。我很确定它可以优化,可能就像你建议的那样。我会尽量腾出时间,再试一次,然后带着结果回来。谢谢。
标签: java proguard maven-shade-plugin uberjar