【问题标题】:Problems obfuscating with ProGuard an uberjar使用 ProGuard 混淆 uberjar 的问题
【发布时间】: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


【解决方案1】:

我在一个更大的 Maven 项目中遇到了同样的问题。
我通过添加 javax.servlet.jsp 来修复它,这样 Proguard 就可以找到丢失的超类。
由于我的项目性质,我将其添加为 pom.xml 中的 Maven 依赖项:

<dependency>
  <groupId>javax.servlet.jsp</groupId>
  <artifactId>javax.servlet.jsp-api</artifactId>
  <version>2.3.3</version>
  <scope>provided</scope>
</dependency>

TL;DR(我是如何到达那里的)

  • 从其mvn repo 下载最新的(在撰写本文时)freemarker-2.3.31-sources.jar
  • 通过jar xf freemarker-2.3.31-sources.jar控制台命令展开其内容
  • 探索结果树到freemarker\ext\jsp\TagTransformModel.java
  • getWriter(Writer out, Map args) 方法使用 JspWriter,来自 L31 的 import javax.servlet.jsp
  • 可从其mvn repo 获得,因此在上述解决方案中新包含了依赖项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 1970-01-01
    • 2012-06-24
    • 2021-08-10
    • 1970-01-01
    相关资源
    最近更新 更多