Zelix KlassMaster - Documentation
 

The open Statement

The ZKM Script open statement opens class files and Java ME JAD files for processing by Zelix KlassMaster. Successive open statements do not have a cumulative effect. It is highly recommended that you open your classes for obfuscation using the same relative directory and/or archive structure that will be used at runtime. If you do this then your obfuscated application can be deployed in exactly the same way as the original, unobfuscated application.

Skip and Unskip

If you open an archive that contains nested JAR, ZIP, WAR or RAR archives then the nested archives will also be opened for obfuscation. This typically happens in the case of JEE EAR or WAR archives. Occassionally this can cause a problem where your EAR contains a nested third party JAR that you don't want to obfuscate. In such cases you can use the -"x.ear!y.war!WEB-INF/lib/z.jar" syntax to tell Zelix KlassMaster™ to not open (i.e. "skip") a specified nested archive file. Note that although "skipped" classes will not be opened for obfuscation they will still be saved to the specified output archive along with the obfuscated classes. They will also be appended to the effective classpath.

You can also use the -"x.jar!com/mycompany/MyClass.class" syntax to tell Zelix KlassMaster™ to not open (i.e. "skip") a specified class or XML file within an archive. You can use the -"com/mycompany/MyClass.class" syntax to tell Zelix KlassMaster™ to not open (i.e. "skip") a specified class or XML file from the file system (i.e. not from within an archive). However, if you "skip" any classes then you must make sure that those classes does not access any of the classes that are to be obfuscated.

If you have specified a broad "skip" clause then you can use a narrower "unskip" to reduce the scope of that "skip" clause. The syntax is +"x.jar!com/mycompany/MyClass.class" The "unskip" must be at the same archive level as the "skip" that it narrows.

Any non-class files contained in opened archive files will be copied across to the corresponding saved archive files. Some of these files may be updated to reflect obfuscated names. See the File | SaveAll documentation for more detail.

File Filtering

You can tell Zelix KlassMaster™ to totally ignore certain files by specifying a file filter. Note that this is fundamentally different from the "skip" and "unskip" syntax that is mentioned above. File filters can specify class or non-class files and filtered files will not be copied to the save destination. Also filtered classes will not be appended to the effective classpath. Note that file filter specifications will be processed before any "skip" clauses.

A file filter specification must immediately follow the open clause (i.e path specification) to which is is to apply. A file in the associated open clause will be processed only if it matches the full file filter specification. A file filter specification can be simple like {"*class"} which means that only class files should be processed. It can be negative like {!"MANIFEST.MF"} which means don't match any manifest file. Finally, it can be complex like {"*.class" && !"Class0.class" || "*.xml" && !"Junk.xml"} which means match and process all class and XML files but not Class0.class or Junk.xml. Note that the && operator takes precedence over the || operator.

Examples

open "C:\directory1\Class1.class" //a single class file
     "C:\directory1\MyJar.jar"    //all the class files in a single jar
     "C:\directory2"              //all the class files in a single directory
     "C:\directory3\*"   //all the class files in a single directory AND its subdirectories
     "C:\directory1\MyJar.jad" //Java ME JAD file will be associated with the JAR it specifies
     "C:\directory4\*.jar" //all the JAR files in directory4
     "C:\directory5\Config.xml" //XML file Config.xml
     "C:\directory6\*.xml" //all the XML files in directory
     ;
	 
open "C:\directory1\MyEar.ear"     //Open the EAR and all its nested WAR and JAR files
     //Don't open the archive X.jar (in the WEB-INF/lib/ directory) nested within MyWar.war nested within MyEar.ear
     -"MyEar.ear!MyWar.war!WEB-INF/lib/X.jar"
     //Don't open ANY zip file archive (in the WEB-INF/lib/ directory) nested within MyWar.war nested within MyEar.ear
     -"MyEar.ear!MyWar.war!WEB-INF/lib/*.zip"
     //Unskip (i.e. open) special.zip (in the WEB-INF/lib/ directory) nested within MyWar.war nested within MyEar.ear
     +"MyEar.ear!MyWar.war!WEB-INF/lib/special.zip"
     //Don't open any class file within the package com/mycompany within MyJar.jar nested within MyEar.ear
     -"MyEar.ear!MyJar.jar!com/mycompany/*.class"
     //Unskip (i.e. open) the class file com/mycompany/MyClass.class within MyJar.jar nested within MyEar.ear
     +"MyEar.ear!MyJar.jar!com/mycompany/MyClass.class"
     ; 
	 
open "C:\directory1\com\mycompany\*.class"  //Open all classes in C:\directory1\com\mycompany
     "C:\directory1\com\mycompany\*.xml"    //Open all xml files in C:\directory1\com\mycompany
     -"C:\directory1\com\mycompany\X.class" //Don't open the class X.class
     -"C:\directory1\com\mycompany\Y.xml"   //Don't open the XML file Y.xml
     ; 
	 
//File filter examples
open "MyJar0.jar" {"*.class"} //match all class files
     "MyJar1.jar" {!"MANIFEST.MF"} //match all files except for the manifest
     //match all class files except Class0 and match all XML files. "&&" takes precedence.
     "MyJar2.jar" {!"*.class" && !"Class0.class" || "*.xml"} 
     ;

Explanation

The statement's action for each of the sourceName types is
Type Action
class file Open the specified class file
ZIP file Open all class files stored in the ZIP file
JAR file Open all class files stored in the JAR file
EAR file Open all class files stored in the nested WAR, JAR or RAR files
directory Open all class files stored in the directory
directory followed by an "*" Open all class files stored in the directory and all of its subdirectories
Java ME JAD file Open the JAD file and associate it with the opened JAR that it specifies
XML file Open the XML file from the file system. Note that any XML file within an opened archive will be automatically opened.

Syntax

"open" ("\"" sourceName "\"" [fileFilter])+
       ("-" "\"" skipName "\"") | ("+" "\"" unSkipName "\""))*
       ";"

fileFilter ::= simpleFileFilter | fileFilterOrList

simpleFileFilter ::= ["!"] "{" "\"" filterString "\"" "}"

fileFilterOrList ::= fileFilterAndList ("||" fileFilterAndList)*

fileFilterAndList ::= simpleFileFilter ("&&" simpleFileFilter)*

where
  • sourceName is the fully qualified pathname of a:
    • class file or
    • JAR file or
    • EAR file or
    • WAR file or
    • RAR file or
    • ZIP file or
    • directory or
    • directory followed by an "*" or
    • Java ME JAD file or
    • XML file.
    Note that a sourceName can contain "*" wildcards in the non-suffix part of an archive, class or XML file name.
  • skipName is the path to a nested archive, class file or XML file that should NOT be opened. The levels of nesting must be separated by "!" characters. Note that a skipName can contain "*" wildcards in the final file name which may be an archive name. For example:
    • x.ear!y.war!WEB-INF/lib/myJar.jar OR
    • x.ear!y.war!WEB-INF/lib/*.jar OR
    • x.jar!com/mycompany/*.class OR
    • C:\directory1\com\mycompany\*.class
    Also, the skipName can contain "*" wildcards in the path that qualifies the final file name.
    • x.ear!y.war!WEB-INF/*/myJar.jar OR
    • x.ear!y.war!WEB-INF/*/myXml.xml OR
    • x.jar!com/mycompany/*/myClass.class
    • C:\directory1\com\mycompany\*.class
  • unSkipName is the path to a nested archive, class file or XML file that should be removed from a corresponding broader "skip" exclusion and therefore SHOULD be opened. The levels of nesting must be separated by "!" characters. As in the case of a skipName, the unSkipName can contain "*" wildcards in the final file name which may be an archive name or in the path that qualifies the final file name. If there is no corresponding broader skipName ("skip" exclusion) then the unSkipName ("unskip" exclusion) will have no effect.
  • filterString is a file name or the final part of a file path. It may contain the "*" wildcard.
    • *.class OR
    • MANIFEST.MF OR
    • myDirectory/*.xml
 
ZKM Script resetIgnoreMissingReferences statement The ZKM Script Language ZKM Script trimExclude statement