Bobby Woolf 谈J2EE体系结构和设计

日期: 2009-12-15 作者:IBM developerworks网站 来源:TechTarget中国 英文

  Java™ 2企业版(Java™ 2 Enterprise Edition,J2EE)是开发并部署企业应用程序的环境。J2EE平台由服务、应用程序编程接口(application programming interfaces,API)及协议所组成,该协议提供了开发多层的且基于Web的应用程序的功能。

  问:EJB或Web服务的BEA控制及注释看上去是非常强大的并且易于使用这些技术。对此,您的看法是什么?在WebSphere®中使用这些技术有多容易?

  答: 您似乎希望获得BEA® WebLogic Workshop和IBM WebSphere Studio Application Developer(以下简称WebSphere Studio)的比较。我没有使用Workshop,所以不能直接评论它的特点。WebSphere Studio确实包含许多对于元信息的编辑器,如部署描述符。使用这些编辑器比编辑原始的XML要容易得多(虽然 Source 记录页面也允许您那样做)。同样,在WebSphere Studio V5中重新设计了这些编辑器,使其与J2EE指定的和WebSphere指定的配置设置有更加明显的不同。

  问:您知道如果启用了WebSphere Application Server V5.1 Global Security,那么Web服务和WebSphere Application Server之间的传输是否可以自动地转换成https?例如,使用defaultSSLsettings和jmserver认证。我不必在Web和Application服务器之间创建新的证书。同时,我已经具有Web和浏览器客户端之间的https了。目前,这仅是不完整的Web<>WAS https。全局安全性还没有被启用。

  答:在WebSphere Application Server 5.1中启用全局安全性会自动地进行Web服务的HTTPS转换吗?据我所知不是这样的。您需要自己手动完成。请见WebSphere Application Server Information Center中的“调用HTTPS上的web服务”和“使用HTTP基础认证来安全化安全的Socket层上的简单对象访问协议服务”。

  问:在我们的项目中有一套EJB。基本上,我们具备安装在WebSphere Studio V5.1.2 上的EAR文件。当测试环境服务器运行时,对于EJB项目及客户端项目的代码变更都不会受到影响。每次我都需要重新启动测试环境服务器才能使得改变生效。那么,存在任何方案或配置装置来解决这个问题吗?

  答:如果在您使用调试器编辑代码的时候(例如编辑EJB实现类,但不改变EJB的接口)启用了hot-method替换,那么将立即改变正在运行的应用程序的代码。请见WebSphere Studio的在线帮助中的“Hot-method 替换”。您也可以重启个别项目,这比重新启动整个项目要快得多。然而,许多变更需要重启测试服务器才能实现;请见WebSphere Studio的在线帮助中的“何时需要重启测试服务器”。也可参阅“调试服务器上的企业级bean”和“调试服务器上的servlet”。

  问:在Web应用程序中,我们希望将uid和pwd传递到EJB层中,以便会话EJB能够通过uid和pwd连接到后端系统。我们不想将uid和pwd作为参数传递,或者存储到一些从Web层到EJB层传递的对象中。同时,存在不同的流程,它需要使用uid和pwd来连接后端。您能推荐完成该任务的解决方案吗?

  答:对于J2EE应用程序,所有用户都使用同样的登录信息来访问后端系统。J2EE不能使每个应用程序的用户都使用各自的登录信息。您的 EJB层应当是无状态的服务,该服务由无状态的会话bean来负责管理,所以不能存储用户的数据,如用户名或密码。您可以在用户的 HTTPSession 中存储这些项目,但是这可能是巨大的潜在安全漏洞,并且登录信息可能不是非常有用的。所以,您需要使用J2EE服务来访问后端系统,它对于所有用户都使用同样的登录信息。

  如果您的后端系统是JDBC数据库,那么您应当将登录信息与数据源联系起来。例如,在WebSphere Studio中,在服务器配置编辑器中添加登录信息作为安全页面上的JAAS 认证条目,然后将其指定为数据源容器管理的认证别名(在数据源页面上)。对于其他的后端系统,您应当获取或开发适合于J2EE连接器体系结构(J2EE Connector Architecture)的适配器,它也提供了登录信息。

  如果您有两种类型的用户,那么他们应当使用两种不同的登录信息,我的文章消除 J2EE 1.3 的服务探测器实现中的缓存中讨论了如何使用两个不同的EJB类来完成此项工作(登录)。显而易见,该技术不能使得成百上千的用户都用他们自己的登录信息登录。

  问:我不是EJB专家,但是我已经学习了IBM提供的该方面的大量的教程和红皮书。我个人认为WebSphere Studio生成“管理的代码”(它被优化来管理容器)的能力激发了开发人员更大的创造力,远远超过不使用EJB开发的时候。这甚至适用于用不到EJB的情形。我的问题是:应当纠正它吗?我已经试着让我的公司从纯生产的角度来学习WebSphere Studio或WebSphere Application Server的EJB开发,但外面的顾问已经发现了所有EJB的负面案例。

  如果IBM有以小型或中型商店为对象而编写的白皮书,那么它将起到帮助作用。该商店展示了比“Banking”应用程序(使用WebSphere Studio和类似于Spring/Hibernate/JDO/“whatever”解决方案的WebSphere Application Server 来开发的应用程序)更复杂的基于web的EJB应用程序。我认为加快设计及开发应用程序的速度要与减少实际编写的代码量同时进行,通过使用WebSphere Studio能够使代码编写更高效。这假设工具能有效地支持您的向导生成的代码。

  花费的时间、创建的代码、应用程序的性能及每方面的耗费的具体细节都能证明通过使用WebSphere Studio或WebSphere Application Server使得J2EE或EJB开发比一行一行地推敲业务及管理代码更加高效且可维护。再一次,将与提高整体性能相关的硬件耗费同缩短开发时间及提高对于庞大的代码库的维护能力所需的耗费进行权衡之后,我认为前者可以忽略不计。

  答:您对于向SMB市场提供更多的市场及技术材料的意见我十分赞同,但是在我的部门这并不实际。我所能做的是试着回答技术问题。

  您在正确的轨道上,也就是您应当最大限度地利用这些工具使得您的工作更简单,最大限度地利用容器使得代码的编写工作更容易。简短的代码更易于编写、测试、调试、维护及通过端口传输。您的代码应以您唯一的业务值为主,而不是寻找每个典型的应用程序的需求,这可以由容器来处理。

  我对EJB的负面案例没有强烈的兴趣。许多由于EJB 1.0的时间框架和忽视诸如本地接口和容器管理的关联(container-managed relationships,CMR)的改进。大多数负面案例包含实体bean并忽视会话及消息驱动的EJB的危险程度。

  即使使用实体bean,O/R映射还是非常困难的,那么您使用什么会好一些呢?我建议开发者开始使用CMP实体bean来将他们的域建模并且处理他们数据库的O/R映射。“然而CMP非常慢的!”也许,O/R映射是通用的,至少对于CMP而言,您使用容器来优化该流程。IBM有许多开发人员致力于将O/R映射工作做得尽可能好。我想问每个客户:您真的认为您的团队能够开发更好的代码吗?(尤其是他们是否已经认为EJB太难了?)我认为首先尝试CMP。如果证实它确实太慢了(或不能忍受),那么确定出现问题的特定的bean并替换它们。然后您需要再次运行您的加载测试,并且验证您的新代码真的优于它所取代的CMP代码。如果开发者严格地检查结果,并且不相信传闻,我认为他们会发现标准的J2EE的特点及WebSphere支持对于他们实际工作是非常有利的。

  问:我们使用WebSphere Studio 5.0作为开发环境开发了一个 J2EE 应用程序。但是我们希望将其部署在WebSphere Application Server 4.0上。由于 EAR 文件是由WebSphere Studio 5.0生成的,所以它兼容WebSphere Application Server 5.0。它给出了关于DTD的错误。考虑到相关的 EJB,我们仅使用了无状态会话bean。需要哪些改变?在WebSphere Application Server 4.0中的哪些地方需要部署应用程序?

  答:如果我正确地理解了您的问题,那您的意图是使用WebSphere Studio 5.0(目前最新的版本是 5.1.2,所以您可能希望升级到该版本)来开发应用程序,并将其部署在WebSphere Application Server 4.0中。看上去您为 WebSphere Application Server 5.0开发应用程序,这是WebSphere Studio 5.0的缺省模式,目前它不能部署而且WebSphere Application Server 4.0也是如此,所以您想知道原因及应该做什么。我希望正确地理解了您的问题。

  好消息!您一定可以使用WebSphere Studio 5.0来开发WebSphere Application Server 4.0 应用程序。这是WebSphere Studio 5.0所特有的,以便开发者能升级到我们最新的工具,即使产品不准备升级到最新的WebSphere Application Server版本。您仅需要知道如何做。

  您需要做的是为WebSphere Application Server 4.0开发应用程序,而不是WebSphere Application Server 5.0默认的WebSphere Studio 5.0。下面是关于在哪里及如何完成这项工作的两个例子:

  在J2EE透视图中,当您选择New -> Enterprise Application Project时,请选择创建J2EE 1.2项目。这样做是因为WebSphere Application Server 4.0支持J2EE 1.2,不是J2EE 1.3默认的WebSphere Studio 5.0。

  同样在 J2EE 透视图中,当您选择New -> EJB Project时,请选择创建 EJB 1.1 项目。这样做是因为WebSphere Application Server 4.0 和J2EE 1.2支持EJB 1.1,不是EJB 2.0默认的WebSphere Studio 5.0。(当然,您不能获得最新的EJB 2.0特征,但是为此您需要升级到WebSphere Application Server 5.0.2或之后的版本。)

  在Server透视图中,当您选择New -> Server and Server Configuration时,请选择创建服务器配置类型为WebSphere v4.0 Server Configuration的服务器。您可以在Server Type列表的WebSphere version 4.0文件夹中找到它。这创建了测试服务器,它是WebSphere Application Server 4.0独立的服务器,为了能测试您部署在完整的WebSphere Application Server 4.0中的J2EE 1.2应用程序。

  在Window -> Preferences中,J2EE下,对于部署中所用的最高的J2EE版本,您可以选择J2EE 1.2。然后,WebSphere Studio将认为您正在为WebSphere Application Server 4.0(或另一个J2EE 1.2容器)进行部署。

  问:这是有关事务管理和回滚的设计问题,它们被编码在单独的DB2®实例(非分布式事务)上。应用程序使用DAO模式来将数据存储到多个表中,一个应用程序使用的每个DAO都保存在一张表中。会话外观EJB业务方法调用了一个以上的DAO来将其保存在一张以上的表中。启用了管理事务的容器。我阅读了一些声明的事务管理的文章,您需要完成其中的一件事:

  使用业务方法中的setRollBackOnly()

  使业务方法抛出运行时的异常

  目前,已经选择了第二项;构造DAOException来扩大RuntimeException,并且当错误发生时所有的DAO类都抛出DAOException实例。请您给出建议,哪个选择是最好的?哪个能使我们的代码有更好的复用性?对于第一种选择,我认为您需要为每个业务方法添加额外的代码行setRollBackOnly(),我认为这很麻烦。

  使用WebSphere Studio V4 IDE测试环境,事务管理及回滚会很好地进行,但是无论何时将应用程序部署到WebSphere Application Server V4上,都不会有回滚发生。存在任何特定的配置或设置来启用WebSphere Application Server V4上声明的事务管理吗?

  答:您很好地利用了模式。数据访问对象(Data Access Object,DAO)及会话外观(Session Facade)都是非常值得一用的。由于您使用EJB,所以进入了普遍存在的困境中:如何实现您的EJB代码及如何使用应用程序的异常?何时使用 setRollbackOnly()?怎样同时配合使用它们?

  应用程序异常表示发生了业务逻辑错误:取款超出了账单余额、预订已被订出的座位、获取已被冻结的信用卡的费用等等。这同系统异常不同,系统异常表示系统级别的错误,如耗尽内存或者数组越界。根据EJB规范(第18章)中指出的,应用程序异常必须是Exception的子类,并且不能RuntimeException或RemoteException的子类,这是非常好的建议。同时,根据该规范,容器必须能够捕获系统异常,标记事务用于回滚,并向EJB客户端抛出RemoteException或EJBException异常。容器必须将应用程序异常传递到EJB客户端并且不改变该异常以及事务。

  我认为这是非常矛盾的,系统异常引发了自动回滚而应用程序异常不能。已经抛出了异常,那么您真的要执行这些事务吗(哪个是自动的行为)?我不这么认为。然而,这是EJB的工作方式。

  因此,对于您的情况:您的应用程序异常类是RuntimeException的子类。这是不好的。当它自动执行回滚的同时,也将您有含义的描述的应用程序异常转换成了通用的异常。规范中指出不要这样做。

  您必须自己处理回滚。这意味着您在会话外观(您的EJB容器的最高层)中编写代码时需要养成这样的习惯——捕获应用程序异常、调用setRollbackOnly()方法并重新抛出同样的异常以便使EJB客户端知道发生了什么。这是编写优秀的EJB代码的方法:在向EJB容器外抛出异常之前,请不要使用RuntimeException的子类及setRollbackOnly()方法。

  问:先前我的应用程序是基于WebSphere 4.0 的J2EE 1.2标准开发的。目前,我试着使用WebSphere Studio 5.0(WebSphere 5.0)的J2EE 1.3标准转换它。我将应用程序从j2ee1.2移植到j2ee1.3的级别。

  我有两个模块,一个是EJB模块(它包含所有的 EJB),另一个是Web模块。该Web模块被成功地转换成每个J2EE 1.3标准。该EJB模块在转换过程中出现了一些错误。日志文件如下:

以下是引用片段:
1 Info: Project structure did not need migration: SCLS-ejb.

3   Info: J2EE version level did not need migration: SCLS-ejb.

5   Info: Migration was not required for META-INF/ejb-jar.xml.

7   Error: java.lang.NullPointerException

9   Error: Unable to migrate the Map and Schema file structure in project SCLS-ejb

  由于这个错误,我不能正常地运行应用程序。所有的实体bean都不起作用。我不能使用实体bean来插入记录。

  答:您已经使用了WebSphere Studio 5.0中的J2EE Migration Wizard试图将您的J2EE 1.2应用程序移植到J2EE 1.3,但是由于使用了NullPointerException而使其失败了。由于我不了解您的代码,所以判断工具出现的故障是很困难的。您或许需要求助于IBM Support。至于您的EJB代码为什么不能正常地执行,可能与您移植工具中出现的故障有关,但也可能因为您需要移植代码。移植向导仅更新了您的部署描述符,而没有更新EJB实现中的代码。请见WebSphere Studio在线帮助中的“移植J2EE应用程序”和“从J2EE 1.2移植到 1.3”。

  问:我真需要学习EJB吗?

  答:我要讲一个在我出席WebSphere Technical Exchange会议时发生的故事。我提出了分布式(XA)事务上的会话及实验:如何将其编码及它们如何工作。该实验由一些简单的样例代码组成,主要是由JDBC数据库及JMS消息系统更新的无状态会话bean(EJB),因此需要分布式的事务。该样例还包含被SSB简单调用的servlet。该实验进行得非常好,事务回滚按预期的计划进行,所有都很顺利。实验之后,客户问我:“真是太棒了!我如何能够仅使用servlet来完成它?”回答是:您不能。我问他为什么不使用EJB。他和他的合作者都感到EJB很难。即使EJB及容器管理的任何内容能使复杂的编程工作变得更简单,人们仍旧认为它们不够简单。

  该故事的含义是:如果您有完成复杂任务的工具,并且希望完成那些任务,那么您需要学习这些工具。我不想论证 EJB 是容易的,但是我不认为用它能非常容易地完成复杂的任务:事务、安全、池、远程调用——当然,由于实体 bean 具有容器管理的持久性。其他的哪些技术使您能够使用面向几百个用户的对象来支持上千个用户?其他的哪些技术使您能够声明您的事务模型、安全模型、持久性模型等在 XML 中的模型并且能在运行时运行那些模型?

  Java(J2SE)包含庞大的类库,使您开发应用程序时不能任意妄为。J2EE包含服务及框架,它们完成了许多您应用程序所需的工作。使容器完成尽可能多的工作,这样您的应用程序就不必去做了。以尽可能少的代码编写您的应用程序,并且使容器来完成此项工作。代码量越少,开发进度就越快,维护越容易,且能更快地通过端口传输到J2EE和WebSphere Application Server的下一个版本中。因此,我的建议是尽可能多地掌握容器给您带来的益处,以及诸如WebSphere Studio Application Developer之类的开发工具使您能完成哪些工作,并且最大限度地利用它们。

  问:我应当使用同步或异步的信息传递吗?

  答:该问题一直存在。我们正在使用RPC(例如,RMI、CORBA、具有远程接口的EJB 等等);为什么我们应当使用JMS或消息传递?通常,当用户等候回答时,由于用户是同步的,所以可以同步地调用。当一个应用程序调用其它的应用程序时,进行异步调用。如果一个应用程序要向其他一些应用程序通告事件,那么也是异步调用。同步调用极易受破坏,所以为了使远程调用更稳固,要进行异步调用。

  存在这样的理解——消息传递比 RPC 慢且低效。然而,消息传递确实有比RPC更高的地方,仅有一点性能差异,除非您加入了高品质的服务,如持久性的消息传递。如果消息传递很慢,这由于您的网速很慢,在这种情况下RPC也会很慢或者根本不能工作。

  通常用户接口不能支持异步调用,因为UI阻碍了调用,可能需等候一段时间。一种技术是重载该页面,直到获得结果为止。更好的方法是重新设计UI,使其不能同步。例如,电子商务站点当打包并传输订单的时候不会出现浏览器阻碍。它告知用户“谢谢订购”并且当订单传输的时候发送包含该包裹号码的电子邮件。这需要UI打破工作流,异步地执行,因此您需要诸如Process Choreographer之类的工作流引擎。然后,处理以异步的方式完成,并且用户可以随时检查它的进行情况。

  这是Web服务的缺陷,没有价值。目前,Web服务(WS-I 基本概要 1.1)是同步的。调用者发出HTTP请求,并且阻止了等候HTTP响应。由于 Web 服务是用于应用程序到应用程序的信息传递,所以若它们能够支持异步的信息传递将会更加有用。

  问:SOA和ESB之间的区别是什么?

  答:面向服务的体系结构(Service Oriented Architecture,SOA)是一种方式或架构,用于具有自服务功能的应用程序,应用程序随后通过用户接口(UI)或经过工作流将其聚合成用户的功能。服务不仅是可复用代码的组件,更是运行程序的一部分,客户端可以不必合并它自己的代码直接调用该程序。事实上,应用程序的界限变得非常模糊了,它包括所有能被调用来执行它的功能的服务。

  企业服务总线(Enterprise Service Bus,ESB)是用于调节SOA中的调用者及服务提供者的机制。它使得调用者在不知道提供者或提供者使用的地址的情况下调用该服务。ESB可在多个提供者、提供者的负载平衡及停止使用提供者(当失效时)之间进行选择,并且基于调用者的需求在提供者之间进行选择,这些提供者提供了各种质量级别的服务。ESB能够调节同步或异步服务,事实上对于同一服务可以提供同步及异步的访问。

  因此SOA和ESB是相对应的。具备SOA的应用程序应当使用ESB来调用它的服务。SOA和ESB不必用Web服务实现。然而,经常需要ESB来调用服务,该服务提供自我描述及发现的能力,这由Web服务帮助完成。在SOA中经常需要由一种技术实现的调用者,它们用于调用由其它技术实现的服务,这也由Web服务帮助完成。所以SOA、ESB和Web服务都集中于创建这样的领域——一个应用程序中的功能在其它应用程序中也是可用的,本质是复用性。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐

  • 事件驱动框架和SOA在空军的应用

    空军正在利用SOA来改善数据共享,并实时跟踪战机,美国空军机动司令部的Michael Marek解释了企业可从中学习的经验。

  • 揭秘New Relic APM技术细节

    New Relic应性能管理(APM)套件主要用于Web软件开发。它允许用户在面向服务的架构(SOA)上跟踪关键事务性能,并且支持代码级别的可见性来评估特定代码段和SQL语句对性能的影响

  • 仅凭SOA和云无法解决业务数据管理风险问题

    SOA和云可以是某些恼人问题高效的解决方案;这一点我们已经知道了。但是也要记住它们并不是所有事情的直接答案,特别是当你的问题是业务数据管理风险,而不是技术问题时。

  • 内存数据网格提供商一头扎进Java

    10年的时间里,应用性能解决方案提供商Alachisoft一直在用NCache(针对N-Tier和网格计算.NET应用的内存计算和数据网格产品)为.NET社区服务。