如何在构建“maven-plugin”软件包时使用Proguard混淆?
“maven-plugin”项目(使用 maven-plugin-plugin)生成的输出 JAR 被 Proguard 工具执行的模糊处理所破坏。尝试将混淆的JAR用作Maven插件会生成异常,例如MojoExecutionException,这会终止构建并显示错误。有哪些正确的Proguard配置选项可以允许生成包含自动生成的插件描述符的工作“maven-plugin”JAR?
“maven-plugin”项目(使用 maven-plugin-plugin)生成的输出 JAR 被 Proguard 工具执行的模糊处理所破坏。尝试将混淆的JAR用作Maven插件会生成异常,例如MojoExecutionException,这会终止构建并显示错误。有哪些正确的Proguard配置选项可以允许生成包含自动生成的插件描述符的工作“maven-plugin”JAR?
为了生成 Maven 插件(maven 打包类型“maven-plugin”,它生成包含插件特定配置资源的 JAR),我们必须指示 maven-plugin-plugin 关于我们的 Mojos 的位置和名称。假设使用注释或其他配置选项执行正确配置的 maven-plugin-plugin,生成的 JAR 将在 JAR 根目录下的 META-INF 目录中包含一个插件.xml文件。此插件.xml文件使用对 Java 类和包名称的静态引用来描述插件的目标和可配置参数(您可以在此处找到有关此文件的更多信息)。
必须特别注意将混淆合并到“maven-plugin”JAR的构建中;在这里,我们解释了使用Proguard混淆库所采取的步骤。使用默认的 Proguard 配置进行库模糊处理时,生成的 JAR 将不再正常工作,因为 Proguard 会重命名、缩小、重新定位和模糊处理 Maven 插件的重要文件。尝试使用插件可能会导致异常,从而终止构建,并显示与 Maven 运行时无法找到和处理插件的配置和类文件相关的错误。
但是,通过一些重新配置,我们可以指示Proguard正确维护生成的插件文件和“maven插件”JAR的目录结构。对 Proguard 选项的必要更改如下所示(请参阅有关以下链接的说明):
-keepdirectories
这指示 Proguard 维护输入 JAR 目录结构,而不是将所有文件移动到根目录。Maven 希望插件.xml文件位于 /META-INF/maven/ 目录中,该目录通过此选项与所有其他目录一起保存。您可以通过指定目录过滤器来更具体地过滤保留的目录,但是我选择不加选择地维护所有输入目录结构。
静态包引用-keeppackagenames org.apache.maven.plugin.my.MyMojo
您应该将占位符包替换为包含 Mojo 定义的包。如果您的 Mojo 定义不共享一个公共包,则应根据需要使用多个选项指定每个唯一包。如果您不确定需要保留哪些包,请在文本编辑器中打开生成的插件.xml文件,并检查每个“mojo”定义中的“实现”元素。“实现”元素通过完全限定名指定类。这些完全限定类名的每个包组件都是应指定的包。例如,我的basesir插件包含一个Mojo实现元素值“com.github.emabrey.maven.plugins.basedir.RootDirectoryGoal”,所以我会把选项写成.-keeppackagenames com.github.emabrey.maven.plugins.basedir
-keepnames class * implements org.apache.maven.plugin.AbstractMojo
此选项可防止 Proguard 重命名包含 Maven 插件 Mojo 实现的类。如果重命名这些类,上述“实现”元素将不再正确标识包含 Mojo 实现的类。
私有类字段和方法-keepclassmembers class * implements org.apache.maven.plugin.AbstractMojo {
private <fields>;
private <methods>;
}
此选项可防止 Proguard 重命名插件 Mojo 实现中的类级方法和字段。Maven 使用这些类字段/方法的名称来生成插件的配置元素。如果 Proguard 重命名字段,则 Maven 执行环境将无法使用用户配置正确填充 Mojo 实现。
版本2.0.13的完整配置(此处有更多版本;请参阅有关插件版本的注释),包括默认库配置以及上述修改,此处提供,以方便您使用最新版本的proguard-base工件指定属性,并将占位符包“org.apache.maven.plugin.my.MyMojo”替换为适当的值):${tool.proguard.version}
<!-- Configures Proguard obfuscation tool to generate an
obfuscated version of the JAR file that replaces the
default unobfuscated JAR.
-->
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.13</version>
<executions>
<execution>
<id>obfuscation-packaging</id>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
<configuration>
<proguardVersion>${tool.proguard.version}</proguardVersion>
<obfuscate>true</obfuscate>
<attach>true</attach>
<appendClassifier>false</appendClassifier>
<addMavenDescriptor>true</addMavenDescriptor>
<injar>${project.build.finalName}.jar</injar>
<injarNotExistsSkip>true</injarNotExistsSkip>
<libs>
<lib>${java.home}/lib/rt.jar</lib>
</libs>
<options>
<option>-keepdirectories</option>
<option>-keeppackagenames org.apache.maven.plugin.my.MyMojo</option>
<option>-keepnames class * implements org.apache.maven.plugin.AbstractMojo</option>
<option>-keepclassmembers class * implements org.apache.maven.plugin.AbstractMojo {
private <![CDATA[<fields>]]>;
private <![CDATA[<methods>]]>;
}
</option>
<option>-keepparameternames</option>
<option>-renamesourcefileattribute SourceFile</option>
<option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
</option>
<option>-target 1.8</option>
<option>-keep public class * {
public protected *;
}
</option>
<option>-keepclassmembernames class * {
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);
}
</option>
<option>-keepclasseswithmembernames,includedescriptorclasses class * {
native <![CDATA[<methods>]]>;
}
</option>
<option>-keepclassmembers,allowoptimization enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
</option>
<option>-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();
}
</option>
</options>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-base</artifactId>
<version>${tool.proguard.version}</version>
</dependency>
</dependencies>
</plugin>
链接问题 (9-04-2019)
Proguard网站存在某种问题,这意味着我指向程序选项的链接并不总是像锚点包含锚点的链接那样转到锚点的位置。如果您没有看到您点击的选项最初显示在其网页上,只需稍微向上滚动即可。
proguard-maven-plugin 的版本问题 (9-04-2019)
的当前版本是截至2017年3月,直到进行此编辑为止。我将保留原始配置和版本号不变,因为版本包含潜在的重大更改。它现在包括种子和映射文件,作为最终 Proguard 混淆伪影的输出工件的一部分。大多数用例实际上不太可能在工件中使用其他文件时遇到任何问题,但是我没有忍者编辑指向的配置,而是留下了此注释,并让您评估哪个版本适合您的项目。也就是说,简单地将版本更改为应该是可以的,因为在版本的提交历史记录中没有记录任何插件配置更改。com.github.wvengen:proguard-maven-plugin
2.0.14
2.0.13
2.0.14
2.0.14
<version>2.0.14</version>
2.0.14