如何模块化(大型)Java 应用程序?

发布于 2024-07-21 13:22:33 字数 804 浏览 4 评论 0原文

我手头有一个相当大的(几个 MLOC)应用程序,我想将其拆分为更易于维护的单独部分。 目前该产品由大约 40 个 Eclipse 项目组成,其中许多项目具有相互依赖性。 仅此一点就使得连续构建系统变得不可行,因为每次签入都必须进行大量重建。

是否有一种“最佳实践”方法来

  • 识别可以立即分离的部分
  • 文档相互依赖性直观
  • 现有代码
  • 地理清我们需要应用于库的 句柄“补丁”(当前通过将它们放在实际库之前的类路径中来处理) )

如果有(免费/开放)工具支持这一点,我将不胜感激。

尽管我没有任何使用 Maven 的经验,但它似乎强制采用了非常模块化的设计。 我现在想知道这是否可以迭代地进行改造,或者使用它的项目是否必须从一开始就考虑到模块化的布局。

编辑于 2009-07-10

我们正在使用 Apache Ant 拆分一些核心模块/常春藤。 真正有用且设计良好的工具,不像 Maven 那样强加给你那么多。

我在我的博客上写下了一些关于我们为什么这样做的更一般的细节和个人意见 - 太长了,无法在这里发布,而且可能不是每个人都感兴趣,所以请自行决定遵循:www.danielschneller.com

I have a rather large (several MLOC) application at hand that I'd like to split up into more maintainable separate parts. Currently the product is comprised of about 40 Eclipse projects, many of them having inter-dependencies. This alone makes a continuous build system unfeasible, because it would have to rebuild very much with each checkin.

Is there a "best practice" way of how to

  • identify parts that can immediately be separated
  • document inter-dependencies visually
  • untangle the existing code
  • handle "patches" we need to apply to libraries (currently handled by putting them in the classpath before the actual library)

If there are (free/open) tools to support this, I'd appreciate pointers.

Even though I do not have any experience with Maven it seems like it forces a very modular design. I wonder now whether this is something that can be retrofitted iteratively or if a project that was to use it would have to be layouted with modularity in mind right from the start.

Edit 2009-07-10

We are in the process of splitting out some core modules using Apache Ant/Ivy. Really helpful and well designed tool, not imposing as much on you as maven does.

I wrote down some more general details and personal opinion about why we are doing that on my blog - too long to post here and maybe not interesting to everyone, so follow at your own discretion: www.danielschneller.com

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

牵你的手,一向走下去 2024-07-28 13:22:34

第一:祝你好运& 好咖啡。 你两者都需要。

我曾经遇到过类似的问题。 遗留代码具有可怕的循环依赖关系,甚至在来自不同包的类之间(例如 org.example.pkg1.A)也依赖于 org.example.pk2.B 反之亦然。

我从 Maven2 和新的 Eclipse 项目开始。 首先,我尝试确定最常见的功能(日志记录层、通用接口、通用服务)并创建 Maven 项目。 每次我对某个部件感到满意时,我都会将该库部署到中央 Nexus 存储库,以便它几乎可以立即用于其他项目。

所以我慢慢地逐层进行。 maven2 处理依赖关系,m2eclipse 插件提供了有用的依赖关系视图。 顺便说一句 - 将 Eclipse 项目转换为 Maven 项目通常并不太困难。 m2eclipse 可以为您做到这一点,您只需创建一些新文件夹(如 src/main/java)并调整源文件夹的构建路径。 只需要一两分钟。 但是,如果您的项目是 Eclipse 插件或 RCP 应用程序,并且您希望 Maven 不仅可以管理工件,还可以构建和部署应用程序,那么预计会遇到更多困难。

就我看来,eclipse、maven 和 nexus(或任何其他 Maven 存储库管理器)是一个很好的起点。 如果您有系统架构的良好文档并且该架构确实得到了实现,那么您很幸运;)

First: good luck & good coffee. You'll need both.

I once had a similiar problem. Legacy code with awful circular dependencies, even between classes from different packages like org.example.pkg1.A depends on org.example.pk2.B and vice versa.

I started with maven2 and fresh eclipse projects. First I tried to identify the most common functionalities (logging layer, common interfaces, common services) and created maven projects. Each time I was happy with a part, I deployed the library to the central nexus repository so that it was almost immediately available for other projects.

So I slowly worked up through the layers. maven2 handled the dependencies and the m2eclipse plugin provided a helpful dependency view. BTW - it's usually not too difficult to convert an eclipse project into a maven project. m2eclipse can do it for you and you just have to create a few new folders (like src/main/java) and adjust the build path for source folders. Takes just a minute or two. But expect more difficulties, if your project is an eclipse plugin or rcp application and you want maven not only to manage artifacts but also to build and deploy the application.

To opinion, eclipse, maven and nexus (or any other maven repository manager) are a good basis to start. You're lucky, if you have a good documentation of the system architecture and this architecture is really implemented ;)

2024-07-28 13:22:34

我在小型代码库(40 kloc)中也有过类似的经历。 没有“规则”:

  • 使用 编译而没有“模块”,以便查看它的用法
  • 我从“叶模块”开始,没有其他依赖项的模块
  • 我处理了循环依赖项(这是一个非常错误的错误) - 容易发生的任务)
  • 使用 Maven 有大量可以部署的文档(报告)
    在使用 Maven 的 CI 过程中
  • ,您始终可以看到站点中和 netbeans 中的内容都使用了哪些内容(使用
    非常好的有向图)
  • 使用 Maven,您可以在代码库中导入库代码,应用源补丁并
    与您的产品一起编译(有时这很容易有时非常
    困难)

还检查依赖分析器:

(来源:javalobby.org< /a>)

Netbeans:


(来源:zimmer428.net< /a>)

I had a similar experience in a small code base (40 kloc). There are no °rules":

  • compiled with and without a "module" in order to see it's usage
  • I started from "leaf modules", modules without other dependencies
  • I handled cyclic dependencies (this is a very error-prone task)
  • with maven there is a great deal with documentation (reports) that can be deployed
    in your CI process
  • with maven you can always see what uses what both in the site both in netbeans (with a
    very nice directed graph)
  • with maven you can import library code in your codebase, apply source patches and
    compile with your products (sometimes this is very easy sometimes it is very
    difficult)

Check also Dependency Analyzer:

(source: javalobby.org)

Netbeans:


(source: zimmer428.net)

亢潮 2024-07-28 13:22:34

对于现有系统来说,迁移到 Maven 是很痛苦的。 然而,它可以毫无困难地应对 100 多个模块项目。

Maven is painful to migrate to for an existing system. However it can cope with 100+ module projects without much difficulty.

心舞飞扬 2024-07-28 13:22:34

您需要决定的第一件事是您将迁移到哪种基础设施。 它应该是许多独立维护的模块(转化为单独的 Eclipse 项目),还是您会认为它是作为一个整体进行版本控制和部署的单个代码块。 第一个非常适合迁移到类似 Maven 的构建环境 - 后者可以一次性包含所有源代码。

无论如何,您都需要一个运行的持续集成系统。 您的第一个任务是自动构建代码库,这样您就可以让 CI 系统监视您的源存储库并在您更改内容时重建它。 我决定在这里采用非 Maven 方法,并且我们专注于拥有一个简单的 Eclipse 环境,因此我使用 ant4eclipse 和 Team ProjectSet 文件(我们无论如何都使用它)创建了一个构建环境。

下一步将是消除循环依赖 - 这将使您的构建更简单,消除 Eclipse 警告,并最终允许您进入“签出、编译一次、运行”阶段。 这可能需要一段时间:-(当您迁移方法和类时,不要移动它们,而是提取或委托它们并保留它们的旧名称并将它们标记为已弃用。这会将您的整理与重构分开,并允许代码“在您的项目之外,仍然可以使用项目内部的代码。

您将受益于允许移动文件和保留历史记录的源代码存储库。CVS 在这方面非常薄弱。

The first thing you need to decide is what infra-structure you will move to. Should it be a lot of independently maintained modules (which translates to individual Eclipse projects) or will you consider it a single chunk of code which is versioned and deployed as a whole. The first is well suited for migrating to a Maven like build environment - the latter for having all the source code in at once.

In any case you WILL need a continuous integration system running. Your first task is to make the code base build automatically, so you can let your CI system watch over your source repository and rebuild it whenyou change things. I decided for a non-Maven approach here, and we focus on having an easy Eclipse environment so I created a build enviornment using ant4eclipse and Team ProjectSet files (which we use anyway).

The next step would be getting rid of the circular dependencies - this will make your build simpler, get rid of Eclipse warnings, and eventually allow you to get to the "checkout, compile once, run" stage. This might take a while :-( When you migrate methods and classes, do not MOVE them, but extract or delegate them and leave their old name lying around and mark them deprecated. This will separate your untangeling with your refactoring, and allow code "outside" your project to still work with the code inside your project.

You WILL benefit from a source repository which allows for moving files, and keeping history. CVS is very weak in this regard.

2024-07-28 13:22:34

我不会推荐 Maven 作为遗留源代码库。 仅仅尝试调整所有内容来配合它可能会给您带来很多麻烦。

我想你需要的是对你的项目进行架构布局。 工具可能会有所帮助,但最重要的部分是组织模块的逻辑视图。

I wouldn't recommend Maven for a legacy source code base. It could give you many headaches just trying to adapt everything to work with it.

I suppose what you need is to do an architectural layout of your project. A tool might help, but the most important part is to organize a logical view of the modules.

明媚如初 2024-07-28 13:22:34

它不是免费的,但 Structure101 将为您提供尽可能好的击球工具支持你所有的要点。 但郑重声明,我有偏见,所以您可能也想看看 SonarJ 和 Lattix。 ;-)

It's not free but Structure101 will give you as good as you will get in terms of tool support for hitting all your bullet points. But for the record I'm biased, so you might want to check out SonarJ and Lattix too. ;-)

墨落成白 2024-07-28 13:22:33

使用 OSGi 可能很适合您。 它将允许在应用程序之外创建模块。 您还可以以更好的方式组织依赖关系。 如果您正确定义了不同模块之间的接口,那么您可以使用持续集成,因为您只需重建在签入时受影响的模块。

OSGi 提供的机制将帮助您理清现有代码。 由于类加载的工作方式,它还可以帮助您以更简单的方式处理补丁。

OSGi 的一些概念似乎很适合您,如维基百科所示:

框架从概念上讲,它分为以下几个区域:

  • 捆绑包 - 捆绑包是带有额外清单标头的普通 jar 组件。
  • 服务 - 服务层通过为普通旧 Java 对象 (POJO) 提供发布-查找-绑定模型,以动态方式连接捆绑包。
  • 服务注册中心 - 用于管理服务的 API(ServiceRegistration、ServiceTracker 和 ServiceReference)。
  • 生命周期 - 用于生命周期管理(安装、启动、停止、更新和卸载捆绑包)的 API。
  • 模块 - 定义封装和依赖关系声明的层(包如何导入和导出代码)。
  • 安全性 - 通过将捆绑包功能限制为预定义功能来处理安全方面的层。

Using OSGi could be a good fit for you. It would allow to create modules out of the application. You can also organize dependencies in a better way. If you define your interfaces between the different modules correctly, then you can use continuous integration as you only have to rebuild the module that you affected on check-in.

The mechanisms provided by OSGi will help you untangle the existing code. Because of the way the classloading works, it also helps you handle the patches in an easier way.

Some concepts of OSGi that seem to be a good match for you, as shown from wikipedia:

The framework is conceptually divided into the following areas:

  • Bundles - Bundles are normal jar components with extra manifest headers.
  • Services - The services layer connects bundles in a dynamic way by offering a publish-find-bind model for plain old Java objects(POJO).
  • Services Registry - The API for management services (ServiceRegistration, ServiceTracker and ServiceReference).
  • Life-Cycle - The API for life cycle management (install, start, stop, update, and uninstall bundles).
  • Modules - The layer that defines encapsulation and declaration of dependencies (how a bundle can import and export code).
  • Security - The layer that handles the security aspects by limiting bundle functionality to pre-defined capabilities.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文