【问题标题】:Extending Java Web Applications with plugins使用插件扩展 Java Web 应用程序
【发布时间】:2008-10-03 23:37:34
【问题描述】:

我的这个 Web 应用程序已经变得一团糟。

我想将其拆分为一个通用的“框架”部分(仍然包括网页和图像等网络内容)和几个添加额外功能和屏幕的模块。我希望这种重构也可以用作第三方扩展的插件系统。

所有模块都需要是单独的部署单元,最好是一个 war 或 jar 文件。

我尝试只制作几个常规的 war 文件,但 Tomcat 将(根据 servlet 规范)这些 war 文件完全分开,例如,它们不能共享它们的类。

我需要插件才能看到“主”类路径。

我需要主应用程序对插件进行一些控制,例如能够列出它们并设置它们的配置。

我希望将插件本身(除非它们指定依赖项)与可能在同一 Tomcat 上运行的任何其他不相关的 Web 应用程序保持完全分离。

我希望它们以“主”应用程序 URL 前缀为根,但这不是必需的。

我想使用 Tomcat(大型架构更改需要与太多人协调),但也想了解 EJB 或 OSGi 世界中的干净解决方案(如果有)。

【问题讨论】:

    标签: java tomcat servlets modularity


    【解决方案1】:

    我一直在修改使用 OSGi 来解决您所描述的相同问题的想法。特别是我正在考虑使用Spring Dynamic Modules

    【讨论】:

    • 我和我工作的一个人也一直在谈论这样做。
    • 有人真的用osgi成功地做到了这一点吗?如果是这样 - 您对如何开始有什么指导?
    • 我实际上正在与一个使用 OSGi 实现应用程序服务层的团队合作。他们使用 Apache Felix 并嵌入了一个 Jetty 容器来将服务公开为 RESTful Web 服务。由于 Apache Felix 直到 1.8 版才完全支持片段,所以出现了问题。
    【解决方案2】:

    看看 Java Portlets - http://developers.sun.com/portalserver/reference/techart/jsr168/ - 简而言之,这是一个允许在其他自包含的 j2ee Web 应用程序之间实现互操作性的规范

    编辑 我忘了提到 Portlet 几乎与框架无关 - 因此您可以将 Spring 用于父应用程序,并且各个开发人员可以在他们的 Portlet 上使用他们想要的任何东西。

    【讨论】:

      【解决方案3】:

      您是否考虑过使用 maven 来分离您的项目,然后让它解决 WAR 和 JAR 之间的依赖关系?您最终会在 WAR 之间重复库,但仅限于必要的地方(这不应该成为问题,除非您喜欢一些时髦的类加载器乐趣)。

      如果您需要以相对透明的方式从一个 WAR 到另一个 WAR,Tomcat 还允许您配置跨上下文应用程序...

      如果您想将内容保存在同一个 Web 应用程序下(例如 ROOT),您可以创建一个代理 Web 应用程序,该代理 Web 应用程序在后台转发到相关的其他 Web 应用程序,以便用户使其相对透明?

      【讨论】:

        【解决方案4】:

        您的主要问题将集中在系统的物理、静态资产上——其余的都是简单有效的罐子。

        在 Tomcat 中,WAR 与单独的类加载器分开,但它们也在会话级别分开(每个 WAR 都是一个单独的 Web 应用程序,并且有自己的会话状态)。

        在 Glassfish 中,如果 WAR 捆绑在 EAR 中,它们将共享类加载器(GF 在 EAR 中使用平面类加载器空间),但仍具有单独的会话状态。

        另外,我不确定您是否可以“转发”到服务器中的另一个 WAR。问题在于转发使用 Web App 根目录的相对 URL,并且每个 WebApp 都有自己的根目录,因此您根本“无法从这里到达那里”。您可以重定向,但这与转发不同。

        因此,Web 应用程序的这些功能会阻止您尝试将它们同质地部署在容器中。

        相反,我认为热门提示是创建一个“汇编器”实用程序,它将您的各个模块“合并”到单个 Web 应用程序中。它可以合并它们的 web.xml、它们的内容、规范化 jar 和类等。

        WAR 是 Java 世界中的一个特性和一个错误。我喜欢它们,因为它们确实在安装它们时确实使部署编译的应用程序“拖放”,并且该功能的使用远比您遇到的要多。但我感觉到你的痛苦。我们有一个跨应用程序共享的通用“核心”框架,我们基本上必须不断地合并它来维护它。我们已经编写了脚本,但仍然有点痛苦。

        【讨论】:

          【解决方案5】:

          “另外,我不确定您是否可以“转发”到服务器中的另一个 WAR。问题是转发使用到 Web App 根目录的相对 URL,每个 WebApp 都有自己的root,所以你只是“无法从这里到达那里”。你可以重定向,但这与转发不同。”

          您可以转发到另一个 WAR,只要该 WAR 允许某人这样做。

          glassfish 和 EAR 的多个 WAR:这是有道理的。

          如果您将 MAIN 类放在 tomcat 的共享 CLASSPATH 中,那么您可以将各个 PLUGIN 放在单独的 WAR 文件中。

          主应用程序也可以是您在 server.xml 中定义的 TOMCAT servlet 的一部分。这可以是 MASTER SERVLET,所有其他 WAR 都可以由这个主 servlet 控制。

          这有意义吗?

          BR,
          ~A

          【讨论】:

            【解决方案6】:

            根据插件功能的复杂性,我还会考虑使用 Web 服务,例如使用 Axis 实现。

            然后为您的主应用程序配置提供服务的 Web 应用程序(插件)的 URL。

            在我看来,优势是双重的:

            • 您在两次战争之间获得了一个漂亮、干净、可调试的 API,即 Soap/XML 消息
            • 您可以升级单个插件,而无需对您的插件进行回归测试 整个应用程序

            缺点是您必须设置一些 Axis 项目,并且您必须有一些 某种插件配置。此外,您可能需要限制对您的服务网络的访问 应用程序,因此可能需要进行一些配置。

            如果插件在同一个数据库上工作,请确保限制缓存时间或配置战争跨越 缓存层。

            【讨论】:

              【解决方案7】:

              我也一直在尝试开发一个通用或抽象的框架,在其中我可以在运行时添加插件(或模块)并增强现有的正在运行的 webapp。

              现在,正如您所说,首选 ed 使用 WAR 或 JAR 文件的方法。 WAR 文件的问题是,您不能作为插件部署到现有应用程序。 Tomcat 会将其部署为单独的 Web 上下文。不可取。

              另一个选项是 JAR 文件并编写一些自定义代码以将该 JAR 文件复制到 WEB-INF/lib 文件夹并将类加载到现有的类加载器中。问题是,如何部署 JSP 或配置文件等非 java 文件。为此,有两个解决方案,a。使用速度模板而不是 JSP (b.) 编写一些自定义代码以从类路径而不是上下文路径读取 JSP。

              OSGI 或 Spring Dynamic 模块很不错,但目前对我来说它们看起来过于复杂。如果我感觉到它,我会再次研究它。

              我正在寻找简单的 API,它可以处理插件的生命周期,并且仍然能够在我打包的 JAR 文件中使用 JSP。

              可能,你可以在部署时使用 un jar 插件并将文件复制到正确的目录。

              【讨论】:

              • 是的,我自己也滚动了。但是您会感到痛苦,然后希望您从一开始就使用 Spring DS 或 OSGI。我知道我做到了。
              【解决方案8】:

              如果您正在考虑将应用程序拆分为单独的模块,那么实际上没有什么比 OSGI 更好的了。看一下 Greenpages 示例。您可以创建一个父模块(核心),在其中包含应用程序所需的 jar。

              如果您对组件编程有所了解,您很快就会发现 OSGI 模块的行为类似于接口,您必须在其中公开您将在其他模块中使用的内容。一旦你明白了,这很简单。无论如何,当您学习如何使用 OSGI 时,它也会非常痛苦。我们在使用 JSON 时遇到了问题,作为我们作为 jar 添加到模块中的 Jackson 版本,被 Spring 核心模块中包含的其他 jar 覆盖。您总是需要仔细检查您需要加载的 jar 版本。

              不幸的是,即使是 OSGI 方法也不能解决我们正在寻找的问题。如何在运行时扩展持久模型和现有表单。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2016-11-01
                • 1970-01-01
                • 1970-01-01
                • 2015-07-06
                • 2019-07-05
                • 1970-01-01
                • 2012-06-22
                • 2012-12-30
                相关资源
                最近更新 更多