我在Spring上有一个应用程序,在JBOSS 7.1上运行数据库oracle。 我想测试我的服务层bean只是运行junit测试。 在我的春天上下文中,我使用像这样的jndi数据源:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jboss/datasources/myDatasource" />
<property name="resourceRef" value="true"/>
</bean>
当我运行加载spring上下文测试的junit测试时,我收到一个例外:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [context.xml]: Invocation of init method failed; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)
如何在我的测试中注入JNDI数据源而不更改jboss中的上下文?
答案 0 :(得分:5)
根据this帖子或this精彩博文,我找到了三种方法来解决我的问题,只需在JUnitTest类中创建BeforeClass方法。
我是为社区发布的:
- 解决方案1
这个解决方案需要catalina.jar和类路径中的oracledriver:
@BeforeClass
public static void setUpClass() throws Exception {
try {
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
InitialContext ic = new InitialContext();
ic.createSubcontext("jboss");
ic.createSubcontext("jboss/datasources");
ic.createSubcontext("jboss/datasources/myDatasource");
OracleConnectionPoolDataSource ds = new OracleConnectionPoolDataSource();
ds.setURL("jdbc:oracle:thin:@xxxxx:1521:xxxxx");
ds.setUser("myUserid");
ds.setPassword("myPass");
ic.rebind("jboss/datasources/myDatasource", ds);
} catch (NamingException ex) {
ex.printStackTrace();
}
}
如果你使用maven,你可以放入你的pom:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>catalina</artifactId>
<version>6.0.37</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3.0</version>
<scope>test</scope>
</dependency>
- 解决方案2
此解决方案需要在类路径中使用commons-dbcp:
@BeforeClass
public static void setUpDataSource() throws Exception {
try {
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
DriverAdapterCPDS cpds = new DriverAdapterCPDS();
cpds.setDriver("oracle.jdbc.OracleDriver");
cpds.setUrl("jdbc:oracle:thin:@xxxxx:1521:xxxxx");
cpds.setUser("myUsername");
cpds.setPassword("myPass");
SharedPoolDataSource dataSource = new SharedPoolDataSource();
dataSource.setConnectionPoolDataSource(cpds);
dataSource.setMaxActive(10);
dataSource.setMaxWait(50);
builder.bind("jboss/datasources/myDatasource", dataSource);
builder.activate();
} catch (NamingException ex) {
ex.printStackTrace();
}
}
在你的pom中:
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
- 解决方案3
此解决方案使用Oracle Driver中包含的OracleConnectionPoolDataSource:
@BeforeClass
public static void setUpDataSource() throws Exception {
try {
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
OracleConnectionPoolDataSource ds = new OracleConnectionPoolDataSource();
ds.setURL("jdbc:oracle:thin:@xxxxx:1521:xxxxx");
ds.setUser("myUsername");
ds.setPassword("myPass");
builder.bind("jboss/datasources/myDatasource", ds);
builder.activate();
} catch (NamingException ex) {
ex.printStackTrace();
}
}
答案 1 :(得分:0)
我的建议是将“基础架构”配置(DataSource
,PlatformTransactionManager
,...)分开,并仅在部署在WildFly中时使用JNDI / JTA,并使用不同的配置进行测试。您可以为此使用Spring条件bean,也可以以不同方式构建应用程序上下文。