項目中需要對代碼進行混淆處理,由于項目是标準的maven項目,便使用了 proguard-maven-plugin
來自動化混淆過程,但是在使用過程中也不免踩到了一些坑,網上也很少有提及,在此記錄一下。
踩過的坑
spring bean名稱沖突問題
預設proguard混淆後的類名類似a.class,b.class,但是不同包路徑下類名可能發生重名,在spring中預設會把類名作為bean的名稱,導緻會報spring bean名稱沖突的問題,可以通過重新實作
BeanNameGenerator
接口來解決:
@SpringBootApplication
@ComponentScan("com.abc.def")
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class)
.beanNameGenerator(new CustomBeanNameGenerator())
.run(args);
}
private static class CustomBeanNameGenerator implements BeanNameGenerator {
@Override
public String generateBeanName(BeanDefinition d, BeanDefinitionRegistry r) {
return d.getBeanClassName();
}
}
}
spring擷取不到jar包裡的包路徑
spring boot啟動後實作
ApplicationRunner
接口的初始化類并沒有執行,也沒有錯誤日志産生。後來把spring容器注冊的Bean列印出來發現除了入口類和spring自己的類都沒有加載。spring啟動debug模式并調整日志級别為
TRACE
,發現spring沒有解析出包含basePackage的jar包來,假設basePackage為
com/abc/def/
,不混淆代碼的日志如下:
2019-11-24 19:33:49.703 [TRACE] [main] [o.s.c.i.s.PathMatchingResourcePatternResolver : 323] Resolved classpath location [com/abc/def/] to resources [URL [jar:file:/tmp/foo/lib/service-facade-1.0.jar!com/abc/def/], URL [jar:file:/tmp/foo/lib/service-impl-1.0.jar!com/abc/def/]]
經proguard混淆後日志如下:
2019-11-24 19:33:49.703 [TRACE] [main] [o.s.c.i.s.PathMatchingResourcePatternResolver : 323] Resolved classpath location [com/abc/def/] to resources []
但是将混淆後jar包先解壓後再壓縮處理,卻可以正常加載。也就是說proguard在打包過程中把包路徑資訊丢失了。需要配置
keepdirectories
參數。
JDK9編譯的jar包類沖突
JDK9編譯出來的jar包會和一些類沖突,需要配置
inLibsFilter
排除掉。
多jar包混淆
預設
proguard-maven-plugin
插件隻能通過
injar
參數将一個jar包混淆,而常見的項目都是多子產品項目,這時就需要通過配置
assembly
參數來實作。
參考配置
Pom.xml:
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.2.0</version>
<executions>
<execution>
<id>release</id>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
<configuration>
<assembly>
<inclusions>
<inclusion>
<groupId>com.abc.def</groupId>
<artifactId>lib1</artifactId>
</inclusion>
<inclusion>
<groupId>com.abc.def</groupId>
<artifactId>lib2</artifactId>
</inclusion>
</inclusions>
</assembly>
<!--exclude jdk9-->
<inLibsFilter>!META-INF/versions/9/**.class</inLibsFilter>
<proguardInclude>proguard.conf</proguardInclude>
<libs>
<lib>${java.home}/lib/rt.jar</lib>
<lib>${java.home}/lib/jce.jar</lib>
</libs>
<!--<silent>true</silent>-->
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-base</artifactId>
<version>6.2.0</version>
</dependency>
</dependencies>
</plugin>
proguard.conf:
-dontshrink
-dontoptimize
-keepdirectories
-adaptclassstrings
-dontusemixedcaseclassnames
-flattenpackagehierarchy 'com.abc.def'
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
-keep class com.abc.def.Application
-keep class * extends org.springframework.boot.ApplicationRunner
# Keep - Applications. Keep all application classes, along with their 'main'
# methods.
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
# Also keep - Enumerations. Keep the special static methods that are required in
# enumeration classes.
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# Keep names - Native method names. Keep all native class/method names.
-keepclasseswithmembers,includedescriptorclasses,allowshrinking class * {
native <methods>;
}