java - Proguard 与 Spring Boot - 集成测试

标签 java spring-boot proguard

我正在使用 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")

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

谢谢

关于java - Proguard 与 Spring Boot - 集成测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57893839/

相关文章:

java - 使用 Proguard (Spring) 混淆后如何避免反射错误

android - 发布版本改造 api 中的 minifyEnabled true 和 shrinkResources true 不起作用

java - 根据唯一值将列表拆分为子列表

java - JSP 在 Spring Boot 2 中不渲染 java 列表

java - 从表中检索不同类型并使用 myBatis 进行映射

java - LdapTemplate 搜索捕获并行流和 LdapTemplate 异常

带有 proguard 的 Android ant build.xml 不在发布中构建

java - 将 Maven Artifact 版本配置为 Spring 属性

java - 如何将图像添加到 JFrame 标题栏?

java - 如何更新 Alfresco 中的文件内容?