在集成 Maven、Tycho 和 Eclipse 时处理非 OSGi 依赖项

2022-01-15 00:00:00 dependencies java eclipse maven tycho

我有一堆基于 Eclipse 的插件,我一直在迁移到 Maven/Tycho.这些插件中的大多数依赖于我现在通过 Maven 管理的独立库,而不是与 .jar 文件混在一起.

I have a bunch of Eclipse-based plugins that I have been migrating to Maven/Tycho. Most of these plugins depend on separate libraries that I now manage through Maven, rather than muddle around with .jar files.

我当前设置中最繁琐的部分是由于 Tycho 明显无法处理仅限 Maven(即非 OSGi)的工件.我目前的设置是这样的:

The most cumbersome part of my current setup is due to the apparent inability of Tycho to process Maven-only (i.e. non-OSGi) artifacts. My current setup works like this:

  1. 在每个 Eclipse 插件的 pom.xml 中,我在 maven-dependency-plugin 发出 unpack 目标代码>初始化阶段.这会将我指定的工件解压缩到单独的 target/dependencies 目录.

  1. In the pom.xml of each Eclipse plugin I issue an unpack goal to maven-dependency-plugin during the initialize phase. This unpacks the artifacts that I specify to a separate target/dependencies directory.

target/dependencies目录作为输出目录添加到build.properties中,以便Tycho在编译时可以将其添加到classpath中:p>

The target/dependencies directory is added as an output directory in build.properties, so that Tycho can add it to the classpath when compiling:

source.. = src/main/java/
output.. = target/classes/
output.. = target/dependencies/

  • target/dependencies 目录添加到 META-INF/MANIFEST.MF 中的 Bundle-ClassPath 库中.

  • The target/dependencies directory is added to the Bundle-ClassPath library in META-INF/MANIFEST.MF.

    这些设置允许 compile Maven 指令编译插件.从 VCS 导入项目并手动将 target/dependencies 目录指定为 Eclipse 中的类文件夹允许所述 IDE 也编译插件.

    These settings allow the compile Maven directive to compile the plugin. Importing the project from VCS and manually specifying the target/dependencies directory as a class folder in Eclipse allows said IDE to also compile the plugin.

    不幸的是,这是一个相当麻烦的解决方案,原因如下:

    Unfortunately this is a rather cumbersome solution for a few reasons:

    • 配置 maven-dependency-plugin 需要列出所有应该解包的工件.一个可以使用unpack-dependencies而不是unpack,但这也会解压所有OSGi依赖项——在每个项目目录中解压Eclipse的一半是不是我的乐趣...

    • Configuring the maven-dependency-plugin requires listing all artifacts that should be unpacked. One could use unpack-dependencies instead of unpack, but that would also unpack all OSGi dependencies - having half of Eclipse unpacked in each project directory is not my idea of fun...

    在Eclipse中添加class文件夹需要运行一次Maveninitialize,这样target/dependencies目录就创建好了.

    Adding the class folder in Eclipse requires Maven initialize to be run once, so that the target/dependencies directory is created.

    在 Eclipse 中,纯 Maven 项目与其依赖的 Tycho 项目之间没有源代码连接.对于从 Maven 项目传播到 Tycho 项目的更改,例如Eclipse 可能会显示一个潜在的编译问题,必须先 mvn install Maven 项目,然后在 Tycho 项目中运行 mvn clean initialize 以删除之前解压的依赖项并拉入当前设置.然后你必须刷新 Eclipse 项目并希望 Eclipse 做正确的事情.

    There is no source connection between the pure Maven projects and their depending Tycho projects in Eclipse. For a change to propagate from a Maven project to an Tycho project, so that e.g. Eclipse may show a potential compilation problem, one has to mvn install the Maven project and then run mvn clean initialize in the Tycho project to remove the previously unpacked dependencies and pull in the current set. Then you have to refresh the Eclipse project and hope that Eclipse does the right thing.

    同样,从 Tycho 项目中查看依赖项的源代码不会显示主要源文件,而是显示 target/dependencies 中可用的任何内容 -很可能只是一个 .class 文件.

    In the same vein, viewing the source of a dependency from a Tycho project will not show the primary source file, but rather whatever is available in target/dependencies - quite possibly just a .class file.

    我认为必须有一个更合理的方法来解决这个问题 - 可以让 Eclipse 和 Maven 项目更紧密地集成.

    I am thinking that there must be a more reasonable way to go about this - something that would allow Eclipse and Maven projects to integrate more tightly.

    那么,我错过了什么?此用例的推荐设置是什么?有更好的选择吗?最好是不需要设置一堆 Nexus 和/或 p2 存储库的东西?

    So, what am I missing? What is the recommended setup for this use case? Is there a better alternative? Preferably something that would not require setting a bunch of Nexus and/or p2 repositories?

    推荐答案

    看起来我们采用了类似的策略.但是,我使用的是 nexus 混合存储库(同时具有 maven 和 p2).

    It seems like we apply similar strategies. However, I use a nexus mixed repository (having both maven and p2).

    1. 对于解包依赖项,我使用 maven-dependency-plugin 将它们放置在目标/依赖项中(见下文).
      • 1.1.复制依赖项无需解包即可完成所需的工作.
    • 2.1.是的,mvn 必须初始化目标/依赖项
    • 3.1.我手动选择相关的罐子.
    • 3.2.是的,如果非 Eclipse 管理(maven)项目发生变化(在您的工作区之外),那么您必须运行 mvn build 来更新它们.
    • 3.3.完成这项工作的关键是:
      • 3.3.1 将您的 maven 和 Eclipse 项目部署到(快照)存储库.我使用 http://www.sonatype.org/nexus/ .因此,当您运行 maven 时,它会查看 nexus 存储库以获取 maven 和 Eclipse 项目的更新.
      • 3.1. I manually select the relevant jars.
      • 3.2. Yes, if the non-Eclipse-managed (maven) projects change (outside of your workspace), then you have to run mvn build to update them.
      • 3.3. A key to making this work, is to:
        • 3.3.1 Deploy your maven and Eclipse projects to a (snapshot) repository. I use http://www.sonatype.org/nexus/ . Thus, when you run maven, it looks at the nexus repository for updates of both maven and Eclipse projects.
        • 4.1.pom.xml 文件应该只包含非 Eclipse jar 作为依赖项.(tycho 插件处理所有 Eclipse 依赖项,这些依赖项应该可以在您的(nexus)存储库中找到.)
        • 4.2.将依赖的 jars 添加到 Eclipse 中的运行时(通过编辑 plugin.xml 运行时)

        Maven 插件:

                <plugin>
                    <!-- Copy non-Ecipse plugins to target/dependency so that may be referenced 
                        for runtime use. -->
                    <artifactId>maven-dependency-plugin</artifactId>
                    <version>2.1</version>
                    <executions>
                        <execution>
                            <id>copy-dependencies</id>
                            <goals>
                                <goal>copy-dependencies</goal>
                            </goals>
                            <configuration>
                                <excludeGroupIds>org.XXX</excludeGroupIds>
                            </configuration>
                        </execution>
                        <execution>
                            <id>classpath</id>
                            <goals>
                                <goal>build-classpath</goal>
                            </goals>
                            <configuration>
                                <fileSeparator>/</fileSeparator>
                                <prefix>target/dependency</prefix>
                                <outputFile>${project.build.directory}/classPath.txt
                                </outputFile>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
        

        示例 build.properties

        bin.includes = META-INF/,
        target/classes/,
        plugin.xml,
        target/dependency/mongo-java-driver-2.11.3.jar
        

        示例清单(仅 jar 的一个子集):

        Bundle-ClassPath: .,
        target/classes/,
        target/dependency/mongo-java-driver-2.11.3.jar
        
  • 相关文章