【问题标题】:Simple @Configurable with modern spring-boot + gradle简单的 @Configurable 与现代 spring-boot + gradle
【发布时间】:2017-03-21 05:38:59
【问题描述】:

我的目标是获得一个基本的 aspectj+spring aop 设置,以便我可以在一个类上使用 @Configurable。另一个限制是它需要使用加载时编织,因为 Lombok 不适用于 CTW。

好消息:我成功了!

坏消息:控制台充斥着[Xlint:cantFindType] 错误。请参阅下面的结果部分。

环境

我有一个用@Configurable 注释的类。它是 Jackson 使用并实例化的类,因此需要 AOP。这不是很有趣,所以我不会在这里展示它。它只是一个普通的类,带有 Configurable 的单个注解,内部有一个 @Autowired bean。

SpringBootApplication

我的应用程序类有通常的注释:

@SpringBootApplication
@EnableSpringConfigured
@EnableLoadTimeWeaving
public class MyApplication {

build.gradle

我的 build.gradle 有所有常见的嫌疑犯。示例:

configurations {
    springinstrument
}

dependencies {
    compile('org.projectlombok:lombok')

    compile('org.springframework.boot:spring-boot-starter-aop')
    compile("org.springframework.boot:spring-boot-starter-data-rest")
    compile('org.springframework.data:spring-data-rest-hal-browser')
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-security')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.boot:spring-boot-devtools')
    compile('org.springframework.plugin:spring-plugin:1.2.0.RELEASE')
..snip..
    runtime('org.springframework:spring-instrument:4.+')
    springinstrument "org.springframework:spring-instrument:4.+"
    runtime configurations.springinstrument.dependencies
}

test.doFirst {
    jvmArgs "-javaagent:${configurations.springinstrument.asPath}"
}

jvm 参数

我正在使用以下参数运行 JUnit 测试(通过 Intellij 的运行配置)

-ea
-javaagent:/Users/me/.gradle/caches/modules-2/files-2.1/org.springframework/spring-instrument/4.3.3.RELEASE/5db399fa5546172b9c107817b4abaae6b379bb8c/spring-instrument-4.3.3.RELEASE.jar

aop.xml

我有一个src/main/resources/META-INF/aop.xml,其中包含:

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
        <weaver options="-Xreweavable -showWeaveInfo">
        <!-- only weave classes with @Configurable interface -->
        <include within="@org.springframework.beans.factory.annotation.Configurable */>
    </weaver>
</aspectj>

但是,我怀疑该文件没有被拾取。我在文件中放什么并不重要,结果总是一样的。即使我放了随机的无效 XML。

测试

junit 测试是一个简单的 Jackson 序列化-反序列化测试,使用 @Configurable 注释类。

测试类有注解:

@SpringBootTest
@RunWith(SpringRunner.class)

结果

通过 Intellij 运行 junit 测试时 -> 可以,但是..

LTW 实际工作,当通过 Intellij 使用上面的 jvm 参数运行时,我的测试通过了。

但是应用程序的启动时间明显更长并且日志中充斥着Xlint:cantFindType错误

例子:

2016-11-07 19:28:21.944  INFO 45213 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
[AppClassLoader@18b4aac2] error can't determine implemented interfaces of missing type org.springframework.security.ldap.authentication.LdapAuthenticationProvider
when weaving type org.springframework.security.config.annotation.authentication.configurers.ldap.LdapAuthenticationProviderConfigurer
when weaving classes 
when weaving 
 [Xlint:cantFindType]
[AppClassLoader@18b4aac2] error can't determine implemented interfaces of missing type io.undertow.server.handlers.accesslog.AccessLogHandler
when weaving type org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory
when weaving classes 
when weaving 
 [Xlint:cantFindType]
[AppClassLoader@18b4aac2] error can't determine implemented interfaces of missing type io.undertow.server.handlers.accesslog.AccessLogHandler
when weaving type org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory
when weaving classes 
when weaving 
 [Xlint:cantFindType]
[AppClassLoader@18b4aac2] error can't determine implemented interfaces of missing type io.undertow.server.handlers.accesslog.AccessLogHandler
when weaving type org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory
when weaving classes 
when weaving 
 [Xlint:cantFindType]
.. many more.. all in the org.springframework.boot package

通过 gradle 命令行运行测试时 -> 工作正常。

当我使用gradle test --tests *MyTestClass 运行测试时,由于出现 NullPointerException 导致测试失败。猜猜看,我希望自动注入 @Autowired bean。

我可以使用 gradle 测试配置,huzzah!我已经更新了上面的配置。但是.. 它遇到了与在我的 IDE 中运行它相同的问题:the Xlint:cantFindType


所以问题:

  1. gradle 配置错误,导致通过 gradle 运行应用失败。如何修复 gradle 配置?

  2. Xlint:cantFindType 错误。 aop.xml 没有被拾取吗? 如何解决?

我还没有找到使用 aop.xml 的简单 spring-boot+gradle+ @Configurable 示例

【问题讨论】:

  • 你试过用-javaagent:aspectjweaver.jar代替-javaagent:spring-instrument.jar吗?
  • 我确实做到了,我首先使用 aspectjweaver 让它工作,我遇到了同样的问题。我将它切换到可能解决它的弹簧仪器思维。

标签: spring gradle spring-boot spring-aop load-time-weaving


【解决方案1】:

问题我解决了,比较尴尬。

  1. 这是因为aop.xml 没有被接收。
  2. 未检测到该文件,因为它位于类路径上名为META_INF/ 的目录中,而不是META-INF/。这是一个非常重要的区别。

无论如何,我已经用最少的配置更新了这个问题,让@Configurable 使用现代的 spring-boot 和 gradle 设置以及加载时间编织以支持 Lombok。希望它对某人有用。

【讨论】:

  • 感谢您回答您自己的问题。超级有帮助。
  • 我也遇到了同样的问题,无法正常工作,你能把你的应用源码贴在某个地方吗?
  • 好的,我修复了它: 1. 我的 aop.xml 位于 jar 的根目录而不是 META-INF 2. 将 aspectjwaver 添加到 javaagents
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-05
  • 2019-02-15
  • 2015-05-15
  • 1970-01-01
  • 2014-08-13
  • 2016-05-22
相关资源
最近更新 更多