无法使用JNDI数据源在JUnit中加载ApplicationContext(Failed to load ApplicationContext in JUnit with JNDI datasource)
我在测试我的应用程序时遇到了一些麻烦,而在正常执行中它运行良好。 我认为它来自未找到的JNDI资源,但我不明白为什么以及如何解决它。
当我开始我的Junit测试时,我收到了这个错误:
java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99) at ... Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'DAOImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource com.sample.DAOImpl.myDatasource; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=myDatasource)} Related cause: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myDatasource' defined in URL [file:src/test/resources/spring/test-dao-config.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.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288) at ... Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource com.sample.DAOImpl.myDatasource; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=myDatasource)} at ... Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=myDatasource)} at ..
这是我的配置:
的context.xml
<Resource name="jdbc/myDatasource" auth="Container" type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@database:99999:instance" username="user" password="password" validationQuery="select 1 from dual" testOnBorrow ="true" maxActive="5" maxIdle="1" maxWait="-1" />
测试的DAO-config.xml中
<bean id="myDatasource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/jdbc/myDatasource" /> </bean>
DaoImpl
@Repository public class DacsDAOImpl implements DacsDAO { private final static Logger LOGGER = LoggerFactory.getLogger(DAOImpl.class); @Autowired @Qualifier("myDatasource") private DataSource myDatasource; .... }
而我的测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "file:src/test/resources/spring/test-dao-config.xml" }) public class MyDAOImplTest { private MyDAO dao; @BeforeClass public static void initJndi() throws IllegalStateException, NamingException { //some test, but doesn't work // SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder(); // builder.bind("java:comp/env/jdbc/myDatasource", "myDatasource"); // builder.activate(); } @Before public void setUp() throws IllegalStateException, NamingException { dao = new MyDAOImpl(); } @Test public void testTotalUser() { int result = dao.getTotalUser(); Assert.assertEquals(0, result); } }
谢谢
I have some troubles testing my application, whereas it works well in normal execution. I think it comes from JNDI resources which are not found, but I don't understand why and how to fix it.
When I start my Junit test, I got this error:
java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99) at ... Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'DAOImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource com.sample.DAOImpl.myDatasource; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=myDatasource)} Related cause: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myDatasource' defined in URL [file:src/test/resources/spring/test-dao-config.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.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288) at ... Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource com.sample.DAOImpl.myDatasource; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=myDatasource)} at ... Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=myDatasource)} at ..
Here is my configuration:
Context.xml
<Resource name="jdbc/myDatasource" auth="Container" type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@database:99999:instance" username="user" password="password" validationQuery="select 1 from dual" testOnBorrow ="true" maxActive="5" maxIdle="1" maxWait="-1" />
test-dao-config.xml
<bean id="myDatasource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/jdbc/myDatasource" /> </bean>
DaoImpl
@Repository public class DacsDAOImpl implements DacsDAO { private final static Logger LOGGER = LoggerFactory.getLogger(DAOImpl.class); @Autowired @Qualifier("myDatasource") private DataSource myDatasource; .... }
And my tests
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "file:src/test/resources/spring/test-dao-config.xml" }) public class MyDAOImplTest { private MyDAO dao; @BeforeClass public static void initJndi() throws IllegalStateException, NamingException { //some test, but doesn't work // SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder(); // builder.bind("java:comp/env/jdbc/myDatasource", "myDatasource"); // builder.activate(); } @Before public void setUp() throws IllegalStateException, NamingException { dao = new MyDAOImpl(); } @Test public void testTotalUser() { int result = dao.getTotalUser(); Assert.assertEquals(0, result); } }
Thanks
原文:https://stackoverflow.com/questions/22461501
最满意答案
请试试我的代码? 它有效,我认为它与你的代码是一样的。
#include <stdio.h> #include <stdbool.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <time.h> #include <pthread.h> #include <netinet/in.h> #include <arpa/inet.h> #include <net/if.h> #include <netdb.h> #define INVALID_SOCKET_FD (-1) int create_tcp_server_socket(unsigned short port, bool bind_local, int backlog, char *caller_name) { int socket_fd = INVALID_SOCKET_FD; struct sockaddr_storage server_addr; unsigned int yes = 1; // just try ipv4 if (socket_fd < 0 && (socket_fd = socket(PF_INET, SOCK_STREAM, 0)) >= 0) { struct sockaddr_in *s4 = (struct sockaddr_in *)&server_addr; setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); memset(&server_addr, 0, sizeof(server_addr)); s4->sin_family = AF_INET; s4->sin_port = htons(port); if (bind_local) s4->sin_addr.s_addr = htonl(INADDR_LOOPBACK); else s4->sin_addr.s_addr = htonl(INADDR_ANY); if (bind(socket_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { close(socket_fd); printf("Server: Failed to bind ipv4 server socket.\n"); return INVALID_SOCKET_FD; } } else if (socket_fd < 0) { printf("Server: Failed to create server socket.\n"); return INVALID_SOCKET_FD; } if (listen(socket_fd, backlog) < 0) { close(socket_fd); printf("Server: Failed to set listen.\n"); return INVALID_SOCKET_FD; } return socket_fd; } pthread_t temp; void *number_two(void *sock) { char buf[1024]; int fd = *(int *)sock; int nread = read(fd, buf, 1024); write(STDOUT_FILENO, buf, nread); return NULL; } int main() { pid_t pid; if ((pid = fork()) < 0) { } else if (pid > 0) { // parent, server char buf[1024]; int fd = create_tcp_server_socket(8787, false, 10, "zz"); int new_fd = accept(fd, NULL, 0); pthread_create(&temp, NULL, number_two, (void *)&new_fd); } else { // child, client uint32_t ip; struct hostent *hp = gethostbyname("localhost"); memcpy(&ip, hp->h_addr_list[0], hp->h_length); struct sockaddr_in server_addr; memset((char *)&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = ip; server_addr.sin_port = htons(8787); int fd = socket(AF_INET, SOCK_STREAM, 0); connect(fd, (struct sockaddr *)&server_addr, sizeof(server_addr)); write(fd, "abcd", 4); } pause(); return 0; }
Please try my code? it works, I think it is the same with your code.
#include <stdio.h> #include <stdbool.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <time.h> #include <pthread.h> #include <netinet/in.h> #include <arpa/inet.h> #include <net/if.h> #include <netdb.h> #define INVALID_SOCKET_FD (-1) int create_tcp_server_socket(unsigned short port, bool bind_local, int backlog, char *caller_name) { int socket_fd = INVALID_SOCKET_FD; struct sockaddr_storage server_addr; unsigned int yes = 1; // just try ipv4 if (socket_fd < 0 && (socket_fd = socket(PF_INET, SOCK_STREAM, 0)) >= 0) { struct sockaddr_in *s4 = (struct sockaddr_in *)&server_addr; setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)); memset(&server_addr, 0, sizeof(server_addr)); s4->sin_family = AF_INET; s4->sin_port = htons(port); if (bind_local) s4->sin_addr.s_addr = htonl(INADDR_LOOPBACK); else s4->sin_addr.s_addr = htonl(INADDR_ANY); if (bind(socket_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { close(socket_fd); printf("Server: Failed to bind ipv4 server socket.\n"); return INVALID_SOCKET_FD; } } else if (socket_fd < 0) { printf("Server: Failed to create server socket.\n"); return INVALID_SOCKET_FD; } if (listen(socket_fd, backlog) < 0) { close(socket_fd); printf("Server: Failed to set listen.\n"); return INVALID_SOCKET_FD; } return socket_fd; } pthread_t temp; void *number_two(void *sock) { char buf[1024]; int fd = *(int *)sock; int nread = read(fd, buf, 1024); write(STDOUT_FILENO, buf, nread); return NULL; } int main() { pid_t pid; if ((pid = fork()) < 0) { } else if (pid > 0) { // parent, server char buf[1024]; int fd = create_tcp_server_socket(8787, false, 10, "zz"); int new_fd = accept(fd, NULL, 0); pthread_create(&temp, NULL, number_two, (void *)&new_fd); } else { // child, client uint32_t ip; struct hostent *hp = gethostbyname("localhost"); memcpy(&ip, hp->h_addr_list[0], hp->h_length); struct sockaddr_in server_addr; memset((char *)&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = ip; server_addr.sin_port = htons(8787); int fd = socket(AF_INET, SOCK_STREAM, 0); connect(fd, (struct sockaddr *)&server_addr, sizeof(server_addr)); write(fd, "abcd", 4); } pause(); return 0; }
相关问答
更多-
在C中使用pthread?(using pthread in C?)[2023-08-08]
目前尚不清楚为什么每隔10秒创建一个新线程而不是让原始线程继续。 由于原始线程退出,您不是直接累积线程,而是您不等待它们中的任何一个,因此有一些资源未发布。 你也不是错误检查,所以你不知道什么时候出错了; 监控将停止。 你最终会以某种方式耗尽空间。 你有几个选择。 不要每10秒创建一个新线程。 通过在soilMoisture()函数中循环来保持线程运行,并取消funct() - 或者至少调用pthread_create() 。 如果必须创建新线程,请将它们分离。 当pthread_attr_t不为NULL时 ... -
重用线程pthread(Reuse of threads pthread)[2022-10-25]
只需对线程进行编码即可完成任何需要完成的工作。 不要继续创建和加入线程。 最简单的方法是使用线程池 - 一组线程和一个线程安全的作业队列。 池中的每个线程都从队列中取出作业,完成该作业,然后等待另一个作业。 使用POSIX线程时,通常使用互斥锁来保护队列和条件变量,以允许线程等待工作。 您可能需要一个布尔变量来跟踪程序是否正在关闭。 在伪代码中,每个线程都这样做: 获取互斥量。 检查程序是否正在关闭,如果是,释放互斥并终止。 检查队列是否为空。 如果是这样,请阻止条件变量并转到步骤2。 从队列中挑选最重要的 ... -
您遇到未定义的行为,因为您在未以'\ 0'结尾的字符串上调用strlen 。 recv不会在字符串的末尾放置一个null终止符。 char *message , client_message[2000]; //... //Receive a message from client while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 ) { //Send the message back to client write(sock , ...
-
这不是我所看到的......请注意,EPERM是T2应该返回的,而不是T1。 而且,如果你以递归方式锁定相同的互斥锁,那么EDEADLK就是T1应该返回的内容。 这是我用来测试的代码: #include
#include #include #include #include pthread_mutex_t m; sem_t s1, s2; void print(const char *s, ... -
请试试我的代码? 它有效,我认为它与你的代码是一样的。 #include
#include #include #include #include #include #include #include #include #include #include #de ... -
Pthread锁定(Pthread locking)[2024-03-31]
原因是当线程等待条件变量时,互斥锁被解锁。 这是预期的行为。 当条件变量发出信号时,线程不会被释放以运行,直到重新获取锁定为止。 如果您将功能更改为: Work* WorkHandler::getWork(){ // Remoed this as it is non-determinstic when it will be printed. lock(); printf("WorkHandler::getWork locked\n"); while(m_workQ ... -
跟踪pthread(Keep track of pthread)[2022-04-13]
线程的整个标识位于pthread_t 初始化线程会将其pthread_t类型ID返回给其父节点 每个线程都可以使用pthread_self()获取自己的ID 您可以使用以下函数比较线程ID: int pthread_equal (pthread_t, pthread_t) 因此:维护一个通用数据结构,您可以使用pthread_t ID和pthread_equal比较函数将线程状态存储为STARTED,RUNNING,FINISHED,以区分线程。 父项在启动线程时将值设置为STARTED,线程本身将自己的状 ... -
你给每个线程一个指向局部变量i的指针。 随着每次循环迭代, i正在改变 - 并且当线程实际启动并且完成就绪循环时,并且i等于5(最后一个值)。 然而,这只是众多潜在结果中的一个。 您的线程ID确实可以读取任何内容,因为您在此代码中有经典的数据竞争。 您正在从多个线程访问变量,该变量不受任何方式的保护。 如果运气好的话,甚至可以阅读42。 解。 为每个线程动态创建一个新变量并传递该变量的地址(您需要在线程中删除以防止内存泄漏),或者将整数变量转换为指针并将此值提供给线程。 为了(稍微)可移植地执行此操作,您的 ...
-
你必须确保一个线程不可能访问一个对象,而另一个线程可能正在修改它。 你没有这样做,所以结果是不可预测的。 一种解决方案是在查看它们设置的值之前,在所有线程上调用pthread_join 。 You must ensure that it is impossible for one thread to access an object while another thread might be modifying it. You have not done this, so the results are u ...
-
我刚刚找到了解决方案。 我在Makefile中做了一些更改,我发现我确实错过了-pthread选项。 真的很奇怪,没有错误消息,并且根本没有创建线程。 非常感谢您的帮助! 对此,我真的非常感激。 I just found the solution. I did some changes in the Makefile and I found out that I really missed the -pthread option. It is really weird that there were no ...