I am looking to obfuscate our Java web app code within our existing Ant build script, but am running into problems around unit testing. I am obfuscating the code right after it has been compiled, before it is jar-ed and before the unit tests are ran.
However, if I obfuscate my production code and not my test code, all my tests fail because they are trying to call methods that no longer exist because they have been renamed by the obfuscator. I can mark certain methods to not obfuscate so they can be used by external systems such as our test suite, but since we are shooting for high unit test coverage we will need to mark all of our methods as un-obfuscatable.
If I obfuscate the test classes as well, I run into two problems:
1: The production classes and the test classes get merged into the same output directory and I am unable to exclude the test classes from the production .jar files
2: I cannot run my normal Ant batchtest call:
<batchtest todir="${basedir}/reports">
<fileset dir="${basedir}/components/common/build-zkm">
<include name="**/*Test.class"/>
</fileset>
</batchtest>
because the obfuscator has changed the names of the tests.
I could just run the obfuscator on the resulting .war/.ear files, but I want to have our unit tests run against the modified code to drive out any bugs caused by the obfuscator.
I am currently working with Zelix KlassMaster, but I am still in the evaluation phase so I would be open to other options if they would work better.
I use yguard (it is free, which is why I mention it).
You should be able to tell the obfuscator not to obfuscate certain things (looking here it seems you can).
Some as others have said, don't obfuscate the tests, but do obfuscate the rest.
However, I would suggest that you do the following:
It will be slower, but if the tests fail in step 3 it'll be easier to fix (potentially) and if the tests fail at 5 then you know there is an issue with the obfuscation not your source code.
Can you tell it to run the obfuscator such that it effectively refactors the code including the references from the tests (i.e. when a production name changes, the test code changes its reference) but not to obfuscate the tests themselves (i.e. don't change the names of the test classes or their methods)? Given previous experience with obfuscators I'd expect that to work.
So for example, suppose we had unobfuscated source of:
public class ProductionCode
{
public void productionMethod() {}
}
public class ProductionCodeTest
{
public void testProductionMethod()
{
new ProductionCode().productionMethod();
}
}
You want to set the options of the obfuscator to make it effectively:
public class Xyzzy
{
public void ababa() {}
}
public class ProductionCodeTest
{
public void testProductionMethod()
{
new Xyzzy(). ababa();
}
}
That way your "run the tests" Ant tasks should be able to stay the same, because the API of the tests hasn't changed - merely the implementation of the methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With