在Eclipse插件项目中用Java生成源码的项目布局方案咨询
问题描述
在eclipse-test-plugin构建过程中,需要用Java生成测试代码(测试数据、桩代码),并将生成器与生成的代码一同打包到插件中,供其他eclipse-test-plugin调用。生成器可能依赖当前模块已引入的其他Eclipse插件中的生成器。
要求满足:
- 支持在Maven reactor中编译多个此类模块;
- 项目可在Eclipse IDE中正常编译;
- 避免重复声明依赖;
- 尽量保持单模块结构(不希望拆分为生产模块+生成器模块+测试模块)。
尝试过将生成器视为生产代码、依赖它的代码视为测试代码,单模块可行但跨模块依赖时,Tycho无法找到依赖模块的测试类;调整build.properties包含test-classes目录后编译失败。
解决方案
一、项目布局(单模块)
保持eclipse-test-plugin的单模块结构,按功能划分源码目录:
src/main/java:存放生成器核心代码(作为插件的生产API,供其他插件调用)src/main/generated:存放生成的测试代码(测试数据、桩代码,同样作为生产API对外暴露)src/test/java:存放仅当前模块使用的内部测试代码(不对外暴露)
二、关键配置调整
1. build.properties(适配Eclipse IDE和Tycho编译)
将所有源码目录和输出目录配置到位,确保Eclipse能识别并编译:
# 源码目录:生产生成器、生成代码、内部测试代码 source.. = src/main/java/,\ src/main/generated/,\ src/test/java/ # 输出目录:生产类、测试类分开 output.. = target/classes/,\ target/test-classes/ # 打包包含的内容:生产类、需要对外的测试类、元数据 bin.includes = META-INF/,\ .,\ target/classes/,\ target/test-classes/com/example/generated/**,\ target/test-classes/com/example/generator/**
注:
bin.includes中可按需筛选需要对外暴露的测试类,避免打包冗余代码。
2. MANIFEST.MF(声明依赖与导出API)
正确声明依赖,并将生成器、生成代码的包导出,供其他插件调用:
Bundle-SymbolicName: com.example.tests.generator Bundle-Version: 1.0.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-17 <!-- 按需调整JDK版本 --> # 依赖的其他Eclipse插件(包括生成器依赖的插件) Require-Bundle: org.eclipse.core.runtime, com.thirdparty.plugin.generator;bundle-version="2.0.0" # 导出供其他插件调用的包 Export-Package: com.example.generator, com.example.generated.testdata, com.example.generated.stubs
3. Maven POM配置(处理生成器编译与代码生成)
解决Java生成器需要先编译再运行的问题,同时确保Tycho正确打包所有内容:
<build> <plugins> <!-- 分阶段编译:先编译生成器,再生成代码,最后编译所有代码 --> <plugin> <groupId>org.eclipse.tycho</groupId> <artifactId>tycho-compiler-plugin</artifactId> <version>${version.tycho}</version> <executions> <!-- 提前编译生成器代码 --> <execution> <id>compile-generator</id> <phase>process-sources</phase> <goals> <goal>compile</goal> </goals> <configuration> <sourceDirectories> <sourceDirectory>src/main/java/com/example/generator</sourceDirectory> </sourceDirectories> <outputDirectory>${project.build.directory}/generator-classes</outputDirectory> </configuration> </execution> <!-- 编译所有生产代码(包括生成的代码) --> <execution> <id>compile-main</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> <configuration> <additionalSourceDirectories> <additionalSourceDirectory>${project.build.directory}/generated-sources/java</additionalSourceDirectory> </additionalSourceDirectories> </configuration> </execution> </executions> </plugin> <!-- 运行生成器生成测试代码 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>run-test-code-generator</id> <phase>generate-sources</phase> <goals> <goal>java</goal> </goals> <configuration> <mainClass>com.example.generator.TestCodeGenerator</mainClass> <classpath> <element> <directory>${project.build.directory}/generator-classes</directory> </element> <!-- 添加生成器依赖的其他类路径 --> <element> <dependency>org.eclipse.core.runtime</dependency> </element> </classpath> <!-- 传递生成代码输出目录参数 --> <arguments> <argument>${project.build.directory}/generated-sources/java</argument> </arguments> </configuration> </execution> </executions> </plugin> <!-- 打包插件,确保所有需要的类被包含 --> <plugin> <groupId>org.eclipse.tycho</groupId> <artifactId>tycho-packaging-plugin</artifactId> <version>${version.tycho}</version> <configuration> <archive> <manifestFile>META-INF/MANIFEST.MF</manifestFile> </archive> </configuration> </plugin> <!-- 源码打包,包含所有源码(生成器、生成代码、测试代码) --> <plugin> <groupId>org.eclipse.tycho</groupId> <artifactId>tycho-source-plugin</artifactId> <version>${version.tycho}</version> <executions> <execution> <id>package-sources</id> <goals> <goal>plugin-source</goal> </goals> <configuration> <additionalFileSets> <fileSet> <directory>${project.basedir}/src/main/generated</directory> <includes> <include>**/*</include> </includes> </fileSet> <fileSet> <directory>${project.basedir}/src/test/java</directory> <includes> <include>**/*</include> </includes> </fileSet> </additionalFileSets> </configuration> </execution> </executions> </plugin> </plugins> </build>
三、优势说明
- 保持单模块逻辑:生成器与测试代码同属一个模块,无需拆分,符合业务逻辑;
- 无依赖重复声明:所有依赖仅在
MANIFEST.MF中声明,Tycho自动同步到Maven依赖; - 跨模块依赖正常:生成器与生成代码作为生产API导出,其他模块通过
Require-Bundle即可访问,Tycho reactor编译时自动处理依赖; - 兼容Eclipse IDE:
build.properties配置了所有源码目录,Eclipse可直接识别并编译; - 兼容非Java生成器:如果使用ANTLR、Python等非Java生成器,直接在
generate-sources阶段运行即可,无需调整模块结构。
内容的提问来源于stack exchange,提问作者Árpád Magosányi
相关产品推荐
相关产品推荐

