java - 如何在 Maven 和 Eclipse 中使用不同的依赖版本两次构建相同的源代码?

标签 java eclipse maven m2eclipse

我想构建两个不同版本的自定义 SonarQube (SQ) 插件;一个用于 SonarQube 6.7.x LTS 版本,一个用于最新的 7.6 版本。目前,我有一个类似于以下的 Maven 结构:

  • 家长
    • common:两个工具和两个插件版本使用的公共(public)代码,不使用 SQ API
    • 工具:一些相关的命令行实用程序,不使用 SQ API
    • plugin-6.7:SQ 6.7 的插件代码
    • plugin-7.6:SQ 7.6 的插件代码
    • dist:构建包含 CLI 实用程序的分发 zip,包括插件版本、依赖许可证和源代码

plugin-6.7 和 7.6 的大部分源代码和资源都是相同的;只有少数类是不同的。因此,我想将此公共(public)代码移动到某个共享源文件夹/模块。

尽管如此,我仍然想将这个公共(public)代码编译两次,以验证代码是否针对两个 SQ API 版本编译。在 Eclipse 中,这应该显示为两个单独的源文件夹或项目,因此我可以轻松验证通用代码没有使用 6.7 API 中尚不可用的任何 SQ API,也没有使用任何已删除的 API或在 7.6 API 中弃用。

我最好坚持在一个版本中构建两个插件版本,所以如果可能的话,我想避免使用两个单独的配置文件。

这有可能吗?

我尝试过的

通过 Maven,我找到了几种方法来实现它,但我无法使用这些方法中的任何一种来使用 m2eclipse。

方法一

新建模块plugin-common,包含pom-6.7.xml和pom-7.6.xml。除了 Artifact ID 或分类器以及对不同 SQ API 版本的依赖性之外,这两个 pom 本质上是相同的。父项目使用

将它们定义为 2 个独立的模块
<module>plugin-common/pom-6.7.xml</module>
<module>plugin-common/pom-7.6.xml</module>

这种方法的问题是我无法将这些模块导入到 Eclipse 中,因为 m2eclipse 只支持 pom.xml 作为文件名。

方法二

与上述类似,但对 pom.xml 文件使用单独的子目录并使用 <sourceDirectory>${project.basedir}/../src/main/java</sourceDirectory>指向公共(public)源代码:

  • 插件通用
    • 源代码/main/java
    • 源代码/主要/资源
    • pom.xml:6.7 和 7.6 模块的父级
    • 6.7/pom.xml
    • 7.6/pom.xml

这种方法允许将两个插件通用版本导入到 Eclipse 中,但 Eclipse 会提示“在项目基目录之外访问 .../src/main/java 目录”。因此,它不会显示两个插件通用项目中的任何源代码。

方法 3

plugin-common 中没有任何 pom.xml 文件,而是使用 build-helper-maven-plugin 将公共(public)代码作为源文件夹添加到 plugin-6.7 和 plugin-7.6 模块,使用 <source>${project.basedir}/../plugin-common/src/main/java</source> .

由于“访问项目基目录之外的.../src/main/java 目录”警告,这在 Eclipse 中再次失败。

最佳答案

我现在选择了以下方法,效果很好。

Maven结构:

  • 家长
    • common:两个工具和两个插件版本使用的公共(public)代码,不使用 SQ API
    • 工具:一些相关的命令行实用程序,不使用 SQ API
    • 插件:SonarQube插件代码
    • dist:构建包含 CLI 实用程序的分发 zip,包括插件版本、依赖许可证和源代码

插件模块包含 3 个基础包:

  • myproject.plugin.common:SQ 6.7 和 7.6 实现之间共享的代码
  • myproject.plugin.sq67:SonarQube 6.7 - 7.5.x 的特定代码
  • myproject.plugin.sq76:特定于 SonarQube 7.6+ 的代码

plugin/pom.xml使用SonarQube API依赖和封装插件定义类似如下:

        <dependency>
            <groupId>org.sonarsource.sonarqube</groupId>
            <artifactId>sonar-plugin-api</artifactId>
            <version>${sonarqube.version}</version>
            <scope>provided</scope>
        </dependency>
        <plugin>
            <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
            <artifactId>sonar-packaging-maven-plugin</artifactId>
            <version>1.16</version>
            <extensions>true</extensions>
            <configuration>
                <pluginKey>mykey</pluginKey>
                <pluginClass>myproject.plugin.common.MyPlugin</pluginClass>
                <pluginName>PluginName</pluginName>
                <pluginDescription>Description</pluginDescription>
                <useChildFirstClassLoader>true</useChildFirstClassLoader>
                <sonarQubeMinVersion>6.7</sonarQubeMinVersion>
            </configuration>
        </plugin>

这允许插件与 SonarQube 6.7+ 一起工作,即使 API 依赖版本设置为 7.6(见下面的配置文件)。 MyPlugin 类是一个通用类,它使用 Java 反射加载特定于 6.7 或特定于 7.6 的实现,具体取决于运行插件的 SonarQube 版本。

最后,父pom.xml 定义了以下两个配置文件:

    <profiles>
        <profile>
            <id>default</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <sonarqube.version>7.6</sonarqube.version>
            </properties>
            <modules>
                <module>common</module>
                <module>plugin</module>
                <module>tool</module>
                <module>dist</module>
            </modules>
        </profile>
        <profile>
            <id>checkSQ6.7Compatibility</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <properties>
                <sonarqube.version>6.7</sonarqube.version>
            </properties>
            <modules>
                <module>common</module>
                <module>plugin</module>
            </modules>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-compiler-plugin</artifactId>
                        <configuration>
                            <excludes>
                                <exclude>**/sq76/**</exclude>
                            </excludes>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

默认配置文件现在构建一个与 SonarQube 6.7 及更高版本兼容的插件,如果在该版本的 SonarQube 上运行,则启用 7.6 特定的功能。

checkSQ6.7Compatibility 配置文件将 SonarQube API 版本覆盖为 6.7,排除任何 SonarQube 7.6 特定的文件夹,并且仅构建公共(public)模块和插件模块(跳过工具和 dist)。这允许验证通用包和特定于 6.7 的包是否可以使用 6.7 API 编译。

在 Eclipse 中,我现在使用默认配置文件进行常规开发,这让我可以同时处理 6.7 和 7.6 的特定代码。在进行任何重大更改后,我可以简单地在 Eclipse 项目配置中选择 checkSQ6.7Compatibility 配置文件,以验证我没有意外地引入对任何 7.6 特定 API 的依赖。

关于java - 如何在 Maven 和 Eclipse 中使用不同的依赖版本两次构建相同的源代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55824022/

相关文章:

java - Spring Scheduling - 每个月晚上 11 点结束的 Cron 表达式?

eclipse - Eclipse 侧边栏可以自动隐藏吗?

spring - 创建名称为 'emf' 的 bean 在 ServletContext 资源中定义时出错

java - Groovy 和 maven - 从 src/main/groovy 编译源代码

java - 跨开发人员共享 Maven 存储库

java - 如何将工作日添加到 Java 中的当前日期?

java - 整数哈希到字符串值

regex - 如何使用 Eclipse 或 PowerGREP 搜索和替换文件中的 block ?

java - 线程 "main"org.apache.axis2.AxisFault : Read timed out 中的异常

java - 当 10Mb 空闲时,Android 分配 4Mb 时出现 OutOfMemoryError