Zelix KlassMaster - Documentation
 

The obfuscateExceptionsUnexclude Statement

The ZKM Script obfuscateExceptionsUnexclude statement acts only on the set of excluded methods and classes created by an obfuscateExceptionsExclude statement. The statement removes specified methods and classes from the set of excluded methods and classes so that they become available once more for exception obfuscation by the ZKM Script obfuscate statement.

The obfuscateExceptionsUnexclude statement is intended to be used in conjunction with a obfuscateExceptionsExclude statement to specify a final set of excluded methods and classes that would have been difficult to achieve using a obfuscateExceptionsExclude statement alone. Typically, in such cases, an initial obfuscateExceptionsExclude statement would set the broad exclusions and then the obfuscateExceptionsUnexclude statement would specify the exceptions to those broad exclusions.

Successive obfuscateExceptionsUnexclude statements have a cumulative effect. The effect of all exclusions and unexclusions that have been set is removed by a resetObfuscateExceptionsExclusions statement.

The remainder of this page is organized into the following sections.

Examples and Explanation

The syntax of the obfuscateExceptionsUnexclude statement is the same as that of the obfuscateExceptionsExclude statement.

obfuscateExceptionsUnexclude statement parameters may be loosely categorized into the following groups

Class unexclude parameters

Put informally (with mandatory components in bold), the syntax of a obfuscateExceptionsUnexclude class unexclude parameter is:
<classAnnotations> <classModifiers> "<archiveQualifier>"!<packageQualifiers>.<className> <containingClause> <extendsClause> <implementsClause>;

For a class and all of its methods to be unexcluded from exception obfuscation, all of the following must be true:
  • Its annotations must match any specified annotations.
  • Its modifiers (e.g. public final) must match all parameter modifiers. So if the parameters are public abstract !interface then the class must be public, abstract and NOT an interface to be excluded.
  • If the parameter has an archive qualifier then the class must be contained in an archive which matches that archive qualifier.
  • Its package qualifiers must match any specified package exclude parameter component. If there is no package exclude parameter component then the class must be in the default package.
  • Its unqualified name must match the specified class name specification.
  • If the parameter has a containing clause then the class must contain members which match the specified class
  • If the parameter has an extends clause then the class must be a subclass of the specified class
  • If the parameter has an implements clause then the class must directly or indirectly implement all of the specified interfaces
obfuscateExceptionsUnexclude 
         * and //unexclude all methods in all classes in default package
         *.Class1 and //unexclude all methods in all classes with the unqualified class name "Class1"
         //unexclude all methods in all classes that start with "Class" except for "Class0" and "Class1"
         *.(Class* && !(Class0 || Class1)) and
         //unexclude all classes annotated which an annotation matching *.MyAnnotation0
         @*.MyAnnotation0 *.*;  

Method unexclude parameters

Put informally (with mandatory components in bold), the syntax of a obfuscateExceptionsUnexclude method unexclude parameter is:
<classAnnotations> <classModifiers> "<archiveQualifier>"!<packageQualifiers>.<className> <extendsClause> <implementsClause>
    <methodAnnotations> <methodModifiers> <methodName>(<argumentTypes>) <throwsClause> +signatureClasses;

For a method to be unexcluded from exception obfuscation, all of the following must be true:
  • Its containing class must match any class unexclude parameter component.
  • Its annotations must match any specified method or method parameter level annotations.
  • Its modifiers (e.g. public native) must match all parameter method modifiers. So if the parameters are public static !synchronized then the method must be public, static and NOT synchronized to be excluded from obfuscation.
  • Its name must match the parameter method name specification. The special name <init> matches all constructors and the special name <clinit> matches all static initializers.
  • Its argument types (e.g. int[], java.lang.String) must match the parameter argument types if they exist. (A single parameter argument type of "*" matches any method argument types including no arguments.) If the parameter has no argument type then the method must take no arguments.
  • Its throws clause must contain all the classes specified in the obfuscateExceptionsExclude parameter's throw clause. So, if the obfuscateExceptionsExclude parameter's throws clause is throws java.io.IOException then the method must throw java.io.IOException or one of its subclasses to be excluded.
obfuscateExceptionsUnexclude 
         pack2.Class1 method1(int) and //Unexclude method1(int) in class pack2.Class1 from exception obfuscation
         *.* *(*) and //Unexclude all methods from exception obfuscation
         *.* <init>(*) and //Unexclude all contructors from exception obfuscation
         *.* <clinit>(*) and //Unexclude all static initializers from exception obfuscation
         *.* m*() and //Unexclude all methods taking no parameters with names matching "m*"
         *.* *(*) throws java.io.IOException and //Unexclude all methods that throw java.io.IOException.
         !(pack1*.)* (m* && !(ma* || me*))() and //Unexclude all methods in packages that don't start with "pack1"
                                                 //and that have names that start with "m" but not "ma" or "me"
         *.* abstract *(java.lang.String) and //Unexclude the names of all "abstract" methods that
                                              //take a single String.
         //Unexclude all the methods of any class implementing "Serializable" in a package that matches "pack1.*"
         pack1.* implements java.io.Serializable *(*) and 
         "MyJar*.jar"!*.* and //Unexclude all classes contained in a JAR file with a name matching "MyJar*.jar"
         //Unexclude all methods annotated with a class matching *.MyAnnotation0.
         *.* @*.MyAnnotation0 *(*);

Syntax

"obfuscateExceptionsUnexclude" unexcludeParameter ("and" unexcludeParameter)* ";"

annotationSpecifier ::= ("@" [packageUnexcludeParameter] nameSpecifier) | annotationSpecifierAndList

annotationSpecifierAndList ::= ["!"] "(" annotationSpecifierOrList ("&&" annotationSpecifierOrList)* ")"

annotationSpecifierOrList ::= annotationSpecifier ("||" annotationSpecifier)*

classUnexcludeParameter ::=
   [annotationSpecifier] [["!"] "public" | "package"]
   [["!"] "abstract"] [["!"] "final"] [["!"] "interface"] [["!"] "synthetic"] [["!"] "enum"] [["!"] "annotation"]
   ["\"" archiveQualifier "\"" "!"] [packageExcludeParameter ["."]] nameSpecifier [containingClause]
   [extendsClause] [implementsClause]

containingClause ::= "containing" "{" "memberAndList" "}"

unexcludeParameter ::= classUnexcludeParameter |
methodUnexcludeParameter

extendsClause ::= "extends" [annotationSpecifier] wildcardClassName

fullyQualifiedClassName ::= name ("." name)*

implementsClause ::= "implements" [annotationSpecifier] wildcardClassName ("," [annotationSpecifier] wildcardClassName)*

memberAndList ::= ["!"] "(" memberOrList ("&&" memberOrList)* ")"

memberOrList ::= memberSpecifier ("||" memberSpecifier)*

memberSpecifier ::= fieldExcludeParameter | methodExcludeParameter

nameAndList ::= ["!"] "(" nameOrList ("&&" nameOrList)* ")"

methodUnexcludeParameter ::=
   classUnexcludeParameter [annotationSpecifier] [["!"] "public" | "protected"| "package"| "private"]
   [["!"] "abstract"] [["!"] "static"] [["!"] "final"] [["!"] "native"] [["!"] "synchronized"] [["!"] "synthetic"] [["!"] "bridge"]
   (nameSpecifier | "<init>" | "<clinit>") "(" [ "*" | (parameter ("," parameter)*)] ")"
   ["throws" wildcardClassName]

name ::= (["0"-"9","a"-"z","A"-"Z","$","_"])+
   i.e. a Java identifer (e.g. a package, class, field or method name) with no wildcards allowed

nameAndList ::= ["!"] "(" nameOrList ("&&" nameOrList)* ")"

nameOrList ::= nameSpecifier ("||" nameSpecifier)*

nameSpecifier ::= wildcardName | nameAndList

packageUnexcludeParameter ::= packageName | packageNameAndList

packageName ::= wildcardName ("." wildcardName)* "."
   NB: the final "." is part of the package name

packageNameAndList ::= ["!"] "(" packageNameOrList ("&&" packageNameOrList)* ")"

packageNameOrList ::= packageUnexcludeParameter ("||" packageUnexcludeParameter)*

parameter ::= [annotationSpecifier] ("*" | "?" | type)

type ::=
   ("byte" | "short" | "char" | "int" | "long" | "float" | "double"| "boolean" |
   fullyQualifiedClassName) ("[]")*

wildcardName ::= (["*","0"-"9","a"-"z","A"-"Z","$","_"])+
   i.e. a Java identifer (e.g. a package, class, field or method name) with the "*" wildcard allowed
Where archiveQualifier is a relative or absolute archive path name with the "*" wildcard allowed. E.g. "/lib/*.jar" or "myJar0.jar"
ZKM Script obfuscateExceptionsExclude statement The ZKM Script Language ZKM Script resetObfuscateExceptionsExclusionsStatement statement
Zelix KlassMaster - Java Obfuscator