yGuard requires JDK 1.7.x or greater and Ant 1.5 or greater installed on your system. It may work with earlier versions of these pieces of software as well, however this has not been tested thoroughly. yGuard 1.3.x and upwards works together with Ant 1.6.
Java 11 - Java 13 Compatibility
Beginning with version 2.10, yGuard supports obfuscation of Java class files that contain
nestmembers attributes which were introduced with the Java 11
.class file format. Further yGuard does support obfuscating
dynamic instructions which were introduced with the Java 11
.class file format.
Please read the notes regarding 3rd party JVM support if you intend to use yGuard with something other than Java.
Java 9 / Java 10 Compatibility
Beginning with version 2.7, yGuard supports obfuscation of Java class files that contain module information which was introduced with the Java 9
.class file format. yGuard does not change module names, though.
yGuard does not support obfuscating multi-release Java archives which were introduced with Java 9.
Java 7 / Java 8 Compatibility
Beginning with version 2.5, yGuard supports obfuscation of Java class files that contain the
invokedynamic instruction, which was introduced with the Java 7
.class file format. JDK 7 does not contain any means of issuing this instruction, with JDK 8 it is being issued when using lambda expressions or default methods.
While yGuard does fully support obfuscating
invokedynamic instructions and therefore default methods and lambda expressions, shrinking of Java class files that contain this instruction is not supported yet.
Compatibility to 3rd party JVM
invokedynamic instructions is a task that is theoretically infeasible. An obfuscation program cannot determine the type and parameters of such instructions in a generic way.
A trade-off solution for this is supporting known
MetaFactory objects by their signature.
JRE makes this task quite trivial.
yGuard supports the built-in
This trade-off however means
yGuard offers only limited support for instruction sets based on
In particular, supporting new
JVM targets, such as Scala, might require manual work.
As we currently do not have the expertise, nor do we have the resources for this project, this is a chore left for the community.
Below is a documentation on the design process involved in supporting the
LambdaMetafactory. It should serve as a base for anyone deciding to add more support for e.g Scala or Groovy.
LambdaMetafactory is covered
To check that JVM compatibility is ensured in new releases, we verified that there are no differences in the class file format in JVM >= 11.
This can be checked in the documentation of the class file format.
The JRE ships two targets for the
dynamic instruction sets. These are:
We can recognise these factories in the obfuscation and shrinking steps using their signature.
Looking at the documentation tells us that we should cover two signatures for
yFiles recognises these methods during renaming.
In order to obfuscate lambdas, these steps are performed:
- if an instance of
InvokeDynamicCpInfois found while parsing the constant pool, check its signature
- if it has a
LambdaMetafactorysignature handle the special case
LambdaMetafactoryTest example, this will remap
La/a/a/a/a$_a;. Most instances of lambda invocations will do a remapping on the JRE functional interface.
However, this process must be carefully tested with actual Java byte code. Even though
StringConcatFactory uses similar code, its semantics is completely different.
Implementing such a factory requires in-depth knowledge of the underlying mechanism. Even in the case of the
JDK it is not always perfectly clear which case will be mapped by the compiler to which construct.