Obfuscated Spring Boot Web jar cannot be run
Hi, I'm testing yGuard trying to add obfuscation to a rather oldish Spring Boot Web 2.x JAR project. I've started off the processing example. While the packaging goes OK, the generated JAR bombs out on start with this (abridged) error message:
ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinition StoreException: Failed to parse configuration class [{mainclass}]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'd' for bean class [{packagepath}.U.d] conflicts with existing, non-compatible bean definition of same name and class [{packagepath}.C.d]
I tried to exclude the offending class something like that:
[...]
<rename>
<keep>
<class name="{offending class}"/>
</keep>
[...]
but that's not enough to solve the issue, that keeps repeating with a different class. I also tried enabling name scrambling (as in scramble = true) , but this has only the (foreseable) effect to change the offending class at random, so there must be something I am doing wrong. Could you please help me? Thanks
If Spring Boot uses the simple name of classes as identifiers for its beans, you will have to exclude all bean class names from obfuscation. yGuard does not offer a naming scheme that produces simple class names that are unique for the whole application. Alternatively, you could manually specify mappings with unique simple class names for all bean classes.
Hi, excluding bean classes from obfuscation is not a viable option in this case. I've now scripted something out to aid in <map> row autogeneration and the projects starts OK.
One more question: "Automatic introspection and reflection will break in most cases, [...]" I understand this includes Spring Boot autowiring. It seems that if you supply a @Qualifier and bean names to some offending beans, startup then goes OK. Should I look for other pitfalls? Thanks
The problem with Spring Boot is mostly that Spring Boot calls classes at runtime that it doesn't strictly require at compile time. Thus, yGuard does not resolve these symbols (such as the beans), and thinks it's okay to rename them. It is possible to determine these cases and map them to the output of yGuard, allowing you to fully obfuscate your application. However, there is no automated support, so this is quite cumbersome. Since this is a recurring issue in this repository, it would definitely be cool to have your working example added to the example section. If you don't mind, can you create a working example and add it here?
The problem with Spring Boot is mostly that Spring Boot calls classes at runtime that it doesn't strictly require at compile time. Thus, yGuard does not resolve these symbols (such as the beans), and thinks it's okay to rename them. It is possible to determine these cases and map them to the output of yGuard, allowing you to fully obfuscate your application. However, there is no automated support, so this is quite cumbersome. Since this is a recurring issue in this repository, it would definitely be cool to have your working example added to the example section. If you don't mind, can you create a working example and add it here?
I'll see to do that; maybe the Python mapping script I prepared can also be helpful. I met a showstopper though: the project I am experimenting with depends on Quartz, and it seems that the obfuscation process somehow breaks an otherwise perfectly working JobDataMap. This is strange and I will probably need to give up on obfuscation altogether if I don't manage to solve the problem.