NullPointer trying to rollback changelist

I have some test cases that I use in a presentation I am giving that were using liquibase 1.9.5.  I decided that I would try to update them to the 2.0-rc6 code so that when I next give the presentation (in January 2011) I will be using the most up-to-date version of liquibase.

I changed the Liquibase construction to use the ResourceAccessor abstraction instead of the FileOpener abstractions, and made sure that I’m using a JdbcConnection to talk to a mysql database running on my workstation.

I am using Spring’s Junit 4 integration to run a junit test that creates some table structure in a @Before method using the liquibase.Liquibase object, and then uses that same object in an @After method to rollback the table structure created in the @Before.

When I run my test, the test does what is supposed to, and all of the assertions pass.  Then in the @After method when the Liquibase object attempts to rollback the changelist, we get a null pointer and blow up.  The NullPointer occurs in ChangeSet, line 308 where it is checking the execType of the ranChangeSet to see if it has been EXECUTED or RERAN.  Unfortunately at this time, the execType is null, so the rollback blows up.

I have attached my dao class, unit test class, as well as my spring configuration file, and my liquibase change set for debugging purposes.  Here is the relevant stack trace from my test run.

Oct 29, 2010 12:11:46 PM liquibase.logging.jvm.JavaUtilLogger info
INFO: Successfully released change log lock Oct 29, 2010 12:11:46 PM org.springframework.test.context.transaction.TransactionalTestExecutionListener endTransaction
INFO: Rolled back transaction after test execution for test context [[TestContext@19ea173 testClass = PhoneBookDAOFreshStandAloneDBIntegrationTest, locations = array[‘classpath:/DatabaseTesting/PhoneBookDAOFreshStandAloneDBIntegrationTest-context.xml’], testInstance = DatabaseTesting.PhoneBookDAOFreshStandAloneDBIntegrationTest@179a49f, testMethod = test_get_hits@PhoneBookDAOFreshStandAloneDBIntegrationTest, testException = liquibase.exception.RollbackFailedException: java.lang.NullPointerException]]

liquibase.exception.RollbackFailedException: java.lang.NullPointerException
at liquibase.changelog.ChangeSet.rolback(ChangeSet.java:340)
at liquibase.changelog.visitor.RollbackVisitor.visit(RollbackVisitor.java:23)
at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:58)
at liquibase.Liquibase.rollback(Liquibase.java:249)
at DatabaseTesting.PhoneBookDAOFreshStandAloneDBIntegrationTest.drop_tables(PhoneBookDAOFreshStandAloneDBIntegrationTest.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:37)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:94)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:192)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:115)
Caused by: java.lang.NullPointerException
at liquibase.changelog.ChangeSet.rolback(ChangeSet.java:310)
… 34 more

I can attach any configuration files if needed.

Also, on a very trivial sidenote, liquibase.changelog.ChangeSet.rolback is misspelled.  It should have 2 Ls not one.

Thanks, the null pointer should be fixed and the spelling too.  There was a generator returning a null collection of statements rather than an empty collection.

Nathan

Thanks for fixing this so quickly.  What release do you think it will be a part of?  Will there be an RC-8?

It should be in the RC7 release. 

I don’t know if there will be an RC8 or if it will be 2.0 final, it depends on issues people find.

Nathan

Thanks.  I have verified that it is working correctly now.  I appreciate the quick turnaround.

Good to hear, thanks for testing it out.

Nathan

Since the release of 2.0.0, I am now getting a NullPointerException when trying to use the SpringLiquibase class.

    Caused by: java.lang.NullPointerException at liquibase.integration.spring.SpringLiquibase.createLiquibase(SpringLiquibase.java:252) at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:230) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417) ... 40 more

I do not have any changelog properties in my bean definition, so it gets a nullpointer trying to loop through them and set them in the liquibase object.

                                       

The code should probably check the size of the map before trying to look through the keys, or initialize the map to empty if it is not set.

Yes, it is a bug fixed in trunk for 2.0.1, hopefully out this week.  YOu can specify an empty parameters map in your spring config to work around the issue for now.

Nathan

Excellent.  Thanks for the quick turnaround.  I already have the empty map fix in my code.  Looking forward to taking the latest release.