【问题标题】:Build classes in same package into separate jars将同一包中的类构建到单独的 jar 中
【发布时间】:2012-02-22 08:55:52
【问题描述】:

我有一个服务器应用程序和两个基于 Swing 的客户端应用程序。我们在 Eclipse 中开发它们,每个都有一个单独的项目。

许多课程是共享的。例如,my.server 包有一些用于服务器和客户端的类,而另一些只用于服务器。虽然我更喜欢将它们放在同一个包中,因为它们密切相关并且其中一些依赖于包的可见性,但我不想分发应用程序不需要的类,因为它不仅会增大文件大小,而且还会这将是一个安全风险。

目前,每个服务器和客户端都有相同的 jar,这是一团糟。理想情况下,我想根据依赖项自动创建 jars,如下所示。

服务器:

  • server.jar:仅服务器使用的类
  • server-client1-common.jar:Server 和 Client 1 共享的类
  • server-client2-common.jar:Server 和 Client 2 共享的类

客户端 1:

  • client1.jar:仅供客户端 1 使用的类
  • server-client1-common.jar:Server 和 Client 1 共享的类
  • client-common.jar:客户端 1 和客户端 2 共享的类,但服务器不共享

客户端 2:

  • client2.jar:仅供客户端 2 使用的类
  • server-client2-common.jar:Server 和 Client 2 共享的类
  • client-common.jar:客户端 1 和客户端 2 共享的类,但服务器不共享

我知道您可以使用 ant 手动执行此操作,但这将是一场维护灾难。有没有工具可以自动处理这种依赖关系?

【问题讨论】:

标签: java build


【解决方案1】:

“维护灾难”是什么意思?如果您创建了一个 ANT 脚本,只需运行它,它就会为您编译和打包 jar。

作为更强大的替代方案,您可以使用 maven。对于更轻量级的东西,内置的 eclipse 导出工具可能会起作用。

【讨论】:

  • 受维护灾难,不是每次创建类或接口都需要更新ant脚本吗?
  • 您可能应该创建至少三个单独的包 - serverclientshared,然后将它们添加到脚本中。
  • 这就是我遇到的问题 - 在同一个包中,一些类依赖于包的可见性,一些是共享的,而另一些则不应该共享。
  • 如果你依赖于应该在不同包中的类的数据包可见性(例如,一个在客户端运行,另一个在服务器上运行),你应该重新考虑你的架构...... IMO你由于没有正确组织它们并试图找到一个可以在构建期间为您组织它的工具,从而使事情变得复杂。
  • 我们的项目(1,000,000 行)的结构如下:com.example.[client|server|shared].individual.package.names。 ant 脚本很大(仅仅是因为项目的大小),但它在 jar 步骤中使用通配符来创建适当的 jar - 每个新类都不会更新。该方案出现的一个问题是在服务器上使用客户端代码,反之亦然。为了防止这种情况发生,我们在本地和增量构建中使用了 VerifyDesign (link)。
【解决方案2】:

我无法为您提供现成的解决方案。这里有一个想法:创建一个注释或一组注释,如下所示:

@jarselector(types='server')
class ServerOnly {
   ...
}

@jarselector(types='server,client1')
class ServerAndClient {
   ...
}

然后通过扩展 jar 任务(或 maven 插件)或编写您自己的任务来创建您自己的 ant 任务,该任务采用此注解并根据注解打包类,然后您将其用作过滤器。

您只需要创建一次任务 - 我过去做过,它没有听起来那么复杂,而且问题听起来足够大,值得付出努力。

之后,您必须对所有类进行一次注释(或者根据您的实现,仅对客户端需要的类进行注释,或者仅对每个 jar 不共享的类等进行注释)。任何看到类的人都可以立即看到它的用途。创建新类时,您可以轻松添加注释。

我真的不认为有现成的 ant 任务或 maven 插件可以做到这一点。

或者——如果你真的不能改变你的包结构——你也可以使用多个源目录来保存包,但将文件拆分到不同的目录中。 Eclipse 并不关心您使用了多少源目录。然后,您只需为源目录调整一次构建工具,然后就可以按这种方式对文件进行排序。

【讨论】:

    【解决方案3】:

    为您要创建的每个 JAR 设置一个单独的 Eclipse 项目。然后在构建路径的“项目”选项卡上为每个顶级项目设置依赖关系。因此,“server”项目将“server-client1-common”和“server-client2-common”列为必需项目。以此类推。

    我看到许多不同的组织都在使用这种模式,我一直认为这是“行业接受”的做法。它只是工作!

    【讨论】:

      【解决方案4】:

      关于构建应用程序的最佳实践之一是每个项目有一个 jar。
      例如,Maven 将其用作默认值。你可以欺骗它,但最好加入它们而不是“对抗”它们。

      http://maven.apache.org/guides/mini/guide-using-one-source-directory.html
      http://www.sonatype.com/people/2010/01/how-to-create-two-jars-from-one-project-and-why-you-shouldnt/

      因此,在您的情况下,您应该创建 6 个项目: 服务器、Client1、Client2、ServerClient1Common、ServerClient2Common、ClientCommon

      为了选择需要的类,我认为没有工具,可能您应该更好地了解什么是常用功能。 创建 Common 项目,并将它们添加到构建路径 - 依赖项。然后开始将您的类移动到 Common 项目中,将它们留在同一个包中。

      例如,创建 ServerClient1Common 项目。
      对于 Client1,转到配置构建路径 -> 项目。添加 ServerClient1Common。删除对服务器项目的所有引用。
      对于服务器,转到配置构建路径 -> 项目。添加 ServerClient1Common。删除对 Client1 项目的所有引用。

      您现在应该有很多缺少的类/导入。尝试一一解决。

      最后,你应该能够编译这3个项目并获得你提到的jar。

      PS:其他策略(比如一个具有不同构建目标的超级项目,或者 3 个具有相互缠绕的 ant/maven 构建器的项目)更加混乱。可能有一个例外 - 拆分类的另一种方式,但我不知道它是否适用于您:client1.jar、client1-interface.jar、client2.jar、client2-interface.jar、server.jar、server-接口.jar。这样,您可以使用 3 个项目,每个项目都有两个目标 jar。要运行 client2.jar,您需要 server-interface.jar

      【讨论】:

        猜你喜欢
        • 2013-02-16
        • 1970-01-01
        • 2014-03-01
        • 1970-01-01
        • 2014-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-24
        相关资源
        最近更新 更多