I'm using ProGuard for spring-boot app obfuscation. It's working fine, resulting jar is builded and is running well, without any issues.
To achieve that I used a few tweaks:
custom beanNameGenerator
public static void main(String[] args) { new SpringApplicationBuilder(MainApp.class) .beanNameGenerator((beanDefinition, beanDefinitionRegistry) -> beanDefinition.getBeanClassName()) .run(args); }
However, integration tests (@SpringBootTest) broke with error (they are running fine when builded without proguard):
java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test.
After include of main entry class (@SpringBootTest(classes=MainApp.class)) :
2019-09-11 19:00:13,178 [main] ERROR org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@6b04acb2] to prepare te
st instance [com.xxx.xxx.it.ExternalIT@258274cb]
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125) ~[spring-test-5.1.7.RELEASE.jar:5.1.7.RELEASE]
...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.xxx.xxx.a.a.b' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
And so on.
Is there any way to make it work, other than creating new profile for performing tests without obfuscating?
preservation of Autowired, Qualifier, Bean, Value annotation members,
You did the right thing here,you need to preserve all attribute
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod
however It's not the cause of your problem,Spring does the autowiring byType and in my experience post obfuscation such issue comes of not finding bean of type.
You need to tweak your code, use your annotation with name like
@Component("yourComponentName")
instead of
@Component
same with bean and Service and other annotation
and wherever you use then use @Qualifier("nameofbeanorService")
and since you preserved annotation attribute your application will work smooth.
Thanks
提取BeanNameGenerator以分离Bean并在@SpringBootApplication的@ComponentScan中注册它,而不是在主要方法中的SpringApplicationBuilder中内联它,这可以使事情正常进行。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.