在可执行jar项目

时间:2018-01-10 05:02:46

标签: java spring spring-mvc jdbctemplate

我在runnable jar项目中配置JDBCTemplate时遇到错误。我正在创建一个基于弹簧的调度程序并遇到这个问题:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'EdockSchedularDAOImpl' defined in class path resource [spring.xml]: Cannot resolve reference to bean 'jdbcTemplate' while setting bean property 'jdbcTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdbcTemplate' defined in class path resource [spring.xml]: Cannot resolve reference to bean 'dataSource' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [spring.xml]: Invocation of init method failed; nested exception is javax.naming.NoInitialContextException: Failed to create InitialContext using factory specified in hashtable
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1469)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:762)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.ibm.main.EdockSchedularMain.main(EdockSchedularMain.java:23)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdbcTemplate' defined in class path resource [spring.xml]: Cannot resolve reference to bean 'dataSource' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [spring.xml]: Invocation of init method failed; nested exception is javax.naming.NoInitialContextException: Failed to create InitialContext using factory specified in hashtable
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:648)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:140)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1131)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1034)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
    ... 15 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [spring.xml]: Invocation of init method failed; nested exception is javax.naming.NoInitialContextException: Failed to create InitialContext using factory specified in hashtable
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1566)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
    ... 27 more
Caused by: javax.naming.NoInitialContextException: Failed to create InitialContext using factory specified in hashtable
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:242)
    at javax.naming.InitialContext.initializeDefaultInitCtx(InitialContext.java:318)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:348)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:428)
    at javax.naming.InitialContext.lookup(InitialContext.java:436)
    at org.springframework.jndi.JndiTemplate$1.doInContext(JndiTemplate.java:155)
    at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:87)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:152)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:179)
    at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:95)
    at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:106)
    at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:231)
    at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:217)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562)
    ... 34 more

这是我的主要课程

public class EdockSchedularMain {
    public static void main(String[] args) {
        ConfigurableApplicationContext  context = new ClassPathXmlApplicationContext("spring.xml");
        EdockSchedularDAO dao = (EdockSchedularDAO) context.getBean("EdockSchedularDAOImpl");
        context.close();
    }
}

这是我的spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:tx="http://www.springframework.org/schema/tx"
     xmlns:jdbc="http://www.springframework.org/schema/jdbc"
     xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
      http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
      http://www.springframework.org/schema/task
      http://www.springframework.org/schema/task/spring-task.xsd"
      default-autowire="byName">

    <context:component-scan base-package="com.sch"/>
    <bean id="EdockSchedularDAOImpl" class="com.sch.dao.EdockSchedularDAOImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate" />
    </bean>
    <bean id="jdbcTemplate" name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg>
            <ref bean="dataSource" />
        </constructor-arg>
    </bean>
    <bean name="dataSource" id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="jdbc/appDB" />
    </bean> 
    <bean id="scheduledTasks" class="com.schedular.EdockSchedular"/>
    <task:scheduler id="taskScheduler" pool-size="10"/>
    <task:scheduled-tasks>
        <task:scheduled ref="scheduledTasks" method="getDataFromDB" fixed-rate="10000"/>
    </task:scheduled-tasks>

</beans>

这是我的DAO课程

public class EdockSchedularDAOImpl implements EdockSchedularDAO{

    private JdbcTemplate jdbcTemplate;

    public List<EdockSchedularBean> getDataFromDB() {
        return null;
    }
    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
}

当我在RAD中运行主类时,我收到此错误。如果我从spring.xml和DAO类中删除JDBCTemplate映射,那么一切运行正常。有人请建议。

1 个答案:

答案 0 :(得分:0)

JNDI在像Tomcat这样的servlet容器中工作,它应该首先在容器的配置文件中声明,否则Spring无法创建数据源bean。

由于您正在运行没有容器的jar项目,因此可以使用Apache的commons-dbcp

首先,导入maven依赖

<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.2.2</version>
</dependency>

然后,在spring.xml中配置数据源

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
      destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3309/sampledb" />
    <property name="username" value="your username" />
    <property name="password" value="your password" />
</bean>