Maven编译Kotlin项目时无法引用注解生成Java类求助
问题
我有一个Kotlin项目,部分代码通过Annotation Processing(AbstractProcessor)生成,生成的是Java代码,输出路径为:
./target/generated-sources/annotations
当前Maven构建配置下,生成的Java代码可以正常访问项目中的Kotlin类,Java代码编译完全正常,但当Kotlin代码引用这些生成的Java类时,执行命令:
mvn clean package spring-boot:repackage -Pproduction -DskipTests=true
会出现编译错误:
[ERROR] Failed to execute goal org.jetbrains.kotlin:kotlin-maven-plugin:1.7.22:compile (compile) on project xxx: Compilation failure: Compilation failure: [ERROR] /path/to/project/src/main/kotlin/com/x/y/z/View.kt:[12,44] Unresolved reference: CRUD [ERROR] /path/to/project/src/main/kotlin/com/x/y/z/View.kt:[35,38] Unresolved reference: XxxCRUDController
当前使用的Maven构建配置如下:
<build> <finalName>xxx</finalName> <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory> <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory> <plugins> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <configuration> <args> <arg>-Xjsr305=strict</arg> </args> <compilerPlugins> <plugin>spring</plugin> </compilerPlugins> </configuration> <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-allopen</artifactId> <version>${kotlin.version}</version> </dependency> </dependencies> <executions> <execution> <id>compile</id> <goals> <goal>compile</goal> </goals> <configuration> <sourceDirs> <sourceDir>${project.basedir}/src/main/kotlin</sourceDir> <sourceDir>${project.build.directory}/generated-sources/annotations</sourceDir> </sourceDirs> </configuration> </execution> <execution> <id>test-compile</id> <goals> <goal>test-compile</goal> </goals> <configuration> <sourceDirs> <sourceDir>${project.basedir}/src/test/kotlin</sourceDir> <sourceDir>${project.build.directory}/generated-sources/annotations</sourceDir> </sourceDirs> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <executions> <!-- Replacing default-compile as it is treated specially by maven --> <execution> <id>default-compile</id> <phase>none</phase> </execution> <!-- Replacing default-testCompile as it is treated specially by maven --> <execution> <id>default-testCompile</id> <phase>none</phase> </execution> <execution> <id>java-compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- Take care of synchronizing java dependencies and imports in package.json and main.js files. It also creates webpack.config.js if not exists yet. --> <plugin> <groupId>com.vaadin</groupId> <artifactId>vaadin-maven-plugin</artifactId> <version>${vaadin.version}</version> <executions> <execution> <goals> <goal>prepare-frontend</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
解决方案
问题根源是编译顺序错误:Kotlin编译时,注解处理器生成的Java代码还未就绪,或者Kotlin编译器无法识别生成的代码目录。按照以下步骤修改配置即可解决:
1. 调整注解处理与编译顺序
让注解处理器在Kotlin编译前执行,确保生成代码提前就绪。修改maven-compiler-plugin配置:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>1.8</source> <!-- 根据项目使用的JDK版本调整 --> <target>1.8</target> <annotationProcessorPaths> <!-- 这里添加你的注解处理器依赖,例如: --> <!-- <path> <groupId>com.your.processor.group</groupId> <artifactId>your-processor-artifact</artifactId> <version>your-processor-version</version> </path> --> </annotationProcessorPaths> <generatedSourcesDirectory>${project.build.directory}/generated-sources/annotations</generatedSourcesDirectory> </configuration> <executions> <execution> <id>default-compile</id> <phase>process-sources</phase> <!-- 提前到process-sources阶段执行注解生成 --> <goals> <goal>compile</goal> </goals> <configuration> <skipMainCompile>true</skipMainCompile> <!-- 仅执行注解处理,不编译主Java源码 --> </configuration> </execution> <execution> <id>java-compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>default-testCompile</id> <phase>none</phase> </execution> </executions> </plugin>
2. 更新Kotlin插件配置,确保能访问生成代码
修改kotlin-maven-plugin,移除生成目录从sourceDirs(避免Kotlin尝试编译Java源码),转而将生成目录加入classpath,同时确保Kotlin编译在Java编译之后执行:
<plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <configuration> <args> <arg>-Xjsr305=strict</arg> </args> <compilerPlugins> <plugin>spring</plugin> </compilerPlugins> <!-- 将生成代码目录加入classpath,让Kotlin编译器能找到生成的类 --> <classpathElements> <classpathElement>${project.build.directory}/generated-sources/annotations</classpathElement> </classpathElements> </configuration> <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-allopen</artifactId> <version>${kotlin.version}</version> </dependency> </dependencies> <executions> <execution> <id>compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> <configuration> <sourceDirs> <sourceDir>${project.basedir}/src/main/kotlin</sourceDir> </sourceDirs> </configuration> </execution> <execution> <id>test-compile</id> <goals> <goal>test-compile</goal> </goals> <configuration> <sourceDirs> <sourceDir>${project.basedir}/src/test/kotlin</sourceDir> </sourceDirs> </configuration> </execution> </executions> </plugin>
3. 标记生成目录为Maven源码目录
添加build-helper-maven-plugin,让Maven整体识别生成的代码目录,避免IDE或其他插件无法识别:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>3.3.0</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>${project.build.directory}/generated-sources/annotations</source> </sources> </configuration> </execution> </executions> </plugin>
关键说明
- 注解处理器必须在Kotlin编译前完成代码生成,否则Kotlin编译器找不到生成的类
- 不要让Kotlin插件尝试编译生成的Java源码,而是通过classpath引用已编译的类
- 标记生成目录为源码目录,确保Maven生态中的所有工具都能识别这些代码
内容的提问来源于stack exchange,提问作者tagtraeumer
相关产品推荐
相关产品推荐

