如何最好地实现 2002 年时代的 J2EE 应用程序的现代化?

2022-09-02 04:43:49

我有这个朋友....

我有一个朋友,他在2000年代初开始的java ee应用程序(j2ee)应用程序上工作。目前,他们在这里和那里添加了一个功能,但具有较大的代码库。多年来,该团队已经萎缩了70%。

[是的,“我有这个朋友是”。是我,试图幽默地将青少年高中辅导员的羞耻感注入其中]

爪哇,2002年

该应用程序使用EJB 2.1,struts 1.x,DAO等直接的jdbc调用(存储过程和预准备语句的混合)。没有 ORM。对于缓存,他们使用OpenSymphony OSCache和自产的缓存层的混合。

在过去几年中,他们一直在努力使用ajax技术和库对UI进行现代化改造。这主要涉及javascript libaries(jquery,yui等)。

客户端

在客户端,缺少从 struts1 到 struts2 的升级路径,这阻碍了他们迁移到 struts2。其他Web框架变得流行(wicket,spring,jsf)。Struts2不是“明显的赢家”。将所有现有的UI从Struts1迁移到Struts2 / wicket / etc似乎并没有以非常高的成本带来太多的边际效益。他们不希望有一个技术拼凑在一起的技术(Struts2中的子系统X,Wicket中的子系统Y等),所以开发人员使用Struts 1编写新功能。

服务器端

在服务器端,他们考虑迁移到ejb 3,但从未有很大的动力。开发人员都对ejb-jar感到满意.xml,EJBHome,EJBRemote,“ejb 2.1原样”代表了阻力最小的路径。

关于 ejb 环境的一大抱怨是:程序员仍然假装“ejb 服务器在单独的 jvm 中运行,而不是 servlet 引擎”。没有应用程序服务器(jboss/weblogic)强制执行这种分离。该团队从未将ejb服务器部署在单独的盒子上,然后再部署在应用程序服务器上。

ear 文件包含同一 jar 文件的多个副本;一个用于“web层”(foo.war/WEB-INF/lib),一个用于服务器端(foo.ear/)。应用服务器仅加载一个 jar。重复性使人模棱两可。

缓存

至于缓存,他们使用几种缓存实现:OpenSymphony缓存和自生缓存。Jgroups 提供集群支持

现在怎么办?

问题:团队目前有空闲的周期来投资实现应用程序的现代化?聪明的投资者会把它们花在哪里?

主要标准:

1)生产力提高。特别是减少了开发新子系统功能的时间并减少了维护。2)性能/可扩展性。

他们不关心时尚或技术上的街头信誉。

你们都推荐什么?

在持久性方面将所有内容(或仅新开发)切换到 JPA/JPA2?
直接冬眠?等待 Java EE 6?

在客户端/Web框架方面:迁移到(部分或全部)到struts2?检票口?jsf/jsf2?

至于缓存:兵马俑?嗯?相干?坚持他们拥有的东西?如何最好地利用 64 位 jvms 提供的巨大堆大小?

提前致谢。


答案 1

真的很难证明重新设计“有效”的东西是合理的。你花了很多工作回到你开始的地方。

可是。

从 EJB 2.1 Session Bean 到 EJB 3 的过渡是相当微不足道的。对我们来说,当我们进行过渡时,大多数 EJB 都是单独部署的,而不是在组合的 EAR 中部署的。但你没有这个问题。即使使用 EJB 3,您很可能仍然拥有一个 ejb-jar.xml文件(或多个文件)。

但是,我认为仍然有好处,而且成本非常低。你可以增量地做到这一点,一个豆一个豆与“一次全部”,这很好,只需将当前ejb-jar中的大部分信息移动到应用程序中.xml文件中。如果不出意外的话,它将可见性(如事务要求等)带入代码,而不是“隐藏”在ejb-jar.xml文件中。

没有理由将“应用层”部署到单独的 jvm/服务器上。Web 层是否在呼叫远程会话 Bean?与本地?通过切换到本地调用,您可能会看到也可能看不到速度(如果配置正确,许多“共存”部署可以类似于某些服务器上的本地调用,如果您已经在这样做,则为dunno)。

切换到本地的最大风险是,通过远程调用,您的参数是“安全”的,不会被更改,因为它们是通过网络序列化的。使用局部语义,如果您有意或无意地更改参数的值(即,更改Bean中属性的值),则该更改将反映在调用方中。这可能是一个问题,也可能不是一个问题。如果他们已经在使用本地调用语义,即使是“远程”Bean,那么他们已经遇到了这个问题。

至于JPA与SQL,我会保持原样。不值得将整个数据层重做为SWTIC到JPA,如果你真的想要JPA运行时(与开发时间)的好处,特别是缓存等,那么你必须一次转换整个数据层(或者至少是大块相互关联的部分)。真的很有风险,容易出错。

对于“重复 jar”问题,这是打包和构建的工件,而不是部署。要解决歧义问题,您需要在开发环境中使用共享的jar存储库,并认识到这样一个事实,即如果您升级一个jar,您将为所有用户升级它。人们谴责这是一个不合理的要求,如果jar发生了变化,就会迫使整个应用程序升级。当然,对于庞大而不同的应用程序。但对于单个JVM中的应用,不,它不是。尽管我们希望每一点都成为我们称之为Java类加载器环境的汤中的一个孤立的世界,但这根本不是真的。我们越能保持这种简化,我们在复杂性和维护方面就越好。对于常见的 jar,可以考虑将这些 jar 捆绑到应用服务器并捆出应用程序。我不喜欢这种方法,但如果你能让它为你工作,它就有它的用途。它肯定会减少部署大小。

客户端,从Struts 1转换为Struts 2并不难,因为它们在高层次上非常相似(值得注意的是,它们都是操作框架)。这里的关键是,这两个框架可以彼此并存,再次允许增量变化。您可以慢慢地迁移旧代码,也可以只在新框架中实现新代码。这与尝试混合和匹配操作框架和组件框架不同。从字面上看,这是一个“狗和猫,生活在一起”的情况。如果我要走这条路,我会简单地在他们自己的WAR中部署组件内容,然后继续前进。组件框架的状态管理使得在后端与它们进行互操作变得非常麻烦。如果您选择通过新的 WAR 实现,请确保花一点时间进行某种“单点登录”,以便人们根据需要“登录”每个模块。只要应用程序不共享任何会话状态,这就是集成真正需要的距离。一旦你选择通过新的WAR添加一个新的子系统,你就可以在客户端使用任何你想要的技术。

缓存是另一个问题。不同的缓存解决了不同的问题。在系统内缓存和记忆一些小位(如 JSP 渲染)或在故障转移或负载平衡期间使用分布式缓存跨实例传输会话是一回事。拥有一个基于缓存的域层是另一回事,其中持久性和缓存非常非常紧密地集成在一起。这要复杂得多。只是把它全部放在你的脑海中是痛苦的。

前者,当您遇到需求时,您几乎可以随意地在整个应用程序中散布,并且这些类型的缓存几乎可以是独立的,而不是协调的,总体的缓存框架的一部分。

后者,则不同。在那里,您几乎需要重做整个数据模型,即使对于您根本没有缓存的部分也是如此,因为您希望确保对数据及其缓存视图具有一致的访问权限。

这实际上是JPA所做的,它有两个级别的缓存,以及为什么我之前提到过它不是你可以随便溜进应用程序的东西,除了系统的大部分独立块。当您有不同的模块命中相同的后端资源时,缓存一致性和一致性成为一个真正的问题,这就是为什么您希望将它们集成到两个系统上的原因。

介意,这是可以做到的。诀窍是简单地集成数据访问级别,然后您可以在该级别开始缓存。但是,如果你有人进行直接的SQL调用,那么这些必须去。

最后,我认为使用的术语是进化,而不是革命。迁移到 EJB 3 或 3.1 我认为不必很痛苦,因为它几乎与 EJB 2.1 一起工作,这是一个福音。你可以有一个“混合”环境。最痛苦的集成是如果你使用Entity Bean,但你没有,所以这很好。对于所有 EJB 反对者来说,这种跨越了 EJB 近 10 年的向后兼容性,是什么让你真正保留了大部分代码,但仍然向前发展。


答案 2

几年前,我和自己处于一个非常相似的位置,有一个复杂的、整体式的应用程序,由EJB 1.x和一个本土的MVC框架混合而成。一次迁移整个东西从来都不是一种选择,我需要一种一次一点地做到这一点的方法,而不会破坏任何东西,也不需要批准一个大预算项目。

让我做到这一点的工具是Spring(当时的v1.2)。当你从Spring中删除所有流行语时,你留下的只是一个简单的框架,用于集成不同的应用程序组件,从而更容易将这些组件换成替代品,并随着您的发展而现代化。

例如,Spring为您提供了与Struts 1的集成,从而可以更轻松地将Struts 1组件引入“Spring way”。您的 Struts 应用程序应该像以前一样运行,但现在它们已经有了自下而上的现代化改造的筹码。

接下来,Spring的数据访问抽象将允许您插入现有的JDBC DAO,并开始引入DA抽象以使其更容易现代化。如果你选择坚持使用JDBC,那很好,Spring提供了广泛的JDBC支持,让它感觉不那么石器时代。如果你想修改JPA或Hibernate,那么它们将与Spring管理的应用程序集成,就像JDBC一样容易。

对于EJB,Spring可以将EJB访问层包装成不那么史前的东西,使它们更容易吞咽。一旦您将客户端层与 EJB 数据访问的细节隔离开来,如果您愿意,则可以将 EJB(一次一个)替换为更简单的 Spring 管理组件(具有任何远程处理、事务、安全性或全部不使用它们),或者如果您愿意,也可以保留 EJB(也许使用 EJB3)。

总而言之,让Spring接管应用程序“骨干”的角色,同时开始使用您已经拥有的相同遗留组件。然后,您可以按照自己决定的速度和风险,增加现代化的自由度。

这并不容易,但只要有一些耐心和毅力,你就可以到达你想去的地方,而不会有太多的干扰。