我正在使用 ProGuard 进行 spring-boot 应用程序混淆。它工作正常,生成的 jar 已构建并且运行良好,没有任何问题。

为了实现这一目标,我进行了一些调整:

  • 自定义 beanNameGenerator

        public static void main(String[] args) { 
            new SpringApplicationBuilder(MainApp.class) 
              .beanNameGenerator((beanDefinition, beanDefinitionRegistry) -> beanDefinition.getBeanClassName()) 
              .run(args); 
         } 
    
  • 保留 Autowired、限定符、Bean、值注释成员,
  • 保留主要方法
  • keepattributes 与 Exceptions、InnerClasses、Signature、Deprecated、SourceFile、LineNumberTable、Annotation、EnclosureMethod 切换
  • dontshrink、dontoptimize、useuniqueclassmembernames、adaptclassstrings、dontusemixedcaseclassnames 选项

但是,集成测试(@SpringBootTest)因错误而中断(在没有 proguard 的情况下构建时它们运行良好):

java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test. 

包含主入口类(@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: {} 

等等。

除了创建新的配置文件来执行测试而不进行混淆之外,还有什么方法可以使其工作吗?

请您参考如下方法:

preservation of Autowired, Qualifier, Bean, Value annotation members,

你在这里做了正确的事情,你需要保留所有属性

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod 

但是这不是问题的原因,Spring 会按类型进行 Autowiring ,根据我的经验,混淆后此类问题是由于找不到类型的 bean 造成的。

您需要调整您的代码,使用名称类似于的注释

@Component("yourComponentName")

而不是

@Component

与bean和Service以及其他注释相同

无论你在哪里使用,都可以使用@Qualifier("nameofbeanorService")

由于您保留了注释属性,您的应用程序将顺利运行。

谢谢


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!