Configuration
Configuration file
The structure of the JSON file that drives a run, with a complete example.
Every run reads one JSON file, passed with -config. It names the jars, the libraries, what to leave alone and which protections to apply. The file must be strict JSON: no comments and no trailing commas.
Structure
| Key | Type | Purpose |
|---|---|---|
input | string | The jar to protect. -input on the command line overrides it. |
output | string | The jar to write. -output on the command line overrides it. |
libraries | array of strings | Jars your code depends on, used to resolve the class hierarchy and compute stack frames. -libraries on the command line replaces the list. |
exclude | string | Exclusion rules, one per line, separated by \n. |
options | object | Every protection and runtime option, see Options. |
options is a nested object, and exclude is a single string, not an array. Options you leave out keep their default or the value set by the profile.
Complete example
This configuration starts from the High profile and sets most options explicitly. It is a reference, not a recommendation: start from a profile and add only what you need.
{
"input": "build/libs/app.jar",
"output": "build/libs/app-protected.jar",
"libraries": ["libs/foo.jar"],
"exclude": "flatten:com.example.render.**\nrename:com.example.Main**",
"options": {
"profile": "High",
"rename": "Invisible",
"lineNumbers": "Delete",
"localVariables": "Delete",
"methodParameters": "RemoveAttribute",
"removeSourceFile": true,
"shuffle": true,
"shuffleOptions": {
"classes": true,
"fields": true,
"methods": true,
"innerClasses": true,
"interfaces": true,
"classAttributes": true,
"classAnnotations": true,
"classTypeAnnotations": true,
"fieldAttributes": true,
"fieldAnnotations": true,
"fieldTypeAnnotations": true,
"methodAttributes": true,
"methodAnnotations": true,
"methodTypeAnnotations": true,
"methodExceptions": true,
"localVariables": true,
"localVariableAnnotations": true,
"methodParameters": false
},
"removeInnerClasses": true,
"controlFlowObfuscation": "Heavy",
"crasher": false,
"constantObfuscation": "Flow",
"watermarkOptions": {
"dummyClass": false,
"textInsideClass": false,
"ldcPop": false,
"zipComment": false,
"dummyClassText": "",
"textInsideClassText": "",
"ldcPopText": "",
"zipCommentText": ""
},
"antiTamper": false,
"controlFlowFlattening": true,
"flattenLoops": false,
"controlFlowShuffling": true,
"integrityCheck": false,
"referenceObfuscation": true,
"salt": true,
"renameDictionary": "",
"renamePackage": "com.example.protected",
"renameClassPrefix": "",
"renameClassSuffix": "",
"renameMemberPrefix": "",
"renameRandom": true,
"aggressiveOverload": false,
"polymorphMin": 2,
"polymorphMax": 4,
"constantFlowDensity": 0.25,
"stringEncryptMode": "Balanced",
"cryptoKeyBits": 128,
"gotoObfuscation": true,
"access": true,
"mappingOutput": "build/mapping.json",
"verbose": false,
"staticFieldInit": true,
"comparisonObfuscation": true,
"contextualStringKey": true,
"multiAlgoStrings": true,
"cffStateMasking": true,
"methodHandleIndirection": true,
"parameterPacking": true,
"fieldDescriptorMutation": true,
"annotationConfuser": true,
"blockBreak": true,
"trapEdge": true,
"integerTable": true,
"polyString": false,
"jntPolyString": false,
"fieldProxy": true,
"invokeDispatcher": true,
"methodSalt": true,
"polyStringSkipInterningUnsafe": false,
"numberSpeck": true,
"sensitiveVm": false,
"sensitiveVmMethods": [],
"magicCrypter": false,
"ghostMembers": true,
"ghostMembersIntense": true,
"maxOutputRatio": 2.0
}
} How the options combine
- The JSON is read.
- If
options.profileis set, the profile fills every option that the file does not set. - Every option written in the file keeps its value, even
false: an explicit"crasher": falsestays off under a profile that would turn it on.
The meaning of each option is in Options; the transformer behind each one is in the transformers reference.