You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Eclipse插件项目中用Java生成源码的项目布局方案咨询

问题描述

在eclipse-test-plugin构建过程中,需要用Java生成测试代码(测试数据、桩代码),并将生成器与生成的代码一同打包到插件中,供其他eclipse-test-plugin调用。生成器可能依赖当前模块已引入的其他Eclipse插件中的生成器。

要求满足:

  1. 支持在Maven reactor中编译多个此类模块;
  2. 项目可在Eclipse IDE中正常编译;
  3. 避免重复声明依赖;
  4. 尽量保持单模块结构(不希望拆分为生产模块+生成器模块+测试模块)。

尝试过将生成器视为生产代码、依赖它的代码视为测试代码,单模块可行但跨模块依赖时,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>

三、优势说明

  1. 保持单模块逻辑:生成器与测试代码同属一个模块,无需拆分,符合业务逻辑;
  2. 无依赖重复声明:所有依赖仅在MANIFEST.MF中声明,Tycho自动同步到Maven依赖;
  3. 跨模块依赖正常:生成器与生成代码作为生产API导出,其他模块通过Require-Bundle即可访问,Tycho reactor编译时自动处理依赖;
  4. 兼容Eclipse IDE:build.properties配置了所有源码目录,Eclipse可直接识别并编译;
  5. 兼容非Java生成器:如果使用ANTLR、Python等非Java生成器,直接在generate-sources阶段运行即可,无需调整模块结构。

内容的提问来源于stack exchange,提问作者Árpád Magosányi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 07:55:54