使用插件扩展 Java Web 应用程序

发布于 2024-07-07 06:02:31 字数 508 浏览 9 评论 0原文

我的这个 Web 应用程序已经变得一团糟,难以管理。

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

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

我试图只制作几个常规的 war 文件,但 Tomcat 将(根据 servlet 规范)这些 war 文件彼此完全分开,因此它们无法共享它们的类。

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

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

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

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

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

I have this web application that has grown to an unmanageable mess.

I want to split it into a common "framework" part (that still includes web stuff like pages and images) and several modules that add extra functionality and screens. I want this refactoring to also be useful as a plugin system for third-party extensions.

All modules need to be separate unit of deployments, ideally a war or jar file.

I tried to just make several regular war files, but Tomcat keeps (according to the servlet spec) these war files completely separate from each-other, so that they cannot share their classes, for example.

I need to plugins to be able to see the "main" classpath.

I need to main application to have some control over the plugins, such as being able to list them, and set their configuration.

I would like to maintain complete separation between the plugins themselves (unless they specify dependencies) and any other unrelated web applications that may be running on the same Tomcat.

I would like them to be rooted under the "main" application URL prefix, but that is not necessary.

I would like to use Tomcat (big architectural changes need to be coordinated with too many people), but also to hear about a clean solution in the EJB or OSGi world if there are.

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

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

发布评论

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

评论(8

追我者格杀勿论 2024-07-14 06:02:32

查看 Java Portlet - http://developers.sun.com/portalserver/ Reference/techart/jsr168/ - 简而言之,该规范允许独立的 j2ee Web 应用程序之间进行互操作

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

Take a look at Java Portlets - http://developers.sun.com/portalserver/reference/techart/jsr168/ - in a nutshell, a specification that allows interoperability between what are otherwise self-contained j2ee web applications

Edit
I forgot to mention that Portlets are pretty much framework agnostic - so you can use Spring for the parent application, and individual developers can use whatever they want on their Portlets.

恋竹姑娘 2024-07-14 06:02:32

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

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

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

Have you looked at using maven to separate out your projects and then have it resolve the dependencies between the WARs and JARs? You'll end up with duplication of libraries between WARs, but only where it's necessary (and this shouldn't be a problem unless you get into some funky classloader fun).

Tomcat also allows you to configure cross context applications if you need to get from one WAR to another in a relatively transparent way...

If you want to keep things under the same single web app (say ROOT) you could create a proxy webapp that forwards through to the relevant other webapp behind the scenes for the user to make it relatively transparent?

无语# 2024-07-14 06:02:32

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

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

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

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

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

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

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

Your primary problem is going to center around the physical, static assets of the system -- the rest are simply, effectively, jars.

WARs are separated, in Tomcat, with separate classloaders but also they're separated at the session level (each WAR is an indvidual web app, and has it's own session state).

In Glassfish, if the WARs were bundled in an EAR, they would share classloaders (GF uses a flat class loader space in EARs), but would still have separate session state.

Also, I'm not sure if you can do a "forward" to another WAR in the server. The problem there is that forwards use a relative URL to the root of the Web App, and each WebApp has their own root, so you simply "can't get there from here". You can redirect, but that's not the same thing as a forward.

So these features of the Web App conspire against you trying to deploy them homogenously within the container.

Rather, I think the hot tip is to create an "assembler" utility that takes your individual modules and "merges" them in to a single Web App. It can merge their web.xml, their content, normalize the jars and classes, etc.

WARs are a feature and a bug in the Java world. I love them because they really do make deploying compiled applications "Drag and drop" in terms of installing them, and that's feature is used far more than what you're encountering. But I feel your pain. We have a common "core" framework we share across apps, and we basically have to continuously merge it to maintain it. We've scripted it, but it's still a bit of a pain.

秋意浓 2024-07-14 06:02:32

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

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

glassfish 和 EAR 的多次战争:这是有道理的。

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

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

那有意义吗 ?

BR,
~A

"Also, I'm not sure if you can do a "forward" to another WAR in the server. The problem there is that forwards use a relative URL to the root of the Web App, and each WebApp has their own root, so you simply "can't get there from here". You can redirect, but that's not the same thing as a forward."

You can forward to another WAR as long as that WAR lets someone do it.

glassfish and multiple WARs of an EAR : that makes sense.

If you put the MAIN classes in the shared CLASSPATH of tomcat, then you can put your individual PLUGINs in separate WAR files.

The Main app can also be part of the TOMCAT servlet that you define in server.xml. This can be the MASTER SERVLET and all other WARs can be controlled by this master servlet.

Does that make sense ?

BR,

~A

厌倦 2024-07-14 06:02:32

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

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

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

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

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

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

Depending on the complexity of the plugin functionality I would also be considering a web service, for instance implemented with Axis.

Your main appplication is then configured with the URL to the web application (plugin) which provides the service.

The advantage,as I see it, is twofold:

  • You get a nice, clean, debuggable API between the two wars, namely the
    Soap/XML messages
  • You are able to upgrade a single plugin without having to regression-test your
    entire application

The disadvatages are that you have to set up some Axis projects, and that you have to have some
sort of plugin configuration. Furthermore you might need to limit access to your services web
applications, so a bit of configuration might be required.

If the plugins work on the same database be sure to either limit cache time or to configure a war-spanning
caching layer.

指尖凝香 2024-07-14 06:02:32

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

现在,正如您所说,首选方法是使用 WAR 或 JAR 文件来完成此操作。
WAR 文件的问题是,您无法作为插件部署到现有应用程序。 Tomcat 会将其部署为单独的 Web 上下文。 不理想。

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

OSGI 或 Spring Dynamic 模块都很好,但目前,它们对我来说看起来过于复杂。 如果我有感觉的话,我会再次研究一下。

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

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

I also been trying develop a common or abstract framework where I can add plugins (or modules) at runtime and enhance existing running webapp.

Now, as you said, preferred ed way to do it using WAR or JAR file.
Problem with WAR file is, you can't deploy as plugin to existing app. Tomcat will deploy it as separate web context. Not desirable.

Another option is to JAR file and write some custom code to copy that JAR file to WEB-INF/lib folder and load the classes into existing classloader. Problem is, how to deploy non-java files like JSP or config files. For that, there r two solutions, a. Use velocity templates instead of JSP (b.) write some custom code to read JSP from classpath instead of context path.

OSGI or Spring Dynamic modules are nice, but at this time, they look overly complex to me. I will look into that again, if I get feel of it.

I am looking for simple API, which can take care of life cycle of plugin and still able to use JSPs in my packaged JAR file.

May be, you can use un jar the plugin at time deployment and copy files to right directories.

谜泪 2024-07-14 06:02:32

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

如果您了解一些有关组件编程的知识,您很快就会发现 OSGI 模块的行为类似于接口,您必须公开将在其他模块中使用的内容。 一旦你理解了,就很简单了。 不管怎样,当你学习如何使用 OSGI 时,它也会非常痛苦。 我们在使用 JSON 时遇到了问题,因为我们作为 jar 添加到模块中的 Jackson 版本被 Spring 核心模块中包含的其他 jar 覆盖。 您始终必须仔细检查根据您的需要加载的 jar 版本。

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

There actually is nothing better than OSGI if you are thinking about splitting application into separate modules. Take a look at Greenpages example. You can create a parent module (core) where you include jars that your application need.

If you know something about component programming, you will soon find out that OSGI modules behave like interfaces, where you have to expose what you will use in other modules. It is quite simple once you understand. Anyway it also can be really painful when you learn how to use OSGI. We had problems using JSON, as a version of Jackson that we added as jar to the module, was overridden by other jar that was contained in the Spring core modules. You always have to double check what version of jar is loaded for your needs.

Unfortunately even OSGI approach does not solve what we are searching for. How to extend a persistent model and existing forms in runtime.

饭团 2024-07-14 06:02:31

我一直在考虑使用 OSGi 来解决您所描述的相同问题。 特别是我正在考虑使用 Spring 动态模块

I have been tinkering with the idea of using OSGi to solve the same problem you are describing. In particular I am looking at using Spring Dynamic Modules.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文