JBoss作为JEE应用服务器以其EJB容器卓越的性能技术的潮流性开发部署JEE应用的方便性赢得了很多JEE开发者的信赖其中免安装基于JMX构架热部署(Hot Deploy)快速开发EJB应用等几项特征与其他商用服务器相比显得有些得意忘形的样子尽管其本身没有重大的缺陷但毕竟是Open Source的开发模式文档很少因此要很好的掌握精通开发基于JBoss的应用还是显得有些力不从心
本文结合作者的开发经验给出在JBoss 下开发JEE的一些很实用的相关的注意事项和规则其中读者一定要知道JBoss 作为JBoss的过渡产品(与JBoss xJBoss x相比)自然有些东西和JBoss xJBoss x有很大差别但是一般情况下本文介绍的内容大体上都适合JBoss各个版本
下载完JBoss 后解压到一个没有空格的目录路径下面就可以运行JBoss所以很方便但前提是目标机器安装了Java Standard Edition一切就绪后我们就开始吧(假设JBoss 安装在C:\jboss_tomcat本使用default配置)
一相关配置文件的设置
为开发JEE应用操作数据库成了必不可少的内容调节日志输出的详细程度成了调试JEE应用的关键EJB应用的调优过程是JEE应用的核心
数据源的配置
在JBoss 中配置数据源的步骤很简单JBoss 本身带了主流数据库的配置实例于目录下C:\jboss_tomcat\docs\examples\jca具体使用哪个配置文件取决于目标用户的数据库如果是SQL Server 则需要使用mssqldsxml文件(支持本地事务)或者mssqlxadsxml文件(支持全局事务)如果是Oracle i数据库则需要使用oracledsxml文件或者oraclexadsxml文件等这里以SQL Server 为例
首先将mssqldsxml文件拷贝到目录C:\jboss_tomcat\server\default\deploy下然后打开文件并作如下修改
<datasources>
<localtxdatasource>
<jndiname>VSSDB</jndiname>
<connectionurl>jdbc:microsoft:sqlserver://:;DatabaseName=DDD
</connectionurl>
<driverclass>commicrosoftjdbcsqlserverSQLServerDriver</driverclass>
<username>sa</username>
<password>sa</password>
<minpoolsize></minpoolsize>
<maxpoolsize></maxpoolsize>
</localtxdatasource>
</datasources>
如果目标JEE应用只需要本地事务则上述过程已经完成了Datasource的配置同时这个配置将用于JDBC以及EJB通过JNDI使用如果要实现EJB使用Datasource则还需要修改位于目录C:\jboss_tomcat\server\default\conf下的standardjbosscmpjdbcxml文件比如
<jbosscmpjdbc>
<defaults>
<datasource>java:/VSSDB</datasource>
<datasourcemapping>MS SQLSERVER</datasourcemapping>
<createtable>true</createtable>
<removetable>false</removetable>
<readonly>false</readonly>
<timeout></timeout>
<pkconstraint>true</pkconstraint>
<fkconstraint>false</fkconstraint>
其中java:/VSSDB中的VSSDB就是mssqldsxml配置的数据源而java:/前缀表明该命名空间只是对JBoss本身可见即运行于JBoss外的应用是不能够使用这里定义的数据源这一点希望注意
其次MS SQLSERVER中的MS SQLSERVER可以在该文件的其他地方找到(如果是其他数据库情况都是类似的)
日志的输出详细程度配置
由于JBoss 开发采用了Logj管理其日志信息(严格地讲它扩展了Logj)因此了解Logj的机理有助于理解JBoss 管理日志的方式JBoss 采用JMX架构的同时且以xml文件类型为配置文件因此可以找到位于目录C:\jboss_tomcat\server\default\conf下的logjxml文件比如其中一段配置示例如下
<appender name=CONSOLE class=orgapachelogjConsoleAppender>
<param name=Target value=Systemout/>
<param name=Threshold value=INFO/>
<layout class=orgapachelogjPatternLayout>
<! The default pattern: Date Priority [Category] Message\n >
<param name=ConversionPattern value=%d{ABSOLUTE} %p [%c{}] %m%n/>
</layout>
</appender>
比如为了调节JBoss 控制台日志输出的详细程度(调整为DEBUG级别)我们需要修改value=INFO将INFO改为DEBUG 如果开发Entity Beans可以调节位于与logjxml文件同一目录下的standardjbossxml文件(该文件主要是提供修改EJB相关的调试运行调优部署参数)如果Entity Beans采用的为Standard CMP x EntityBean则将其中的属性的取值改为true
<containerconfiguration>
<containername>Standard CMP x EntityBean</containername>
<calllogging>false</calllogging>
<invokerproxybindingname>entityrmiinvoker</invokerproxybindingname>
<synconcommitonly>false</synconcommitonly>
完成上述两步后在调试Entity Beans时通过控制台可以看到Entity Beans发出的JDBC调用细节
Tomcat容器相关参数的配置
如果使用JBoss 与Tomcat 的集成版本则可以通过调节分别位于目录C:\jboss_tomcat\server\default\deploy\jbosswebtomcatsar下的webxml和目录C:\jboss_tomcat\server\default\deploy\jbosswebtomcatsar\METAINF下的jbossservicexml文件来达到目标读者特定需求比如如果想将HTTP服务端口改为则可以修改jbossservicexml文件如果想使目标JEE应用处理更多的文件类型可以修改webxml文件
相关类库的放置
如果应用涉及到第三方类库比如JDBC Driver则可以将这些JDBC Driver存放到目录下C:\jboss_tomcat\server\default\lib注意不是目录C:\jboss_tomcat\lib下
如果是与目标JEE应用相关则可以存放到目标war(或者ear)里面或者xxxwar目录中的WEBINFO\lib下无论那种情形都需要遵循JEE规范当然JBoss 的配置文件有很多比如还有提供邮件服务的mailservicexml文件等
二开发EJB应用
如果开发EJB应用建议采用JBoss作为开发服务器因为开发调试部署速度快如果采用其他商用服务器由于实现机理的不同其编译的速度很慢如果采用Entity Beans技术则您需要知道这几点第一您目标系统的数据源有多少个操作入口即是否存在Entity Beans之外的方式来操作数据库如果有则需要调节相应的提交策略以及策略
比如JBoss 采用的方式有种ABCD当然如果除了Entity Beans访问数据库外别无它出采用A是很理智的如果有则需要取决于具体的情况使用方式同时方式的选择与策略有关系能够采用的Entity Beans或Entity Beans Methods则尽量采用这样会减少或消除死锁发生的可能性尽量采用:n的关系来操作n方的数据表结构这样能够提高EJB Container的效率
一般情况下JEE应用服务器支持JDBC事务JTA事务容器管理事务同时最好不要在程序中同时使用上述三种事务类型比如在JTA事务中嵌套JDBC事务第二方面事务要在尽可能短的时间内完成不要在不同方法中实现事务的使用比如下面给出了回滚JDBC事务的代码示例
public void processT(String orders) {
Context initCtx = new InitialContext();
javaxsqlDataSource ds = javaxsqlDataSource)initCtxlookup
(java:comp/env/jdbc/OrdersDB);
javasqlConnection conn = dsgetConnection();
try{
connsetAutoCommit( false ); //更改JDBC事务的默认提交方式
orderNo = createOrder( orders );
updateOrderStatus(orderNo orders created);
mit();//提交JDBC事务
}catch( Exception e ){
try{
connrollback();//回滚sJDBC事务
throw new EJBException(事务回滚 + egetMessage());
}catch( SQLException sqle ){
throw new EJBException(出现SQL操作错误 + sqlegetMessage());
}
}
}
下面给出了JTA事务代码示例
public void processOrder(String orderMessage) {
UserTransaction transaction = mySessionContextgetUserTransaction();//获得JTA事务
try{
transactionbegin();//开始JTA事务
orderNo = sendOrder(orderMessage);
updateOrderStatus(orderNo order sent);
mit();//提交JTA事务
}catch(Exception e){
try{
transactio