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

use*_*465 21 java caching jdbc java-ee

我有这个朋友......

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

[是的,"我有这个朋友".这是我,试图幽默地注入少年高中辅导员的耻辱]

Java,Vintage 2002

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

在过去几年中,他们花了很多精力来使用ajax技术和库来实现UI的现代化.这主要涉及javascript库(jquery,yui等).

客户端

在客户端,缺少从struts1到struts2的升级路径阻碍了它们迁移到struts2.其他Web框架变得流行(wicket,spring,jsf).Struts2不是"明显的赢家".将所有现有的UI从Struts1迁移到Struts2/wicket /等似乎并没有以非常高的成本提供太多的边际收益.他们不希望拼凑出各种技术(如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 /).app服务器只加载一个jar.重复使得含糊不清.

高速缓存

至于缓存,它们使用多个缓存实现:OpenSymphony缓存和本地缓存.Jgroups提供群集支持

怎么办?

问题是:团队目前有多余的周期来投资现代化应用程序?聪明的投资者会在哪里花钱?

主要标准:

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

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

你们都推荐什么?

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

在客户端/ Web框架方面:将(部分或全部)迁移到struts2?便门?JSF/JSF2?

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

提前致谢.

Wil*_*ung 7

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

那就是说.

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

但是,我认为仍然有好处,而且成本非常低.你可以逐步地进行bean,bean和"all all",这很好,只需将当前ejb-jar.xml文件中的大部分信息移动到应用程序中的注释即可.如果不出意外,它会将可见性(如事务要求等)带入代码,而不是"隐藏"在ejb-jar.xml文件中.

没有理由将"app tier"部署到单独的jvm/server上.Web层是否调用远程会话bean?vs本地?您可能会或可能不会通过切换到本地呼叫来看到加速(如果配置正确,许多"共处"部署可以类似于某些服务器上的本地调用,如果您已经这样做,则不知道如何).

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

至于JPA vs SQL,我会保持原样.不值得重做整个数据层以切换到JPA,如果你真的想要JPA运行时(与开发时间相比)的好处,特别是缓存等,那么你必须转换整个数据层(或至少大)所有相互关联的部分都是一次性的.确实存在风险且容易出错.

对于"重复的罐子"问题,这是包装和构建的工件,而不是部署.要解决歧义问题,您需要在开发环境中使用共享jar存储库,并认识到如果将j​​ar升级为jar,您将为所有人升级它.人们谴责这是一个不合理的需求,迫使整个应用程序升级,如果一个jar改变.对于庞大的,完全不同的应用程序,当然.但是对于单个JVM中的应用程序,不,它不是.尽管我们希望每一点都能成为一个孤立的世界,我们称之为Java类加载器环境,但事实并非如此.我们越能保持简化,我们在复杂性和维护方面就越好.对于常见的罐子,您可以考虑将这些罐子捆绑到应用服务器和应用程序之外.我并不喜欢这种方法,但是如果你能让它适合你的话,那就有它的用途.它肯定会减少部署规模.

客户端,从Struts 1转换为Struts 2并不难,因为它们在高层次上非常相似(特别是它们都是动作框架).这里的关键是两个框架可以相互并存,允许再次进行渐进式更改.您可以慢慢迁移旧代码,或者您可以在新框架中单独实现新代码.这与尝试混合和匹配动作框架和组件框架不同.这实际上就是"狗与猫共同生活"的情况.如果我要走这条路,我只需将组件内容部署到自己的WAR中继续前进.组件框架的状态管理使得后端与它们的互操作真的很麻烦.如果您选择通过新的WAR实施,请确保花一点时间进行某种"单点登录",以便人们"适当地"登录到每个模块.只要应用程序不共享任何会话状态,这就是集成真正需要的范围.一旦您选择通过新WAR添加新子系统,您就可以使用您想要的任何技术用于客户端.

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

前者在遇到需求时几乎可以毫不费力地在应用程序中使用,而且这些类型的缓存可以非常独立,而不是协调的,总体缓存框架的一部分.

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

这实际上是JPA所做的,它有两个级别的缓存,为什么我之前提到它不是你可以随便插入应用程序的东西,除了你的系统的大多数独立的块.当您使用不同的模块来访问相同的后端资源时,缓存一致性和一致性就成为一个真正的问题,这就是您希望在两个系统上集成的模块的原因.

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

最后,我认为使用的术语是进化,而不是革命.迁移到EJB 3或3.1我不认为必须是痛苦的,因为它几乎与EJB 2.1一起工作,这是一个福音.你可以有一个"混合"的环境.如果您使用Entity bean,那么最痛苦的集成就是如此,但您没有,所以这很好.对于所有的EJB反对者来说,这种向后兼容性跨越了近10年的EJB,实际上可以让您保留大量代码,但仍然可以继续前进.