简体   繁体   中英

Proguard with spring boot - integration tests

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); } 
  • preservation of Autowired, Qualifier, Bean, Value annotation members,
  • preservation of main method
  • keepattributes switch with Exceptions, InnerClasses, Signature, Deprecated, SourceFile, LineNumberTable, Annotation , EnclosingMethod
  • dontshrink, dontoptimize, useuniqueclassmembernames, adaptclassstrings, dontusemixedcaseclassnames options

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM