dbunit2.4.9和poi3.9整合版本问题小述



        每次用开源的框架时,最蛋疼的不是业务逻辑如何如何复杂,而是痛苦的版本问题。开源的框架都不是不同的团队搞出来的东西,因此版本兼容做的不是很全面完善。可是作为一个小程序员也没有必要去指责框架的问题了,毕竟我们自己造轮子还是太费时,还有最重要的是水平达不到啊。在此就先发发牢骚了,下面切入正题了,相信用过unitils的朋友们都遇到过这个问题喽,截图如下:(此为dbunit2.4.9和poi3.9最新版本)

java.lang.NoSuchMethodError: org.apache.poi.hssf.usermodel.HSSFDateUtil.isCellDateFormatted(Lorg/apache/poi/hssf/usermodel/HSSFCell;)Z
	at org.dbunit.dataset.excel.XlsTable.getValue(XlsTable.java:153)
	at unitils.test.excel.MultiSchemaXlsDataSetReader$XlsTable.getValue(MultiSchemaXlsDataSetReader.java:114)
	at org.dbunit.operation.AbstractBatchOperation.isEmpty(AbstractBatchOperation.java:77)
	at org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:135)
	at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
	at org.unitils.dbunit.datasetloadstrategy.impl.CleanInsertLoadStrategy.doExecute(CleanInsertLoadStrategy.java:45)
	at org.unitils.dbunit.datasetloadstrategy.impl.BaseDataSetLoadStrategy.execute(BaseDataSetLoadStrategy.java:44)
	at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:230)
	at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:153)
	at org.unitils.dbunit.DbUnitModule$DbUnitListener.beforeTestSetUp(DbUnitModule.java:557)
	at org.unitils.core.Unitils$UnitilsTestListener.beforeTestSetUp(Unitils.java:273)
	at org.unitils.UnitilsJUnit4TestClassRunner$TestListenerInvokingMethodRoadie.runBeforesThenTestThenAfters(UnitilsJUnit4TestClassRunner.java:151)
	at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
	at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
	at org.unitils.UnitilsJUnit4TestClassRunner.invokeTestMethod(UnitilsJUnit4TestClassRunner.java:95)
	at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:61)
	at org.unitils.UnitilsJUnit4TestClassRunner.access$000(UnitilsJUnit4TestClassRunner.java:44)
	at org.unitils.UnitilsJUnit4TestClassRunner$1.run(UnitilsJUnit4TestClassRunner.java:62)
	at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
	at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
	at org.unitils.UnitilsJUnit4TestClassRunner.run(UnitilsJUnit4TestClassRunner.java:68)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

       这里总是提示NoSuchMethod这个问题,翻看dbunit的pom.xml文件发现他依赖的是poi3.2-FINAL版本,这个真是让人吐血啊,这个版本比较久了,虽然在spring中导出Excel视图我用的是poi3.9版本,这两个版本Cell的创建方式不同,但我还是为了解决它换了poi3.2-FINAL版本,期望问题得以解决。在满怀信心的点击了

Junit Test后我的心凉了,发现又会提示如下错误:

org.unitils.core.UnitilsException: Error inserting test data from DbUnit dataset for method public void unitils.test.impl.UserDaoTest.findUserByUserName()
	at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:156)
	at org.unitils.dbunit.DbUnitModule$DbUnitListener.beforeTestSetUp(DbUnitModule.java:557)
	at org.unitils.core.Unitils$UnitilsTestListener.beforeTestSetUp(Unitils.java:273)
	at org.unitils.UnitilsJUnit4TestClassRunner$TestListenerInvokingMethodRoadie.runBeforesThenTestThenAfters(UnitilsJUnit4TestClassRunner.java:151)
	at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
	at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
	at org.unitils.UnitilsJUnit4TestClassRunner.invokeTestMethod(UnitilsJUnit4TestClassRunner.java:95)
	at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:61)
	at org.unitils.UnitilsJUnit4TestClassRunner.access$000(UnitilsJUnit4TestClassRunner.java:44)
	at org.unitils.UnitilsJUnit4TestClassRunner$1.run(UnitilsJUnit4TestClassRunner.java:62)
	at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
	at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
	at org.unitils.UnitilsJUnit4TestClassRunner.run(UnitilsJUnit4TestClassRunner.java:68)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.unitils.core.UnitilsException: Error while executing DataSetLoadStrategy
	at org.unitils.dbunit.datasetloadstrategy.impl.BaseDataSetLoadStrategy.execute(BaseDataSetLoadStrategy.java:46)
	at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:230)
	at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:153)
	... 18 more
Caused by: org.dbunit.dataset.NoSuchColumnException: user.ID -  (Non-uppercase input column: id) in ColumnNameToIndexes cache map. Note that the map's column names are NOT case sensitive.
	at org.dbunit.dataset.AbstractTableMetaData.getColumnIndex(AbstractTableMetaData.java:117)
	at org.dbunit.operation.AbstractOperation.getOperationMetaData(AbstractOperation.java:89)
	at org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:140)
	at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79)
	at org.unitils.dbunit.datasetloadstrategy.impl.CleanInsertLoadStrategy.doExecute(CleanInsertLoadStrategy.java:45)
	at org.unitils.dbunit.datasetloadstrategy.impl.BaseDataSetLoadStrategy.execute(BaseDataSetLoadStrategy.java:44)
	... 20 more

       

        细看Caused by:是没有这列user.ID,google,度娘后发现只能是改源码或者把dbunit换成2.4.2版本。确实dbunit2.4.2和poi3.2-FINAL可以完美兼容,问题得以解决。可是我不甘心啊,为什么辛辛苦苦写的spring Excel View却要因为一个测试要从新更改为poi3.2的API,这是个不小的工程。于是我选择了暴力的手段,更改源码,google上说其实dbunit可以支持高版本的poi,就是要改pom文件,然后重新编译。

        在网上找到了dbunit2.4.9的源码包,更改poi的依赖改为如下:

 <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.9</version>
      <exclusions>
        <exclusion>
          <artifactId>log4j</artifactId>
          <groupId>log4j</groupId>
        </exclusion>
        <exclusion>
          <artifactId>commons-logging</artifactId>
          <groupId>commons-logging</groupId>
        </exclusion>
      </exclusions>
      <optional>true</optional>
    </dependency>

         

          这样源码再重新编译时用到的就是poi3.9的API了,dbunit就可以支持高版本的poi版本了。

          第一个问题得已解决了,第二个问题找不到***.ID是由于unitils和dbunit的版本不兼容的问题,因为unitils支持的dbunit是2.2.2。而unitils默认调用的是dbunit的DefaultMetadataHandler.class,需要把这个类更改为如下:

boolean areEqual = 
                areEqualIgnoreNull(table, tableName, caseSensitive) &&
                areEqualIgnoreNull(column, columnName, caseSensitive);
        return areEqual;

        这样第二个问题得以解决了,当然也得重新编译dbunit2.4.9喽,最后问题得以解决了。截图如下:

        下面我就献上我重新编译好的dbunit2.4.9jar文件和它的源码包,想自己编译就编译下好了,想用的就下载jar文件了。在此在说一句,在如此浩瀚的开源框架中何时才是个头啊,什么时候能用上自己的框架啊,哈哈哈。。。

猜你喜欢

转载自xiaozhiwz.iteye.com/blog/1942422
3.9