The fixedClasses Statement
The ZKM Script fixedClasses statement ensures that specified classes are effectively insulated from the major effects of any subsequent
Zelix KlassMaster trim or obfuscate statements.
The effect is that a "fixed" class produced by Zelix KlassMaster
can be replaced with the original class file without effecting the obfuscated application. This effect is useful in scenarios where particular classes
may be recompiled automatically at runtime replacing the class produced by Zelix KlassMaster. This can happen with JSP servlets.
Note that the specified classes may still be changed slightly. For example some debugging information can be removed.
More significantly, inner class and generics information can still be removed. This information is generally only used by
compilers and debuggers so this would typically not be a problem. However, you can prevent the removal of inner class and generics information
from effecting your fixed classes by specifying "keepInnerClassInfo=ifNameNotObfuscated" and "keepGenericsInfo=true" on your
obfuscate statement.
Also, the fixedClasses statement has no effect of the operation of the removeMethodCalls statement.
However, if the ZKM_FIXED_TOTALLY_UNCHANGED configuration option is specified then the specified classes will be copied across
completely unchanged.
For each class matched by the statement, Zelix KlassMaster will
Successive fixedClasses statements (in the same script) have a cumulative effect. Once a fixed class
has been specified the only way to remove the specification is with a resetFixedClasses
statement.
The remainder of this page is organized into the following sections.
Put informally (with mandatory components in bold), the syntax for a class exclusion parameter is:
<classAnnotations> <classModifiers> "<archiveQualifier>"!<packageQualifiers>.<className> <containingClause> <extendsClause> <implementsClause>;
For a class to be treated as a fixed class, 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 parameter's class name specifier.
- 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
fixedClasses pack2.Class1 and //Treat class pack2.Class1 as a fixed class
pack3.* and //Treat all classes in package "pack3" as fixed classes
//Treat all classes contained in a JAR file with a name matching "MyJar*.jar" as fixed classes
"MyJar*.jar"!*.* and
//Treat all classes annotated which an annotation matching *.MyAnnotation0 as fixed classes
@*.MyAnnotation0 *.*;
"fixedClasses" classExcludeParameter ("and" classExcludeParameter )* ";"
annotationSpecifier ::= ("@" [packageExcludeParameter] nameSpecifier) | annotationSpecifierAndList
annotationSpecifierAndList ::= ["!"] "(" annotationSpecifierOrList ("&&" annotationSpecifierOrList)* ")"
annotationSpecifierOrList ::= annotationSpecifier ("||" annotationSpecifier)*
classExcludeParameter ::=
[annotationSpecifier] [["!"] "public" | "package"]
[["!"] "abstract"] [["!"] "final"] [["!"] "interface"] [["!"] "synthetic"] [["!"] "enum"] [["!"] "annotation"]
["\"" archiveQualifier "\"" "!"] [packageExcludeParameter ["."]] nameSpecifier [containingClause]
[extendsClause] [implementsClause]
containingClause ::= "containing" "{" "memberAndList" "}"
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)* ")"
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
packageExcludeParameter ::= packageName | packageNameAndList
packageName ::= wildcardName ("." wildcardName)* "."
NB: the final "." is part of the package name
packageNameAndList ::= ["!"] "(" packageNameOrList ("&&" packageNameOrList)* ")"
packageNameOrList ::= packageExcludeParameter ("||" packageExcludeParameter)*
wildcardClassName ::= wildcardName ("." wildcardName)*
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
|