单元测试从JBoss 6.4迁移至7.1遇javax.naming.CommunicationException
问题概述
原在JBoss 6.4环境正常运行的EJB测试类,迁移至JBoss 7.1后执行JNDI lookup操作时,出现连接超时错误:
javax.naming.CommunicationException: Failed to connect to any server. Servers tried: [http-remoting://127.0.0.1:4447 (Operation failed with status WAITING after 5000 MILLISECONDS)] [Root exception is java.net.ConnectException: Operation failed with status WAITING after 5000 MILLISECONDS]
已尝试修改PROVIDER_URL为remote://localhost:4447、http-remoting://localhost:4447,并添加安全凭证,但问题未解决。
原有依赖与代码
POM依赖
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>jboss</groupId> <artifactId>jboss-client</artifactId> <version>4.0.2</version> </dependency> <dependency> <groupId>org.jboss</groupId> <artifactId>jboss-remote-naming</artifactId> <version>2.0.4.Final</version> </dependency> <dependency> <groupId>org.jboss.logmanager</groupId> <artifactId>jboss-logmanager</artifactId> <version>2.1.18.Final</version> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.xnio</groupId> <artifactId>xnio-nio</artifactId> <version>3.4.6.Final</version> </dependency> </dependencies>
核心代码
protected static Context namingContext; protected static EjbCallerContext ejbCtx = null; protected static final String BASE_URL = "http//localhost:8080"; protected static final String PROVIDER_URL = "http-remoting://127.0.0.1:4447"; protected static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory"; protected static Properties crProperties() { Properties jndiProperties = new Properties(); jndiProperties.put("jboss.naming.client.ejb.context", true); jndiProperties.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, PROVIDER_URL)); jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY); } public static void crProperties() throws NamingException { Properties pp = getPpProperties(); namingContext = new InitialContext(pp); ejbCtx = new EjbCallerContext("prova", "prova"); } // EJB lookup代码 private static final String REMOTE_JNDI_NAME = "ProvaEjb!ejb.ProvaeInterface"; ProvaInterface= (ProvaInterface) namingContext.lookup(REMOTE_JNDI_NAME);
解决方案
1. 更新客户端依赖版本
JBoss 7.1与6.4的客户端依赖不兼容,需替换为适配7.1的版本:
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- 导入JBoss EJB客户端BOM统一管理版本 --> <dependency> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-ejb-client-bom</artifactId> <version>7.1.1.Final</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.jboss.ejb-client</groupId> <artifactId>jboss-ejb-client</artifactId> <version>1.0.5.Final</version> </dependency> <dependency> <groupId>org.jboss.remote-naming</groupId> <artifactId>jboss-remote-naming</artifactId> <version>1.0.7.Final</version> </dependency> <dependency> <groupId>org.jboss.xnio</groupId> <artifactId>xnio-api</artifactId> <version>3.0.7.GA</version> </dependency> <dependency> <groupId>org.jboss.xnio</groupId> <artifactId>xnio-nio</artifactId> <version>3.0.7.GA</version> </dependency> <dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> <version>3.1.2.GA</version> </dependency> </dependencies>
2. 修正远程连接端口
JBoss 7.1默认http-remoting端口为8080(6.4为4447),需调整PROVIDER_URL:
protected static final String PROVIDER_URL = "http-remoting://127.0.0.1:8080";
若使用传统remote协议,默认端口仍为4447,但需确保JBoss配置中开启对应连接器。
3. 完善JNDI初始化属性
补充缺失的return语句,并正确配置安全凭证与超时:
protected static Properties crProperties() { Properties jndiProperties = new Properties(); jndiProperties.put("jboss.naming.client.ejb.context", true); jndiProperties.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, PROVIDER_URL)); jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory"); // 配置安全凭证(需与JBoss中创建的用户一致) jndiProperties.put(Context.SECURITY_PRINCIPAL, "prova"); jndiProperties.put(Context.SECURITY_CREDENTIALS, "prova"); // 设置连接超时,避免短时间内超时 jndiProperties.put("jboss.naming.client.connect.timeout", "10000"); return jndiProperties; }
4. 调整EJB JNDI名称格式
JBoss 7.1远程EJNDI名称需包含应用/模块信息,格式为:[应用名称]/[模块名称]/[EJB类名]![全限定接口名]
示例:
private static final String REMOTE_JNDI_NAME = "MyApp/MyModule/ProvaEjb!ejb.ProvaInterface";
若为独立WAR包部署,可简化为ProvaEjb!ejb.ProvaInterface(需确认模块名与部署包一致)。
5. 配置JBoss安全权限
- 在JBoss bin目录执行
add-user.sh(Windows为add-user.bat),创建Application User,关联ejb-remote角色。 - 确认
standalone.xml中开启远程连接器配置:
<subsystem xmlns="urn:jboss:domain:ejb3:1.2"> <remote connector-ref="remoting-connector" thread-pool-name="default"/> </subsystem> <subsystem xmlns="urn:jboss:domain:remoting:1.1"> <connector name="remoting-connector" socket-binding="remoting"/> </subsystem>
6. 网络连通性排查
- 确认JBoss 7.1服务正常启动,端口8080/4447未被占用。
- 使用
telnet 127.0.0.1 8080测试端口连通性,确保无防火墙拦截。
内容的提问来源于stack exchange,提问作者user21126632

