【问题标题】:m2e: Folder containing java _sources_ need to be used by several m2e projectsm2e:包含 java _sources_ 的文件夹需要被多个 m2e 项目使用
【发布时间】:2013-05-19 23:54:51
【问题描述】:

我有一种情况,我需要一个包含 Java 源代码的文件夹,用作树结构中几个“彼此相邻”的 maven 项目的源文件夹。由于 maven 项目的依赖差异,我无法创建包含源的编译版本的工件,但需要让每个项目将其视为除了 src/main/java 之外的源文件夹。

显然 Maven 可以通过添加位于“../foo/src”中的另一个源文件夹轻松地做到这一点,但 m2e 拒绝这样做,为了让我们能够很好地工作,我需要让它在 Eclipse 中工作。

我将如何拥有这样的结构:

/common/src
/a/pom.xml  (add source folder ../common/src)
/a/src/main/java/...
/b/pom.xml  (add source folder ../common/src)
/b/src/main/java/....

让它在 Eclipse 中工作?

(注意:我知道http://dev.eclipse.org/mhonarc/lists/m2e-users/msg01988.html - 但是,它是从 2011 年开始的)

【问题讨论】:

标签: java eclipse maven m2eclipse m2e


【解决方案1】:

你不应该那样做。

如果您想在不同的模块中使用该代码,那么它也应该是一个 Maven 模块,用作其他模块的依赖项。

您尝试做的主要问题是,即使它不是两个模块之间源的实际复制/粘贴,最终它的行为就像一个。一旦你建立了两个罐子会发生什么?你会有重复的类,所以如果你在同一个应用程序中使用它们,类路径会有点错误。

那么,您到底想要完成什么?

  • 在两个不同的模块中重用某些代码?然后将其用作依赖 jar。
  • 在两个不同的模块中重用代码,但您不想以多个 jar 结尾?然后您可以使用maven-shade-plugin 将依赖项嵌入到最终工件中。
  • 为同一个库构建两个略有不同的版本?然后,您可以再次使用 maven-shade-plugin 来扩展一个带有其他源的 jar。或者,您可以使用 aspectj-maven-plugin 将方面注入到一组基类中。
  • 是否有会触发循环依赖的代码设计,因为模块依赖于公共代码,而公共代码又依赖于每个模块的代码?正确的解决方法是从模块中提取通用 API,该 API 将进入共享依赖项并由每个模块以不同方式实现。

如果您真的必须将其保留为共享源目录而不是共享依赖项,那么您可以查看this answer

【讨论】:

  • 我需要有一个在三个项目中使用的共享代码源,并且出于技术原因,该源还需要能够看到使用它的项目的源。原因是我们可能必须向相关客户的不同分支提供相同二进制文件的略有不同的版本。如果我只有一个依赖 jar,我不能引用项目特定类所在的项目 src/main/java(但需要诉诸工厂和/或依赖注入,这在更简单的方法中不需要)。重复的类在这里也不是问题。
  • 我明白了,所以你试图避免循环依赖和依赖复杂框架来进行 API⟷实现分离。我发现依赖注入对于任何项目来说都是一个非常好的设计决策,这将使未来的开发更加模块化。但是我不知道您的项目已经有多大,建议现在进行调整。所以我会推荐一个简单的工厂,它很容易实现并且不会给代码增加太多的复杂性。拥有共享源目录的文件系统对我来说是一种代码异味,是否要使用它是您的决定。
  • 请注意,这对于从命令行调用的 Maven 非常有效,尽管在使用扩展添加额外的源 jar 时。这是一个错误还是一个功能,还有待商榷。现在我同意这看起来不可行。
【解决方案2】:

文件系统的小技巧怎么样? 只需对文件夹进行符号链接,您可能就可以了 :)

对于 NTFS,您可以尝试从命令行执行 mklink。 更多解释在这里:http://en.wikipedia.org/wiki/NTFS_symbolic_link

【讨论】:

  • 我将如何使用 NTFS 执行此操作?
【解决方案3】:

您应该能够使用相对路径和Maven Build Helper 作为解决方案。

在每个项目中,或在它们都继承自的“父”pom.xml 中,添加以下内容:

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>1.8</version>
    <executions>
      <execution>
        <id>add-source</id>
        <phase>generate-sources</phase>
        <goals>
          <goal>add-source</goal>
        </goals>
        <configuration>
          <sources>
            <source>${basedir}/../../common/src</source>
          </sources>
        </configuration>
      </execution>
    </executions>
  </plugin>

【讨论】:

  • 应该很容易找到。我使用 IntelliJ ;-)
  • 问题是关于如何使它在 eclipse 中与 m2e 一起工作。我让它从命令行工作。
  • 好吧,我误解你的问题其实是关于 m2e 插件的。
【解决方案4】:

如果您使用 Subversion,可能最方便的方法是将共享源文件夹保存在单独的存储库中,并通过 svn:externals 将其添加到所有需要它的项目中。另一方面,这会使创建标签和分支变得更加复杂。

使用 Mercurial 子存​​储库可能会实现类似的功能,但不会那么方便。

【讨论】:

  • 对不起,没有。这是在 git 中。
【解决方案5】:

为什么不在其他项目的pom.xml 中简单地将公共库设为 Maven &lt;dependency /&gt; 并在依赖项目中使用 m2e 的“解决工作区项目中的依赖项”功能(我相信这是默认设置) (右键单击项目 => 项目属性 => Maven)?

这样,依赖项目将自动在 IDE 中查看公共库的类,而无需您实际构建/安装公共库工件到 maven 存储库(本地或远程)。

由于您使用的是 Git,因此分支可能会让您轻松提供公共库的不同版本(版本与 pom.xml 中的版本相同)并在相关项目的 &lt;dependency /&gt; 元素中相应地引用这些版本.

【讨论】:

  • 主要是因为我希望共享代码能够看到每个项目的src/main/java 中的代码,换句话说,每个项目都有一个单独的池。
【解决方案6】:

我会使用NTFS Junction

我在我的项目中使用它们来在项目之间共享资源,而无需实际复制它们。连接点就像驱动器和文件系统之间的黑洞。它们的行为与硬链接相同,但可以引用文件夹,即使在不同的驱动器(包括网络驱动器)上也是如此。从您的角度来看,它看起来就像在您的项目文件夹中有 /common/src 文件夹(然后您可以告诉 Eclipse 将其用作源文件夹)。当然,您可以重命名连接点,以便项目 a 看到的 /common/src 将被称为 common

/common/src
/a/src
/a/common <- this is a junction to /common/src

为了简化 Junction 的创建,我非常喜欢使用 this shell extension

【讨论】:

    猜你喜欢
    • 2011-10-02
    • 2016-12-18
    • 2023-03-26
    • 1970-01-01
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多