jboss4 迁移
几周前,我发布了一个有关从Java EE 5迁移到7的博客 。这主要是关于如何使用新的Java EE 7改进Java EE 5代码。 现在,在这篇文章中,我将对应用程序服务器端的迁移路径进行一些研究。
如果您使用的是Java EE 5,则很有可能正在使用以下服务器之一:
- JBoss 4倍或5倍
- 玻璃鱼 2x
- Weblogic 10倍
- Websphere 7倍
还有许多其他支持Java EE 5的服务器,您可以在此处检出它们。
序幕
我最终获得了我在JBoss 4x上的大部分经验,因为当时我正在工作的公司已经在他们的大多数项目中大量使用了它。 我对此事几乎没有表决权,只是保持与JBoss合作的方向。
当我们决定将我们的一个客户端关键应用程序从Java EE 5迁移到7时,我们面临着使用哪个应用程序服务器的难题。 自从我担任技术管理职务以来,我现在能够影响该决定。 由于以下原因,我们最终选择了Wildfly :
- 已实现Java EE 7完整配置文件
- 强大的CLI管理服务器
- 团队已经熟悉Wildfly随附的Java EE实现
即使这篇文章研究了JBoss和Wildfly ,但某些原则仍然适用于Application Server。 因此,我希望这对其他Application Server用户同样有用。 当前,我们正在使用Wildfly 8.2.0,但本文中讨论的内容也应与最新的Wildfly版本一起使用。
战略
执行Application Server迁移,尤其是涉及服务器之间相距甚远的迁移,绝非易事。 迁移路径并非一帆风顺,因为每个应用程序最终都会使用Application Server的不同功能。 更糟糕的是,该应用程序甚至可能正在实现这些功能所支持的业务代码,而这些功能可能在目标迁移服务器中不可用。
无论如何,在进行迁移项目时可以遵循两种策略:
功能冻结
顾名思义,您将冻结项目以执行必要的调整以迁移应用程序。 处理复杂性可能更容易,但是另一方面,它会延迟业务功能并创建不可协商的期限。 要说服利益相关者采用这种策略是非常困难的,但是如果您有能力的话,那就去做。
组合式
另一个选择是保持开发持续进行并同时进行迁移。 这对企业来说是最好的,但是需要更多的纪律和计划。 您始终可以将应用程序分区并将其拆分为模块,然后少量迁移。 这是我通常使用的策略。
第一步
您可能需要一些时间才能完全迁移您的应用程序。 在此期间,您需要保持旧服务器以及新服务器的运行。 为此,您需要更新和复制环境。 就像分支代码一样,但是在运行时。
您使用的支持工具可能也需要更新。 新服务器的Maven插件,即Jenkins部署,无论与Application Server进行交互。 这是一项艰巨的任务,因为管理所有这些额外环境和分支的复杂性并不容易。
走的路
考虑迁移时,您需要担心几个细节。 这不是一个详尽的列表,但可能是您将会遇到的最常见的主题。
类加载
如果您没有遇到ClassNotFoundException
, NoClassDefFoundError
或ClassCastException
您可能要考虑玩彩票并中奖!
对于JBoss 4.x Classloader尤其如此。 当时,类加载是(仍然是,但甚至超过)一项昂贵的操作,因此JBoss使用了一种称为UnifiedClassLoader
东西。 这意味着应用程序之间没有真正的隔离。 EAR档案可能会相互查看以加载库。 当然,这是要管理的主要难题。 最糟糕的部分是当您必须使用JBoss服务器将应用程序部署到客户中时。 如果您无法控制它,那么当前的部署可能会与您自己的部署发生冲突。
Wildfly引入了基于模块的类加载,而不是通常的分层方法。 通常,除非使用文件描述符明确声明,否则部署在Wildfly中的应用程序将无权访问Application Server库。 对于Java EE应用程序,这些模块是自动加载的。
更换服务器时,以下是与类加载相关的最常见问题:
- 坐在其他应用程序上的缺少库。
- 在服务器上已删除或更新的库上进行中继。
- 应用程序上使用的库现在是新服务器的一部分。
要解决此问题,您需要通过添加删除所需的库来调整项目依赖关系。 这里没有分步指南。 每种情况都需要进行分析并相应解决。 这有点像试图解开一个满是结的弦。
如果您使用的是Dependency Plugin ,那么您可以使用mvn dependency:tree
和mvn dependency:analyze
来帮助您。
Wildfly还为您提供了一个特定的描述符文件jboss-deployment-structure.xml
,通过添加或删除依赖项或更改类加载器的行为,您可以微调类加载。 这是一个例子:
jboss部署结构
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2"><ear-subdeployments-isolated>false</ear-subdeployments-isolated><deployment><dependencies><module name="org.jboss.msc" export="true"/><module name="org.jboss.as.naming" export="true"/><module name="org.jboss.as.server" export="true"/><module name="deployment.app-client.jar" export="true"/><module name="deployment.app-ear.ear.app-entity.jar" export="true"/></dependencies></deployment>
</jboss-deployment-structure>
这个自定义描述符正在添加来自其他部署的依赖关系,即app-client.jar
,甚至是app-ear.ear.app-entity.jar
中另一个EAR的子部署。
最后,我的建议是尝试遵守标准,仅在绝对必要时才引入其他库。 这肯定会减少您的类加载问题,并使将来更轻松地迁移到服务器的新版本甚至更改为另一台服务器。
常规配置
在JBoss 4.x中,所有配置都分布在不同的文件中: server.xml
, jboss-service.xml
, login-config.xml
以及许多其他文件。 您必须手动编辑文件才能更改所需的配置。 这是一项繁琐的工作,尤其是当您无权访问服务器并必须记录一组更改以供他人执行时。
在Wildfly中,大多数配置都进入configuration/standalone.xml
,但我从未编辑过该文件。 Wildfly附带了非常强大的命令行界面(CLI),可让您编写几乎所有需要在服务器上执行的更改的脚本。 以下是Undertow配置的示例:
欠佳
/subsystem=undertow/server=default-server/ajp-listener=ajp:add(socket-binding=ajp)/subsystem=undertow/server=default-server/host=app \:add( \alias=["localhost, ${app.host}"] \)/subsystem=undertow/server=default-server:write-attribute(name="default-host", value="app")/subsystem=undertow/server=default-server/host=app/filter-ref=server-header:add
/subsystem=undertow/server=default-server/host=app/filter-ref=x-powered-by-header:add
/subsystem=undertow/server=default-server/host=app/location="/":add (\handler=welcome-content)/subsystem=undertow/server=default-server/host=default-host/filter-ref=server-header:remove
/subsystem=undertow/server=default-server/host=default-host/filter-ref=x-powered-by-header:remove:reload/subsystem=undertow/server=default-server/host=default-host/location="/":remove/subsystem=undertow/server=default-server/host=default-host:remove/subsystem=undertow/server=default-server/host=segurnet/setting=single-sign-on:add(path="/"):reload
这将设置一个名为app
的虚拟主机,使其成为默认主机,删除Wildfly随附的默认主机并激活Single Sign On。
使用脚本和CLI可以很容易地从头启动新服务器。 您应该始终喜欢这种方式来更改服务器上的配置。
数据源
在JBoss 4.x中,设置数据源只需要您将数据库驱动程序复制到lib
文件夹,并使用数据源连接详细信息创建*-ds.xml
文件。
在Wildfly中 ,有些棘手,但没什么大不了的。 将数据源设置为模块,然后可以使用CLI将数据源连接详细信息添加到服务器配置中。 过去,我甚至写过一篇完整的博客文章: 使用Maven配置JBoss / Wildfly数据源 。
安全
JBoss 4.x中的安全性已在conf/login-config.xml
。 Wildfly并没有引入太多更改,但是如果您需要实现自定义登录模块,则依赖项会更改。 我还写了一个完整的博客文章: Wildfly的Custom Principal和LoginModule 。
JNDI绑定
在JBoss 4.x中通常使用@LocalBinding
为您的EJB定义确切的JNDI名称。 但是Java EE 7按作用域引入了标准JNDI名称,这意味着您应该遵循约定来查找EJB。
代替:
本地绑定
@Stateless
@Local(UserBusiness.class)
@LocalBinding(jndiBinding="custom/UserBusiness")
public class UserBusinessBean implements UserBusiness {}...private UserBusiness userBusiness;try {InitialContext context = new InitialContext();userBusiness = (UserBusiness) context.lookup("custom/userBusiness");
} catch(Exception e) {}
您可以:
EJB 3.1绑定
@EJB(lookup="java:global/app-name/app-service/UserBusinessBean")
private UserBusiness userBusiness;
当Wildfly启动时,您还可以在日志中检查标准绑定:
Wildfly JNDI标准绑定
java:global/segurnet/segurnet-protocol-gu-ejb/UserBusinessBean!com.criticalsoftware.segurnet.protocol.gu.ejb.business.UserBusinessjava:app/app-service/UserBusinessBean!com.app.business.UserBusinessjava:module/UserBusinessBean!com.app.business.UserBusinessjava:global/app-name/app-service/UserBusinessBeanjava:app/app-service/UserBusinessBeanjava:module/UserBusinessBean
其他的东西
这是我也写过博客文章的更具体的主题,可能也很有趣:
- Spring Batch作为Wildfly模块
- Wildfly,Apache CXF和@SchemaValidation
最后的话
如前所述,迁移永远不会遵循直接的路径。 不过,您可以做一些改进的事情。 编写测试,测试和测试。 我有告诉你写测试吗? 在进行任何迁移工作之前,请先执行此操作。 即使迁移的一切看起来都很好,您也可能会在不同版本的Java EE实现之间遇到轻微的行为更改。
另外,不要小看这项工作。 使您的应用程序与正在开发的新功能保持一致,以及更改服务器,需要您花费时间和精力来确保一切都不会中断。 除非我们谈论的是非常小的应用程序,否则肯定不会花1周的时间。 我们花了将近2年的时间才能将应用程序迁移到100万行以上。 但是,请谨慎对待这些数字。 这些非常取决于您的团队动态。
我的最终建议:如果您使用的是旧版Java EE版本,则一定要迁移。 在我的博客中了解有关从Java EE 5降级到7的Legacy的信息 。 跳跃并非易事,但是随着Java EE发行版的每个新版本以及对标准化的关注,每次升级都将减轻痛苦。
翻译自: https://www.javacodegeeks.com/2015/11/application-server-migration-jboss-ee5-to-wildfly-ee7.html
jboss4 迁移