I'm having trouble obfuscating a java library with yGuard. A part of this library is supposed to be an implementation of a Service Provider Interface (SPI) and as such needs to be excluded from the obfuscation process. The non-obfuscated version of the application which uses this library works without problems. However after obfuscation process, it doesn't.

I suspect this to be due to an improperly set <shrink> element of yGuard's ANT task - it probably removes some methods since they are considered as unused. I made sure that the package and the classes are excluded within the renaming phase of obfuscation (<rename>) so that shouldn't be the cause of the problem.

I had hoped that I could avoid shrinkage of the SPI implementation by specifying the only method required to be implemented by the main interface I'm implementing as an entry point for the shrink engine, but have failed. This method then delegates to other interface implementations so I expected the entire thing to be walked around. See what I have below:

<shrink logfile="obfuscate_shrink_log.xml">
    <property name="error-checking" value="pedantic"/>
    <keep>
        <method name="void main(java.lang.String[])" class="package.path.to.main.Class"/>
        <method name="org.relaxng.datatype.DatatypeLibrary createDatatypeLibrary(java.lang.String)" class="package.path.to.my.implementation.of.DatatypeLibraryFactory"/>
        <class classes="public"/>
    </keep>
</shrink>

<rename mainclass="package.path.to.main.Class" logfile="obfuscate_rename_log.xml" replaceClassNameStrings="true">
    <property name="error-checking" value="pedantic"/>
    <keep>
        <class name="package.path.to.my.implementation.of.DatatypeLibraryFactory"/>
        <class name="package.path.to.my.implementation.of.DatatypeLibrary"/>
        <class name="package.path.to.my.implementation.of.Datatype"/>
    </keep>
</rename>

I'm implementing a set of org.relaxng.datatype interfaces. They can be invoked through SPI with Jing.

How can I specify an entire package to be excluded from the obfuscation process (both rename and shrink) with yGuard?

有帮助吗?

解决方案

After carefully reading yGuard's documentation I realized what I did wrong (well not wrong, what I was missing). If you do what I did in the question it will cause the shrink engine to keep the methods you specify, but it will not keep the constructor of the class which will then cause SPI to fail to instantiate your implementation.

The following needs to be done:

<shrink logfile="obfuscate_shrink_log.xml">
    <property name="error-checking" value="pedantic"/>
    <keep>
        <method name="void main(java.lang.String[])" class="package.path.to.main.Class"/>
        <class name="package.path.to.my.implementation.of.DatatypeLibraryFactory" methods="public"/>
        <class classes="public"/>
    </keep>
</shrink>

<rename mainclass="package.path.to.main.Class" logfile="obfuscate_rename_log.xml" replaceClassNameStrings="true">
    <property name="error-checking" value="pedantic"/>
    <keep>
        <class name="package.path.to.my.implementation.of.DatatypeLibraryFactory"/>
    </keep>
</rename>

This will leave the public API of a specific class out of obfuscation shrinking and renaming. You only need to leave out the part which enables your service provider implementation to be instantiated.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top