项目第一次使用SSH,于是准备先做个Demo出来,就是想实现用户注册和登录,可是在持久化时就是遇到了问题。
这个问题困扰了我和跟我pair的兄弟一天了,试验了几种方法,代码和Spring开发参考手册上的基本上一样,也用过其他人的方法,别人的程序在我的环境下没有问题,仿照他们的代码自己编一个就不行,几种方法的共性问题是:
java.lang.NoSuchMethodError: org.springframework.util.ClassUtils.isPresent(Ljava/lang/String;)Z
不同的方法会有不同的错误呈现,然而总是会出现这句话。
我使用MyEclipse5.1的add spring capabilities和add hibernate capabilities自动生成的POJO和mapping文件,一切顺利,如下所示:
- default package
- /**
- * User generated by MyEclipse - Hibernate Tools
- */
- public class User implements java.io.Serializable {
- // Fields
- private String userID;
- private String userName;
- private String password;
- // Constructors
- /** default constructor */
- public User() {
- }
- /** full constructor */
- public User(String userID, String userName, String password) {
- this.userID = userID;
- this.userName = userName;
- this.password = password;
- }
- // Property accessors
- //省略存取器方法
- }
- // default package
- import java.util.List;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.hibernate.LockMode;
- import org.springframework.context.ApplicationContext;
- import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
- /**
- * Data access object (DAO) for domain model class User.
- * @see .User
- * @author MyEclipse - Hibernate Tools
- */
- public class UserDAO extends HibernateDaoSupport {
- private static final Log log = LogFactory.getLog(UserDAO.class);
- protected void initDao() {
- //do nothing
- }
- public void save(User transientInstance) {
- log.debug("saving User instance");
- try {
- getHibernateTemplate().save(transientInstance);
- log.debug("save successful");
- } catch (RuntimeException re) {
- log.error("save failed", re);
- throw re;
- }
- public static UserDAO getFromApplicationContext(ApplicationContext ctx) {
- return (UserDAO) ctx.getBean("UserDAO");
- }
- }
之后是配置文件:hibernate.cfg.xml
- <?xml version='1.0' encoding='UTF-8'?>
- <!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
- <!-- Generated by MyEclipse Hibernate Tools. -->
- <hibernate-configuration>
- <session-factory>
- <property name="connection.username">SOMIS</property>
- <property name="connection.url">
- jdbc:oracle:thin:@127.0.0.1:1521:ORA92
- </property>
- <property name="dialect">
- org.hibernate.dialect.Oracle9Dialect
- </property>
- <property name="myeclipse.connection.profile">SOMIS</property>
- <property name="connection.password">ss</property>
- <property name="connection.driver_class">
- oracle.jdbc.driver.OracleDriver
- </property>
- <mapping resource="User.hbm.xml" />
- </session-factory>
- </hibernate-configuration>
spring的配置文件,applicationContext.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
- <beans>
- <bean id="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <property name="configLocation">
- <value>file:src/hibernate.cfg.xml</value>
- </property>
- </bean>
- <bean id="UserDAO" class="UserDAO">
- <property name="sessionFactory">
- <ref bean="sessionFactory" />
- </property>
- </bean>
- </beans>
以下是测试代码:
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import junit.framework.TestCase;
- public class UserDAOTest extends TestCase {
- public void testSave() {
- ApplicationContext ctx = new ClassPathXmlApplicationContext( new
- String[] { "applicationContext.xml" });
- UserDAO userDAO=UserDAO.getFromApplicationContext(ctx);
- User user=new User();
- user.setPassword("123");
- user.setUserID("1");
- user.setUserName("admin");
- userDAO.save(user);
- }
- }
这时测试可以通过(使用Spring自带的测试类也测试过)。
然后在配置文件中加入声明式事务处理,测试就通不过了。
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
- <beans>
- <bean id="sessionFactory"
- class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
- <property name="configLocation">
- <value>file:src/hibernate.cfg.xml</value>
- </property>
- </bean>
- <bean id="UserDAO" class="UserDAO">
- <property name="sessionFactory">
- <ref bean="sessionFactory" />
- </property>
- </bean>
- <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
- <property name="sessionFactory"><ref bean="sessionFactory"/></property>
- </bean>
- <bean id="userDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
- <property name="transactionManager" >
- <ref bean="transactionManager"/>
- </property>
- <property name="target">
- <ref bean="UserDAO"/>
- </property>
- <property name="transactionAttributes">
- <props>
- <prop key="save">PROPAGATION_REQUIRED</prop>
- </props>
- </property>
- </bean>
- </beans>
这是很平常的写法了,可是就是不知道为什么会报下面的错误:
- org.springframework.beans.factory.BeanCreationException: Error
- creating bean with name 'userDAOProxy' defined in class path
- resource [applicationContext.xml]: Instantiation of bean failed;
- nested exception is org.springframework.beans.BeanInstantiationException:
- Could not instantiate bean class [org.springframework.transaction.interceptor.TransactionProxyFactoryBean]:
- Constructor threw exception; nested exception is java.lang.NoSuchMethodError:
- org.springframework.util.ClassUtils.isPresent(Ljava/lang/String;)Z
- org.springframework.beans.BeanInstantiationException:
- Could not instantiate bean class [org.springframework.transaction.interceptor.TransactionProxyFactoryBean]:
- Constructor threw exception; nested exception is java.lang.NoSuchMethodError:
- org.springframework.util.ClassUtils.isPresent(Ljava/lang/String;)Z
- java.lang.NoSuchMethodError: org.springframework.util.ClassUtils.isPresent(Ljava/lang/String;)Z
- at org.springframework.aop.framework.DefaultAopProxyFactory.<clinit>(DefaultAopProxyFactory.java:56)
- at org.springframework.aop.framework.ProxyConfig.<init>(ProxyConfig.java:63)
- at org.springframework.aop.framework.AbstractSingletonProxyFactoryBean.<init>(AbstractSingletonProxyFactoryBean.java:39)
- at org.springframework.transaction.interceptor.TransactionProxyFactoryBean.<init>(TransactionProxyFactoryBean.java:105)
- at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
- at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
- at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
- at java.lang.reflect.Constructor.newInstance(Unknown Source)
- at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:171)
- at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
- at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:52)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:486)
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:362)
- at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:233)
- at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:145)
- at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:277)
- at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:313)
- at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:87)
- at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:72)
- at UserDAOTest.testSave(UserDAOTest.java:11)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
- at java.lang.reflect.Method.invoke(Unknown Source)
- at junit.framework.TestCase.runTest(TestCase.java:154)
- at junit.framework.TestCase.runBare(TestCase.java:127)
- at junit.framework.TestResult$1.protect(TestResult.java:106)
- at junit.framework.TestResult.runProtected(TestResult.java:124)
- at junit.framework.TestResult.run(TestResult.java:109)
- at junit.framework.TestCase.run(TestCase.java:118)
- at junit.framework.TestSuite.runTest(TestSuite.java:208)
- at junit.framework.TestSuite.run(TestSuite.java:203)
- at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
- at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
- at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
- at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
- at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
- at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
后来我又使用了编程式事务处理,直接报错就是
java.lang.NoSuchMethodError: org.springframework.util.ClassUtils.isPresent(Ljava/lang/String;)Z
使用声明式事务处理也试过下面的代码:
- <!--事务拦截器,激活事务管理器所必须的bean-->
- <bean id="transactionInterceptor"
- class="org.springframework.transaction.interceptor.TransactionInterceptor">
- <!-- 事务拦截器bean需要依赖注入一个事务管理器 -->
- <property name="transactionManager" ref="transactionManager"/>
- <property name="transactionAttributes">
- <!-- 下面定义事务传播属性-->
- <props>
- <!--PROPAGATION_REQUIRE规则表示:在bean中所有以get开头的方法,当抛出异
- 常时,自动回滚,并只读,其他异常自动回滚-->
- <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
- <prop key="*">PROPAGATION_REQUIRED</prop>
- </props>
- </property>
- </bean>
- <!--定义事务处理代理bean,他需要两个属性,一个是指定需要代理的bean,另一个是代理bean所需的
- 事务拦截器-->
- <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
- <!-- 指定对满足哪些bean name的bean自动生成业务代理 -->
- <property name="beanNames">
- <!-- 下面是所有需要自动创建事务代理的bean-->
- <list>
- <value>UserDAO</value>
- </list>
- <!-- 此处可增加其他需要自动创建事务代理的bean-->
- </property>
- <!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器-->
- <property name="interceptorNames">
- <list>
- <!-- 此处可增加其他新的Interceptor -->
- <value>transactionInterceptor</value>
- </list>
- </property>
- </bean>
依然报错,不知道怎么办了。
在Google,百度,Yahoo都搜过了,有位仁兄说了句Debug找错就完了。
对了,MyEclipse自动加入的spring1.2的包里 org.springframework.util.ClassUtils真的没有isPresent方法,可是我加了spring2.0的包,还是不行。
我是束手无策了,使用的最简单的方法(网上,书上,Rod Johnson的两本,再加上各种国内的技术书都看遍了,都使用这种方法),就这么几个文件,真的不知道怎么办了,望~