Spring源码构建环境搭建

在使用Spring源码Debug的过程中,遇到了一些问题,如下:

问题1. cannot find symbol CoroutinesUtils

1
2
3
4
5
6
Error:(347, 51) java: cannot find symbol
symbol: variable CoroutinesUtils
location: class org.springframework.core.ReactiveAdapterRegistry.CoroutinesRegistrar
Error:(348, 51) java: cannot find symbol
symbol: variable CoroutinesUtils
location: class org.springframework.core.ReactiveAdapterRegistry.CoroutinesRegistrar

问题2. 找不到符号符号: 类 AnnotationTransactionAspect位置: 类 org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration

问题3. Unexpected AOP exception; nested exception is java.lang.IllegalStateException: Unable to load cache item

1
2
3
4
5
6
7
8
9
10
Caused by: org.springframework.aop.framework.AopConfigException: Unexpected AOP exception; nested exception is java.lang.IllegalStateException: Unable to load cache item
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:214)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:488)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:367)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:310)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:431)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1861)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:608)
... 10 more

通过报错信息可以猜测到这些问题应该是和动态代理有关系。查阅相关资料,发现spring原来写了一份源码构建文档import-into-idea如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
The following has been tested against IntelliJ IDEA 2016.2.2

## Steps

_Within your locally cloned spring-framework working directory:_

1. Precompile `spring-oxm` with `./gradlew :spring-oxm:compileTestJava`
2. Import into IntelliJ (File -> New -> Project from Existing Sources -> Navigate to directory -> Select build.gradle)
3. When prompted exclude the `spring-aspects` module (or after the import via File-> Project Structure -> Modules)
4. Code away

## Known issues

1. `spring-core` and `spring-oxm` should be pre-compiled due to repackaged dependencies.
See `*RepackJar` tasks in the build and https://youtrack.jetbrains.com/issue/IDEA-160605).
2. `spring-aspects` does not compile due to references to aspect types unknown to
IntelliJ IDEA. See https://youtrack.jetbrains.com/issue/IDEA-64446 for details. In the meantime, the
'spring-aspects' can be excluded from the project to avoid compilation errors.
3. While JUnit tests pass from the command line with Gradle, some may fail when run from
IntelliJ IDEA. Resolving this is a work in progress. If attempting to run all JUnit tests from within
IntelliJ IDEA, you will likely need to set the following VM options to avoid out of memory errors:
-XX:MaxPermSize=2048m -Xmx2048m -XX:MaxHeapSize=2048m
4. If you invoke "Rebuild Project" in the IDE, you'll have to generate some test
resources of the `spring-oxm` module again (`./gradlew :spring-oxm:compileTestJava`)


## Tips

In any case, please do not check in your own generated .iml, .ipr, or .iws files.
You'll notice these files are already intentionally in .gitignore. The same policy goes for eclipse metadata.

## FAQ

Q. What about IntelliJ IDEA's own [Gradle support](https://confluence.jetbrains.net/display/IDEADEV/Gradle+integration)?

A. Keep an eye on https://youtrack.jetbrains.com/issue/IDEA-53476

Spring5源码的编译环境

  1. JDK >= 1.8
  2. Gradle环境
  3. Eclipse/IDEA

Spring源码下载后推荐不直接导入IDE,大型的开源项目都是借助于自动糊构建工具实现编译打包,编译的过程中容易出现依赖问题。

源码编译

  1. 进入spring-framework目录,执行./gradlew :spring-oxm:compileTestJava 先对Spring-oxm模块进行预编译;

  2. 还是进入spring-framework目录,执行./gradlew build -x test编译整个源码。后面的-x test是编译期间忽略测试用例,因为编译过程中可能会出现编译不通过问题。最好跳过一些task任务如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    buildscript {
    //skip Test tasks
    gradle.taskGraph.whenReady {
    tasks.each { task ->
    if (task.name.contains("checkstyleTest") || task.name.contains("spring-test"))
    {
    task.enabled = false
    }
    }
    }
    }
  3. 源码导入到IDEA,用gradle导入,由于涉及到aop功能,序号1和序号2只能选取其中一个

    3.1. (可选)排除 spring-aspects项目,idea工具的ajc编译bug(http://youtrack.jetbrains.com/issue/IDEA-64446);选中 spring-aspects 项目 右键,选择“Load/Unload Moudules” 在弹出的窗体中进行设置.

    3.2. (可选)由于idea默认是不支持acj编译的,不能直接使用aspectj功能,报错内容Error:(42, 16) java: 找不到符号符号: 类 AnnotationTransactionAspect等

    1. 将idea的编译器设置为ajc

      打开:IDEA–Preferences–Build,Execution,Deployment–Compiler–JavaCompiler,将Use compiler设置为Ajc,将Path to Ajc compiler设置为AspectJ安装目录下的lib文件夹中的aspectjtools.jar文件,同时,可以勾选Delegate to Javac选项,它能够只编译AspectJ的Facets项目,而其他普通项目还是交由Javac来编译。

    2. 安装aspetj,下载地址:https://www.eclipse.org/aspectj/downloads.php

    3. idea 安装aspctj插件Aspectj Support和Spring AOP/@Aspectj

    4. 将spring-aop_main和spring_aspectjs_main模块添加aspectj facets

      打开:File–Project Structure–Facets,点击+号,选择AspectJ,选择spring-aop_main。添加完后,同样的操作,将spring-aspectjs_main模块也设置AspectJ。

      1. cglib和objenesis需要重新打包,用gradle下的task任务打包

    3.4.添加kotlin编译,用于解决spring-core包下kt文件编译

注意事项

问题3没有找到根本原因,应该是cglib包的问题。由于一开始spring版本我下载的是5.1.9-SNAPSHOT分支的代码,最后我合并了最终的5.2.10-RELEASE分支代码,错误就没出现了,怀疑是开发版本问题。