3

我有一个关于管理编译和部署 jar 依赖项的正确方法的一般性问题。对于一个简单的库/应用程序,我通常会像下面这样布置 dev 目录。

Calculator
   src
   test
   build
   lib
   …

有很多方法可以做到这一点,但这是我对通用项目的典型布局。我的问题围绕 lib 目录。我通常将我的项目所依赖的 jars 放在 lib 目录(log4j 等)中,因此在编译时我可以将各种路径设置为 lib\log4j.jar 或类似的东西。现在,当我们创建一个可分发的包时,我倾向于反映这种布局。

dist
   Calculator.jar
   lib
      log4j.jar
      addition.jar
      subtraction.jar

这允许我设置一个脚本来设置我的类路径相对于主 jar 的位置,或者我可以在清单中为主 jar 设置类路径(在这种情况下为 Calculator.jar)这可能是也可能不是最好的方法这样做,但它对我有用,并且似乎是我与之交谈过的其他开发人员处理依赖项的公认方式。

当我想创建一个使用我以这种方式布置的其他项目的新项目时,我的问题就来了。

所以假设我想创建一个新的计算器项目,它使用上面示例中的计算器项目。如果我遵循相同的布局,我会得到如下内容:

dist
   ScentificCalculator.jar
   lib
      Calculator.jar
      lib 
         Log4j.jar
         addition.jar
         subtraction.jar

当然,你的依赖树越深,这可能会失控:

SuperWhizBangCalculator.jar
lib
   ScientificCalculator.jar
   lib 
      Calculator.jar
      lib
         log4j.jar
         addition.jar
         subtraction.jar

另一种选择是展平树:

SuperWhizBangCalculator
   lib
      ScientificCalculator.jar
      Calculator.jar
      log4J.jar
      addition.jar
      subtraction.jar

但这似乎有些不对劲。您失去了告诉您哪些库与您所依赖的组件一起使用的结构。所以我想知道是否有一个社区驱动的标准方法来做到这一点,并理解从来没有一个适合所有人的尺寸。

谢谢你的时间...

4

7 回答 7

1

我不认为你会找到一个社区驱动的标准,但我认为总体上拥有一个 lib-in-a-lib 并不是一个好主意。您冒着复制许多项目通用的 jar 文件的风险。这会浪费磁盘空间,并且会给你升级不在你的类路径中的第一个 jar 的风险......

我认为您的第三种选择是最好的选择。

另外,我会考虑一下 Eclipse 如何管理两个不同项目之间的链接......您可以将一个项目放在另一个项目的构建路径中......

于 2010-03-02T05:34:26.687 回答
1

这里有两种类型的东西

  1. 与第三方库(如 log4j)的外部依赖
  2. 项目内部的依赖

理想情况下,您应该拥有内部依赖项的 lib 目录。您应该在创建部署计划时动态构建外部依赖项。

于 2010-03-02T05:59:26.787 回答
1

不直接回答你的问题。但是你可以看看 Apache 的 Maven 2,它可以为你做大部分的“依赖管理”。

请注意,让 Maven 2 启动、运行和工作有一些学习曲线 :)

除此之外,第三个选项对我来说很有意义。

于 2010-03-02T17:43:01.253 回答
1

回应另一个答案,“为什么不直接使用 Maven?”

Maven 将为您管理所有依赖项,当另一个项目想要使用您的 jar 时,他们这样做会容易得多。如果 Java 世界中有构建、布局和依赖项的标准,那就是 Maven。

于 2010-03-02T17:47:48.183 回答
1

选择你的最后一个选项 - flat lib 目录。如果您下载任何具有依赖关系的开源项目(如果有许多相关的 JAR,它们可能会使用另一个级别的子目录),您会发现这是什么。

不要将目录结构与依赖管理混淆——它们是完全独立的东西。如果你想要智能的依赖管理,那么你需要看看像 Maven、ANT 和 Ivy,或者可能是一些具有显式依赖的模块系统 (OSGi)。

于 2010-03-02T18:06:52.963 回答
0

我绝对会采用最后一种方法。想象一个程序 A 使用库 B 和 C,它们都使用 D。在结构化布局中,您将有两个 D 实例,这只是在乞求版本冲突。

于 2010-03-02T05:41:53.953 回答
0

关键的信息是如何加载类。在“java -jar SuperWhizBang.jar”情况下,您将有一个加载所有类的类加载器。那么合并依赖关系就很有意义了。

如果您选择使用单独的类加载器,那么层次结构将是一个好主意。这通常发生在 OSGi 设置中,但这对于您的解决方案来说可能是多余的。

于 2010-03-02T18:25:10.797 回答