ProGuard-壓縮-混淆

ProGuard是一個(gè)Java類文件壓縮器、優(yōu)化器、混淆器和預(yù)校驗(yàn)器。

壓縮步驟檢測(cè)并刪除未使用的類、字段、方法和屬性。優(yōu)化步驟分析和優(yōu)化方法的字節(jié)碼?;煜襟E使用無(wú)意義的簡(jiǎn)短名稱重命名其余的類、字段和方法。這些第一步使代碼庫(kù)更小、更高效,并且更難進(jìn)行反向工程。最后一個(gè)預(yù)驗(yàn)證步驟將預(yù)驗(yàn)證信息添加到類中,這是Java微版本所必需的,或者可以縮短Java 6的啟動(dòng)時(shí)間。

這些步驟都是可選的。例如,ProGuard還可以僅用于列出應(yīng)用程序中的死代碼,或者用于預(yù)驗(yàn)證類文件,以便在Java 6中高效使用。

proguard1.png

ProGuard通常讀取輸入jar(或war、ear、zip或目錄)。然后它會(huì)收縮、優(yōu)化、混淆和預(yù)先驗(yàn)證它們??蛇x地,可以執(zhí)行多個(gè)優(yōu)化傳遞,每個(gè)優(yōu)化傳遞之后通常會(huì)執(zhí)行另一個(gè)收縮步驟。ProGuard將處理后的結(jié)果寫(xiě)入一個(gè)或多個(gè)輸出jar(或war、ear、zips或目錄)。輸入可能包含資源文件,其名稱和內(nèi)容可以選擇性地進(jìn)行更新,以反映混淆的類名。

ProGuard需要指定輸入jar的庫(kù)jar(或war、ear、zip或目錄)。這些基本上是編譯代碼所需的庫(kù)。ProGuard使用它們重構(gòu)正確處理所需的類依賴項(xiàng)。庫(kù)jar本身始終保持不變。您仍然應(yīng)該將它們放在最終應(yīng)用程序的類路徑中。

入口點(diǎn)

為了確定哪些代碼必須保留,哪些代碼可以丟棄或混淆,必須為代碼指定一個(gè)或多個(gè)入口點(diǎn)。這些入口點(diǎn)通常是帶有主方法、applet、midlet等的類。

  • 在收縮步驟中,ProGuard從這些種子開(kāi)始,遞歸地確定使用哪些類和類成員。所有其他類和類成員都將被丟棄。
  • 在優(yōu)化步驟中,ProGuard進(jìn)一步優(yōu)化代碼。在其他優(yōu)化中,可以將非入口點(diǎn)的類和方法設(shè)置為私有的、靜態(tài)的或最終的,可以刪除未使用的參數(shù),并且可以內(nèi)聯(lián)一些方法。
  • 在混淆步驟中,ProGuard重命名不是入口點(diǎn)的類和類成員。在整個(gè)過(guò)程中,保留入口點(diǎn)可以確保仍然可以通過(guò)它們的原始名稱訪問(wèn)它們。
  • 預(yù)驗(yàn)證步驟是唯一不需要知道入口點(diǎn)的步驟。

本手冊(cè)的使用部分描述了必要的-keep選項(xiàng),示例部分提供了大量示例。

反射

對(duì)于任何代碼的自動(dòng)處理,反射和內(nèi)省都會(huì)帶來(lái)特定的問(wèn)題。在ProGuard中,動(dòng)態(tài)創(chuàng)建或調(diào)用(即按名稱)的代碼中的類或類成員也必須指定為入口點(diǎn)。例如,class . forname()構(gòu)造可以在運(yùn)行時(shí)引用任何類。通常不可能預(yù)知必須保留哪些類(使用它們的原始名稱),因?yàn)轭惷赡軓呐渲梦募凶x取,例如。因此,必須在ProGuard配置中使用相同的-keep選項(xiàng)指定它們。
但是,ProGuard已經(jīng)為您檢測(cè)并處理以下情況:

  • Class.forName("SomeClass")
  • SomeClass.class
  • SomeClass.class.getField("someField")
  • SomeClass.class.getDeclaredField("someField")
  • SomeClass.class.getMethod("someMethod", new Class[] {})
  • SomeClass.class.getMethod("someMethod", new Class[] { A.class })
  • SomeClass.class.getMethod("someMethod", new Class[] { A.class, B.class })
  • SomeClass.class.getDeclaredMethod("someMethod", new Class[] {})
  • SomeClass.class.getDeclaredMethod("someMethod", new Class[] { A.class })
  • SomeClass.class.getDeclaredMethod("someMethod", new Class[] { A.class, B.class })
  • AtomicIntegerFieldUpdater.newUpdater(SomeClass.class, "someField")
  • AtomicLongFieldUpdater.newUpdater(SomeClass.class, "someField")
  • AtomicReferenceFieldUpdater.newUpdater(SomeClass.class, SomeType.class, "someField")

類和類成員的名稱當(dāng)然可能不同,但是構(gòu)造應(yīng)該完全相同,這樣ProGuard才能識(shí)別它們。引用的類和類成員保存在收縮階段,字符串參數(shù)在混淆階段正確更新。
此外,如果有必要保留一些類或類成員,ProGuard將提供一些建議。例如,ProGuard會(huì)注意到這樣的構(gòu)造:“(SomeClass)Class.forName(variable). newinstance()”。這可能表明類或接口的SomeClass和/或其實(shí)現(xiàn)可能需要保留。然后可以相應(yīng)地調(diào)整配置。

要獲得適當(dāng)?shù)慕Y(jié)果,您至少應(yīng)該對(duì)正在處理的代碼有一定程度的熟悉。執(zhí)行大量反射的混淆代碼可能需要反復(fù)試驗(yàn),特別是在沒(méi)有關(guān)于代碼內(nèi)部結(jié)構(gòu)的必要信息的情況下。

Keep 可選項(xiàng)

-keep [,modifier,...] class_specification

指定要保留為代碼入口點(diǎn)的類和類成員(字段和方法)。例如,為了保留應(yīng)用程序,可以指定主類及其主方法。為了處理庫(kù),您應(yīng)該指定所有可公開(kāi)訪問(wèn)的元素。

-keepclassmembers [,modifier,...] class_specification

指定要保留的類成員(如果它們的類也被保留的話)。例如,您可能希望保留實(shí)現(xiàn)Serializable接口的類的所有序列化字段和方法。

-keepclasseswithmembers [,modifier,...] class_specification

指定要保留的類和類成員,條件是所有指定的類成員都存在。例如,您可能希望保留所有具有 main 方法的應(yīng)用程序,而不需要顯式地列出它們。

-keepnames class_specification

-keep, allowclass_specification 的縮寫(xiě)

指定要保留其名稱的類和類成員(如果在收縮階段沒(méi)有刪除這些名稱)。例如,您可能希望保留實(shí)現(xiàn)Serializable接口的類的所有類名,以便處理后的代碼與任何最初序列化的類保持兼容。完全不使用的類仍然可以被刪除。僅適用于模糊。

keepclassmembernames class_specification
  • keepembers,allowshrinking class_specification 的縮寫(xiě)

指定要保留其名稱(如果在收縮階段沒(méi)有刪除這些名稱)的類成員。例如,在處理JDK 1.2或更早版本編譯的庫(kù)時(shí),您可能希望保留合成類$ methods的名稱,這樣在處理使用處理過(guò)的庫(kù)的應(yīng)用程序時(shí),混淆器可以再次檢測(cè)它(盡管ProGuard本身不需要這個(gè))。僅適用于模糊。

-keepclasseswithmembernames class_specification

-keepclasseswithmembers,allowshrinking class_specification 的縮寫(xiě)

指定要保留其名稱的類和類成員,條件是在收縮階段之后所有指定的類成員都出現(xiàn)。例如,您可能希望保留所有 native 方法名稱及其類的名稱,以便處理后的代碼仍然可以鏈接到本機(jī)庫(kù)代碼。完全不使用的本地方法仍然可以被刪除。如果使用了類文件,但是沒(méi)有使用它的本機(jī)方法,那么它的名稱仍然是模糊的。僅適用于模糊。

-printseeds [filename]

指定詳細(xì)列出由各種-keep選項(xiàng)匹配的類和類成員。列表被打印到標(biāo)準(zhǔn)輸出或給定文件中。如果確實(shí)找到了想要的類成員,特別是在使用通配符的情況下,這個(gè)列表非常有用。例如,您可能想要列出您保存的所有應(yīng)用程序或所有applet。

壓縮 可選項(xiàng)

-dontshrink

指定不壓縮輸入類文件。默認(rèn)情況下,應(yīng)用是開(kāi)啟壓縮的;所有類和類成員都被刪除,除了各種-keep選項(xiàng)列出的類和它們直接或間接依賴的類。在每個(gè)優(yōu)化步驟之后還應(yīng)用收縮步驟,因?yàn)橐恍﹥?yōu)化可能會(huì)刪除更多的類和類成員。

-printusage [filename]

指定列出輸入類文件的死代碼。列表被打印到標(biāo)準(zhǔn)輸出或給定文件中。例如,您可以列出應(yīng)用程序未使用的代碼。僅適用于開(kāi)啟壓縮時(shí)。

-whyareyoukeeping class_specification

指定打印有關(guān)為什么在收縮步驟中保留給定類和類成員的詳細(xì)信息。如果您想知道為什么輸出中會(huì)出現(xiàn)某些給定的元素,那么這將非常有用。一般來(lái)說(shuō),有很多不同的原因。此選項(xiàng)為每個(gè)指定的類和類成員將最短的方法鏈打印到指定的種子或入口點(diǎn)。在當(dāng)前實(shí)現(xiàn)中,打印出來(lái)的最短鏈有時(shí)可能包含循環(huán)扣除額——這些扣除額并不反映實(shí)際的收縮過(guò)程。如果指定-verbose選項(xiàng),則跟蹤包含完整的字段和方法簽名。僅適用于開(kāi)啟壓縮時(shí)。

優(yōu)化 可選項(xiàng)

-dontoptimize

指定不優(yōu)化輸入類文件。默認(rèn)情況下,優(yōu)化是啟用的;所有方法都在字節(jié)碼級(jí)別上進(jìn)行了優(yōu)化。

-optimizations optimization_filter

在更細(xì)粒度的級(jí)別上指定要啟用和禁用的優(yōu)化。僅適用于優(yōu)化時(shí)。這是一個(gè)專家的選擇。

-optimizationpasses n

指定要執(zhí)行的優(yōu)化傳遞的次數(shù)。默認(rèn)情況下,只執(zhí)行一次傳遞。多次傳遞可能會(huì)導(dǎo)致進(jìn)一步的改進(jìn)。如果優(yōu)化通過(guò)后沒(méi)有發(fā)現(xiàn)任何改進(jìn),則優(yōu)化結(jié)束。僅適用于優(yōu)化時(shí)。

-assumenosideeffects class_specification

指定在處理過(guò)程中可以擴(kuò)展類和類成員的訪問(wèn)修飾符。這可以改善優(yōu)化步驟的結(jié)果。例如,在內(nèi)聯(lián)公共getter時(shí),可能還需要將訪問(wèn)的字段也變?yōu)楣驳摹1M管Java的二進(jìn)制兼容性規(guī)范在形式上不要求這樣做(cfr)。Java語(yǔ)言規(guī)范,第二版,第13.4.6節(jié)),一些虛擬機(jī)將有問(wèn)題的處理代碼,否則。僅適用于優(yōu)化時(shí)(以及使用-repackageclasses選項(xiàng)混淆時(shí))。
反指示:在處理要用作庫(kù)的代碼時(shí),可能不應(yīng)該使用此選項(xiàng),因?yàn)樵贏PI中設(shè)計(jì)為非公共的類和類成員可能會(huì)變成公共的。

-mergeinterfacesaggressively

指定可以合并接口,即使接口的實(shí)現(xiàn)類沒(méi)有實(shí)現(xiàn)所有接口方法。這可以通過(guò)減少類的總數(shù)來(lái)減少輸出的大小。注意,Java的二進(jìn)制兼容性規(guī)范允許這樣的構(gòu)造(cfr)。Java語(yǔ)言規(guī)范,第二版,第13.5.3節(jié)),即使它們?cè)贘ava語(yǔ)言中是不允許的(cfr)。Java語(yǔ)言規(guī)范,第二版,第8.1.4節(jié))。僅適用于優(yōu)化時(shí)。

反指示:設(shè)置此選項(xiàng)會(huì)降低某些jvm上處理的代碼的性能,因?yàn)楦呒?jí)即時(shí)編譯傾向于使用較少實(shí)現(xiàn)類的更多接口。更糟糕的是,一些jvm可能無(wú)法處理生成的代碼。值得注意的是:

Sun的JRE 1.3在一個(gè)類中遇到超過(guò)256個(gè)Miranda方法(沒(méi)有實(shí)現(xiàn)的接口方法)時(shí),可能會(huì)拋出一個(gè)內(nèi)部錯(cuò)誤。

混淆 可選項(xiàng)

-dontobfuscate

指定不混淆輸入類文件。默認(rèn)情況下,應(yīng)用混淆;類和類成員接收新的短隨機(jī)名稱,但不同的-keep選項(xiàng)列出的名稱除外。刪除對(duì)調(diào)試有用的內(nèi)部屬性,如源文件名、變量名和行號(hào)。

-printmapping [filename]

指定為已重命名的類和類成員打印從舊名稱到新名稱的映射。映射被打印到標(biāo)準(zhǔn)輸出或給定文件中。例如,對(duì)于后續(xù)的增量混淆,或者如果您希望再次理解混淆的堆棧跟蹤,就需要使用它。僅適用于開(kāi)啟混淆。

-applymapping filename

指定重用在前一次混淆運(yùn)行ProGuard時(shí)打印出的給定名稱映射。映射文件中列出的類和類成員接收與其一起指定的名稱。未提及的類和類成員將接收新名稱。映射可以引用輸入類和庫(kù)類。此選項(xiàng)對(duì)于增量混淆非常有用,即處理現(xiàn)有代碼片段的外接程序或小補(bǔ)丁。在這種情況下,您應(yīng)該考慮是否還需要選項(xiàng)—使用uniqueclassmembernames。只允許一個(gè)映射文件。僅適用于開(kāi)啟混淆。

-obfuscationdictionary filename

指定一個(gè)文本文件,其中所有有效單詞都用作混淆字段和方法名稱。默認(rèn)情況下,短名稱如“a”、“b”等用作混淆的名稱。通過(guò)使用混淆字典,您可以指定保留的關(guān)鍵字列表,或者具有外部字符的標(biāo)識(shí)符??崭?、標(biāo)點(diǎn)符號(hào)、重復(fù)單詞和#符號(hào)后的注釋將被忽略。請(qǐng)注意,混淆字典很難改善混淆。優(yōu)秀的編譯器可以自動(dòng)替換它們,通過(guò)使用更簡(jiǎn)單的名稱再次混淆,可以相當(dāng)簡(jiǎn)單地恢復(fù)效果。最有用的應(yīng)用程序是指定通常已經(jīng)出現(xiàn)在類文件中的字符串(如“代碼”),從而進(jìn)一步減小類文件的大小。僅適用于開(kāi)啟混淆。

-classobfuscationdictionary filename

指定一個(gè)文本文件,其中所有有效單詞都用作混淆類名?;煜值漕愃朴谶x項(xiàng)之一-混淆字典。僅適用于開(kāi)啟混淆。

-packageobfuscationdictionary filename

指定一個(gè)文本文件,其中所有有效的單詞都用作混淆的包名?;煜值漕愃朴谶x項(xiàng)之一-混淆字典。僅適用于開(kāi)啟混淆。

-overloadaggressively

指定在混淆時(shí)應(yīng)用主動(dòng)重載。然后,多個(gè)字段和方法可以獲得相同的名稱,只要它們的參數(shù)和返回類型不同(不僅僅是它們的參數(shù))。這個(gè)選項(xiàng)可以使處理后的代碼更小(更難以理解)。僅適用于開(kāi)啟混淆。

反指示:生成的類文件屬于Java字節(jié)碼規(guī)范(cfr)。Java虛擬機(jī)規(guī)范,第二版,4.5節(jié)和4.6節(jié)的第一段),盡管這種重載在Java語(yǔ)言中是不允許的(cfr)。Java語(yǔ)言規(guī)范,第二版,8.3節(jié)和8.4.7節(jié))。盡管如此,一些工具仍然存在問(wèn)題。

-useuniqueclassmembernames

指定將相同的混淆名稱分配給具有相同名稱的類成員,將不同的混淆名稱分配給具有不同名稱的類成員(針對(duì)每個(gè)給定的類成員簽名)。如果沒(méi)有這個(gè)選項(xiàng),可以將更多的類成員映射到相同的短名稱,如“a”、“b”等。因此,該選項(xiàng)略微增加了生成的代碼的大小,但它確保在后續(xù)的增量混淆步驟中始終尊重保存的混淆名稱映射。

例如,考慮兩個(gè)不同的接口,其中包含具有相同名稱和簽名的方法。如果沒(méi)有此選項(xiàng),這些方法可能在第一個(gè)混淆步驟中獲得不同的混淆名稱。如果隨后添加了一個(gè)包含實(shí)現(xiàn)這兩個(gè)接口的類的補(bǔ)丁,那么ProGuard將不得不在增量混淆步驟中為這兩個(gè)方法強(qiáng)制使用相同的方法名。原始的混淆代碼被更改,以保持生成的代碼一致。在初始混淆步驟中使用此選項(xiàng),將永遠(yuǎn)不需要進(jìn)行此類重命名。

僅適用于開(kāi)啟混淆。事實(shí)上,如果您計(jì)劃執(zhí)行增量混淆,您可能希望避免完全收縮和優(yōu)化,因?yàn)檫@些步驟可以刪除或修改代碼中對(duì)以后的添加非常重要的部分。

-dontusemixedcaseclassnames

指定在混淆時(shí)不要生成混合大小寫(xiě)的類名。默認(rèn)情況下,混淆的類名可以包含大寫(xiě)字符和小寫(xiě)字符的混合。這將創(chuàng)建完全可接受和可用的jar。只有在使用不區(qū)分大小寫(xiě)的歸檔系統(tǒng)(例如Windows)在平臺(tái)上解壓縮jar時(shí),解壓縮工具才可能讓名稱類似的類文件彼此覆蓋。解壓時(shí)自毀的代碼!真正想在Windows上解包jar的開(kāi)發(fā)人員可以使用這個(gè)選項(xiàng)來(lái)關(guān)閉這個(gè)行為。請(qǐng)注意,混淆的jar將因此變得更大。僅適用于開(kāi)啟混淆。

-keeppackagenames [package_filter]

指定不混淆給定的包名稱??蛇x過(guò)濾器是一個(gè)以逗號(hào)分隔的包名列表。包名可以包含?、*通配符,它們的前面可以有!非元件。僅適用于開(kāi)啟混淆。

-flattenpackagehierarchy [package_name]

指定通過(guò)將重命名的所有包移動(dòng)到給定的父包中來(lái)重新包裝它們。如果沒(méi)有參數(shù)或使用空字符串("),包將被移動(dòng)到根包中。這個(gè)選項(xiàng)是進(jìn)一步混淆包名稱的一個(gè)例子。它可以使處理后的代碼更小,更難以理解。僅適用于開(kāi)啟混淆。

-repackageclasses [package_name]

指定通過(guò)將重命名的所有類文件移動(dòng)到單個(gè)給定包中來(lái)重新打包。如果沒(méi)有參數(shù)或使用空字符串("),則該包將被完全刪除。此選項(xiàng)覆蓋-扁平化包層次結(jié)構(gòu)選項(xiàng)。這是進(jìn)一步混淆包名稱的另一個(gè)例子。它可以使處理后的代碼更小,更難以理解。它的棄用名稱是-defaultpackage。僅適用于開(kāi)啟混淆。
反指示:如果將在包目錄中查找資源文件的類轉(zhuǎn)移到其他地方,它們將不再正常工作。如果有疑問(wèn),請(qǐng)不要使用此選項(xiàng),以免影響包裝。

-keepattributes [attribute_filter]

指定保存所保存的參數(shù)名稱和方法類型。這個(gè)選項(xiàng)實(shí)際上保留了調(diào)試屬性LocalVariableTable和LocalVariableTypeTable的精簡(jiǎn)版本。它在處理庫(kù)時(shí)非常有用。一些ide可以使用這些信息來(lái)幫助使用這個(gè)庫(kù)的開(kāi)發(fā)人員,例如使用工具提示或自動(dòng)完成。僅適用于開(kāi)啟混淆。

-renamesourcefileattribute [string]

指定要放入類文件的SourceFile屬性(和SourceDir屬性)中的常量字符串。注意,屬性一開(kāi)始就必須存在,因此還必須使用-keepattributes指令顯式地保存它。例如,您可能希望處理后的庫(kù)和應(yīng)用程序生成有用的模糊堆棧跟蹤。僅適用于開(kāi)啟混淆。

-adaptclassstrings [class_filter]

指定與類名對(duì)應(yīng)的字符串常量也應(yīng)該混淆。如果沒(méi)有過(guò)濾器,所有與類名對(duì)應(yīng)的字符串常量都會(huì)被調(diào)整。對(duì)于篩選器,只有匹配篩選器的類中的字符串常量才會(huì)被調(diào)整。例如,如果您的代碼包含大量引用類的硬編碼字符串,并且您不希望保留它們的名稱,那么您可能希望使用這個(gè)選項(xiàng)。主要適用于混淆時(shí),雖然相應(yīng)的類也會(huì)自動(dòng)保存在收縮步驟中。

-adaptresourcefilenames [file_filter]

根據(jù)相應(yīng)類文件(如果有)的混淆名稱,指定要重命名的資源文件。如果沒(méi)有篩選器,與類文件對(duì)應(yīng)的所有資源文件都將被重命名。使用篩選器,只重命名匹配的文件。例如,請(qǐng)參見(jiàn)處理資源文件。僅適用于開(kāi)啟混淆。

-adaptresourcefilecontents [file_filter]

指定要更新其內(nèi)容的資源文件。資源文件中提到的任何類名都將根據(jù)相應(yīng)類(如果有的話)的混淆名稱進(jìn)行重命名。如果沒(méi)有篩選器,則更新所有資源文件的內(nèi)容。使用篩選器,只更新匹配的文件。資源文件使用平臺(tái)的默認(rèn)字符集進(jìn)行解析和編寫(xiě)。您可以通過(guò)設(shè)置環(huán)境變量LANG或Java系統(tǒng)屬性file.encoding來(lái)更改這個(gè)默認(rèn)字符集。例如,請(qǐng)參見(jiàn)處理資源文件。僅適用于開(kāi)啟混淆。

預(yù)校驗(yàn) 選項(xiàng)

-dontpreverify

指定不預(yù)驗(yàn)證處理后的類文件。默認(rèn)情況下,如果類文件的目標(biāo)是Java微版本或Java 6或更高版本,則會(huì)預(yù)先驗(yàn)證它們。對(duì)于Java微版本,需要預(yù)驗(yàn)證,因此如果指定此選項(xiàng),則需要對(duì)處理后的代碼運(yùn)行外部預(yù)驗(yàn)證器。對(duì)于Java 6,不需要(目前)預(yù)先驗(yàn)證,但是它提高了Java虛擬機(jī)中類加載的效率。

-microedition

指定處理后的類文件以Java微版本為目標(biāo)。然后,preverifier將添加適當(dāng)?shù)腟tackMap屬性,這與Java標(biāo)準(zhǔn)版的默認(rèn)StackMapTable屬性不同。例如,如果您正在處理midlet,則需要此選項(xiàng)。

一般 可選項(xiàng)

-verbose

指定在處理過(guò)程中寫(xiě)入更多信息。如果程序以異常終止,該選項(xiàng)將打印出整個(gè)堆棧跟蹤,而不僅僅是異常消息。

-dontnote [class_filter]

指定不打印有關(guān)配置中可能出現(xiàn)的錯(cuò)誤或遺漏的注釋,如類名中的拼寫(xiě)錯(cuò)誤,或可能有用的選項(xiàng)缺失??蛇x過(guò)濾器是一個(gè)正則表達(dá)式;ProGuard不打印具有匹配名稱的類的注釋。

-dontwarn [class_filter]

指定根本不警告未解析的引用和其他重要問(wèn)題。可選過(guò)濾器是一個(gè)正則表達(dá)式;ProGuard不會(huì)打印關(guān)于具有匹配名稱的類的警告。忽視警告是危險(xiǎn)的。例如,如果處理確實(shí)需要未解析的類或類成員,那么處理后的代碼將不能正常工作。只有當(dāng)你知道你在做什么時(shí)才使用這個(gè)選項(xiàng)!

-ignorewarnings

指定打印關(guān)于未解析引用和其他重要問(wèn)題的警告,但在任何情況下都要繼續(xù)處理。忽視警告是危險(xiǎn)的。例如,如果處理確實(shí)需要未解析的類或類成員,那么處理后的代碼將不能正常工作。只有當(dāng)你知道你在做什么時(shí)才使用這個(gè)選項(xiàng)!

-printconfiguration [filename]

指定用包含的文件和替換的變量寫(xiě)出已解析的整個(gè)配置。結(jié)構(gòu)被打印到標(biāo)準(zhǔn)輸出或給定文件中。有時(shí),這對(duì)于調(diào)試配置或?qū)ML配置轉(zhuǎn)換為更具可讀性的格式非常有用。

-dump [filename]

指定在任何處理之后寫(xiě)出類文件的內(nèi)部結(jié)構(gòu)。結(jié)構(gòu)被打印到標(biāo)準(zhǔn)輸出或給定文件中。例如,您可能想要寫(xiě)出給定jar文件的內(nèi)容,而根本不需要處理它。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容