Hey,
A company I’m working with has an older project with Liquibase and GWT and they’ve upgraded GWT and are encountering some problems with the Liquibase migrations, so I’m looking for suggestions on how to work around the problem.
Background
The project was on GWT v2.7.x and Liquibase v3.5.3, neither of which are close to current. Liquibase is invoked using a custom servlet listener (not using the one that comes with liquibase, but a simpler and customized one).
They’re looking to make some dependency upgrades and moved up to GWT v2.8.2 which went pretty smoothly.
The Problem
Liquibase still works fine in a production configuration, but it doesn’t run properly when you run GWT SuperDevMode in JetBrains IntelliJ. Seems like something has changed with the GWT launcher which results in the liquibase file appearing in multiple classpath locations simultaneously, which results in this error:
liquibase.exception.ChangeLogParseException: Error Reading Migration File: Found 3 files that match db-schema/installer.xml
at liquibase.parser.core.xml.XMLChangeLogSAXParser.parseToNode(XMLChangeLogSAXParser.java:118) ~[liquibase-core-3.8.9.jar:na]
at liquibase.parser.core.xml.AbstractChangeLogParser.parse(AbstractChangeLogParser.java:15) ~[liquibase-core-3.8.9.jar:na]
at liquibase.Liquibase.getDatabaseChangeLog(Liquibase.java:217) ~[liquibase-core-3.8.9.jar:na]
at liquibase.Liquibase.update(Liquibase.java:190) ~[liquibase-core-3.8.9.jar:na]
at liquibase.Liquibase.update(Liquibase.java:179) ~[liquibase-core-3.8.9.jar:na]
at liquibase.Liquibase.update(Liquibase.java:175) ~[liquibase-core-3.8.9.jar:na]
(That error shows liquibase 3.8.9 because I’ve been trying different versions of Liquibase to see if they all behave the same way, as well as digging into the code a little).
If I check the classpath myself, I can see that the class loader has three URLs for three filesystem paths and each of them seems to be resolving the “installer.xml”, so “getResources” shows three different URL for the same classpath name.
I haven’t been able to figure out why the classpath is behaving differently with GWT 2.8.2 launched through IntelliJ so far, so I was trying to see if I could somehow tweak the invocation of liquibase to avoid the problem.
The ResourceAccessor
being used is this:
ResourceAccessor accessor = new ClassLoaderResourceAccessor( Thread.currentThread().getContextClassLoader() );
Nice and simple, but if the file appears multiple times has duplicates and Liquibase (understandably) doesn’t like that, I thought I’d try a FileSystemResourceAccessor
(or a CompositeResourceAccessor
starting with the FileSystemResourceAccessor) to see if that solved the problem, but instead I get this error:
Caused by: liquibase.exception.UnexpectedLiquibaseException: java.lang.ClassCastException: com.somecompany.somepackage.SecurityChange cannot be cast to liquibase.change.custom.CustomChange
at liquibase.change.custom.CustomChangeWrapper.customLoadLogic(CustomChangeWrapper.java:337) ~[liquibase-core-3.8.9.jar:na]
at liquibase.change.AbstractChange.load(AbstractChange.java:708) ~[liquibase-core-3.8.9.jar:na]
at liquibase.change.custom.CustomChangeWrapper.load(CustomChangeWrapper.java:312) ~[liquibase-core-3.8.9.jar:na]
at liquibase.changelog.ChangeSet.toChange(ChangeSet.java:468) ~[liquibase-core-3.8.9.jar:na]
at liquibase.changelog.ChangeSet.handleChildNode(ChangeSet.java:401) ~[liquibase-core-3.8.9.jar:na]
at liquibase.changelog.ChangeSet.load(ChangeSet.java:325) ~[liquibase-core-3.8.9.jar:na]
at liquibase.changelog.DatabaseChangeLog.createChangeSet(DatabaseChangeLog.java:606) ~[liquibase-core-3.8.9.jar:na]
at liquibase.changelog.DatabaseChangeLog.handleChildNode(DatabaseChangeLog.java:336) ~[liquibase-core-3.8.9.jar:na]
at liquibase.changelog.DatabaseChangeLog.load(DatabaseChangeLog.java:305) ~[liquibase-core-3.8.9.jar:na]
at liquibase.parser.core.xml.AbstractChangeLogParser.parse(AbstractChangeLogParser.java:23) ~[liquibase-core-3.8.9.jar:na]
I’m puzzled by this one – is this the result of changing the ResourceAcccessor
? Is there way other way I can work around the fact that the installer.xml seems to be shows up in multiple classpath roots? I’ve dug a little into newer versions of Liquibase and so far it looks like I see the same problem with them.