1. 程式人生 > >**Proguard+Maven混淆java web專案**

**Proguard+Maven混淆java web專案**

Proguard+Maven混淆java web專案## 標題
這裡用到的是常用配置,更多詳細配置方法和引數資訊見官網:https://www.guardsquare.com/en/products/proguard/manual/usage#keepoptions

  1. proguard常用關鍵字
    dontshrink 不壓縮
    dontoptimize 不優化
    keep 保留類和類中的成員,防止被混淆或移除
    keepclassmembers 只保留類中的成員,防止被混淆或移除
    dontwarn 一個和keep可以說是形影不離,尤其是處理引入的library時,不顯示警告資訊

  2. proguard萬用字元

    *匹配任意長度字元,不包含包名分隔符(.)
    ** 匹配任意長度字元,包含包名分隔符(.)
    *** 匹配任意引數型別

  3. 哪些不應該混淆
    a. 使用了列舉要保證列舉不被混淆
    b. 對第三方庫中的類不進行混淆
    c. 運用了反射的類也不進行混淆
    d. 交給Spring管理的類
    e. JNI中呼叫的類
    f. Test類

  4. 混淆模板
    a. 在需要被混淆工程的pom檔案中加入以下配置,具體配置的引數意義已註釋。

    <plugins>
    		<!-- ProGuard混淆外掛-->
            <plugin>
                <groupId>com.github.wvengen</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <version>2.0.11</version>
                <executions>
                    <execution>
                        <!-- 混淆時刻,這裡是打包的時候混淆-->
                        <phase>package</phase>
                        <goals>
                            <!-- 使用外掛的什麼功能,當然是混淆-->
                            <goal>proguard</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <!-- 是否將生成的PG檔案安裝部署-->
                    <attach>true</attach>
                    <!-- 是否混淆-->
                    <obfuscate>true</obfuscate>
                    <!-- 指定生成檔案分類 -->
                    <attachArtifactClassifier>pg</attachArtifactClassifier>
                    <options>
                        <!-- JDK目標版本1.8-->
                        <option>-target 1.8</option>
                        <!-- 不做收縮(刪除註釋、未被引用程式碼)-->
                        <option>-dontshrink</option>
                        <!-- 不做優化(變更程式碼實現邏輯)-->
                        <option>-dontoptimize</option>
                        <!-- 不路過非公用類檔案及成員-->
                        <option>-dontskipnonpubliclibraryclasses</option>
                        <option>-dontskipnonpubliclibraryclassmembers</option>
                        <!-- 優化時允許訪問並修改有修飾符的類和類的成員 -->
                        <option>-allowaccessmodification</option>
                        
                        <!-- 確定統一的混淆類的成員名稱來增加混淆-->
                        <option>-useuniqueclassmembernames</option>
                        
                        <!-- 不混淆所有包名,本人測試混淆後WEB專案問題實在太多,畢竟Spring配置中有大量固定寫法的包名-->
                        <option>-keepdirectories</option>
                        
                        <!-- 排除所有註解類 -->
                        <option>-keep class * extends java.lang.annotation.Annotation { *; }</option>
                        <option>-keep interface * extends java.lang.annotation.Annotation { *; }</option>
                        <option>-keeppackagenames</option>
                        <option>-keepnames interface **</option>
                        
                        <!-- 不混淆所有特殊的類-->
                        <option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod</option>
                        
                        <!-- 不混淆所有的set/get方法,畢竟專案中使用的部分第三方框架會用到大量的set/get對映-->
                        <option>-keepclassmembers public class * {void set*(***);void set*(int,***);*** get*();*** get*(int);boolean is*();boolean is*(int);}</option>
						<option>-ignorewarnings</option> <!--忽略所有告警-->
						
						<!-- 不混淆lib下jar包裡面的class檔案,保留第三方jar包 -->
						<option>-keep class WebRoot.WEB-INFO.lib.*</option>
						
						<!-- 保留實現了java.beans.BeanInfo介面的類   -->
						<option>-keep class * implements java.beans.BeanInfo</option>
						
						<!-- 保留所有公共類中的main方法 -->
						<option>-keepclasseswithmembers public class * { public static void main(java.lang.String[]);}</option>
						
						<!-- 保留列舉中的指定的靜態方法   -->
						<option>-keepclassmembers enum * {public static **[] values(); public static ** valueOf(java.lang.String);} </option>
						
						<!-- 保持測試相關的程式碼 -->
						<option>-dontnote junit.framework.**</option>
						<option>-dontnote junit.runner.**</option>
						<option>-dontwarn android.test.**</option>
						<option>-dontwarn android.support.test.**</option>
						<option>-dontwarn org.junit.**</option>
						
						<!-- 保留所有序列化相關內容 -->
						<option>-keepclassmembers class * extends java.io.Serializable {  
    							static final long serialVersionUID;  
    							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>
						<!-- 保留所有方法名以class結尾的方法, 這可能導致已被混效過的將被再次混淆 -->
 						<option>-keepclassmembernames class * {  
    							java.lang.Class class$(java.lang.String);  
    							java.lang.Class class$(java.lang.String,boolean);  
						}</option>
						<!-- 不顯示warnning -->
						<!-- <option>-dontwarn</option> -->
						
						<!--以下配置為暴露在外被別的工程呼叫的類,不參與混淆-->
						<option>-keepclassmembers class 《包名》.** {public *; private *** *;}</option>
                 				<option>-keep class 《包名》.**</option>
                    </options>
                    
                    <!-- 新增執行依賴,不混淆 -->
                    <libs>
                        <lib>${java.home}/lib/rt.jar</lib>
                        <lib>${java.home}/lib/jsse.jar</lib>
						<lib>${java.home}/lib/jce.jar</lib>
						<lib>${java.home}/lib/charsets.jar</lib>
						<lib>${java.home}/lib/jfr.jar</lib>
						<lib>${java.home}/lib/ext/access-bridge-64.jar</lib>
						<lib>${java.home}/lib/ext/cldrdata.jar</lib>
						<lib>${java.home}/lib/ext/dnsns.jar</lib>
						<lib>${java.home}/lib/ext/jaccess.jar</lib>
						<lib>${java.home}/lib/ext/jfxrt.jar</lib>
						<lib>${java.home}/lib/ext/localedata.jar</lib>
						<lib>${java.home}/lib/ext/nashorn.jar</lib>
						<lib>${java.home}/lib/ext/sunec.jar</lib>
						<lib>${java.home}/lib/ext/sunjce_provider.jar</lib>
						<lib>${java.home}/lib/ext/sunmscapi.jar</lib>
						<lib>${java.home}/lib/ext/sunpkcs11.jar</lib>
						<lib>${java.home}/lib/ext/zipfs.jar</lib>
                    </libs>
                    <addMavenDescriptor>false</addMavenDescriptor>
                    <!-- 輸入 -->
                    <injar>${project.build.finalName}.jar</injar>
                    <!-- 輸出 -->
                    <outjar>${project.build.finalName}-pg.jar</outjar>
                    <outputDirectory>${project.build.directory}</outputDirectory>

                </configuration>
            </plugin>
    	</plugins>

b. 配置完成後,maven clean compile install到本地倉庫,以備被其他工程依賴。

  1. 工程相互依賴(A依賴混淆後的B工程)
    在A工程的pom檔案中的依賴中加入如下配置
		<dependency>
			<groupId>com.iflytek</groupId>
			<artifactId>B</artifactId>
			<!—如果需要依賴被混淆過後的B工程,需要用此分類標識,否則則不用 -->
			<classifier>pg</classifier>
			<version>${ version}</version>
		</dependency>