7

我有这个 Web 应用程序已经发展到无法管理的混乱状态。

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

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

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

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

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

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

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

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

4

8 回答 8

4

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

于 2008-10-03T23:44:23.710 回答
3

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

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

于 2008-10-04T09:40:01.463 回答
1

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

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

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

于 2008-10-03T23:47:16.747 回答
1

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

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

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

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

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

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

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

于 2008-10-03T23:49:10.347 回答
1

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

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

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

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

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

那有意义吗 ?

BR,
~A

于 2008-10-04T02:24:46.990 回答
0

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

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

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

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

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

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

于 2008-10-04T09:27:48.680 回答
0

我也一直在尝试开发一个通用或抽象的框架,在其中我可以在运行时添加插件(或模块)并增强现有的正在运行的 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 插件并将文件复制到正确的目录。

于 2009-04-22T12:58:22.153 回答
0

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

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

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

于 2012-08-15T20:59:29.663 回答