LiquiBase fails to correctly parse the changelog.xml file on a host with a non-english locale.
Our test host (Windows) is configured with Turkish as the primary language and LiquiBase fails with the following stack trace:
java.lang.RuntimeException: Property not found: initiallyDeferred
at liquibase.util.ObjectUtil.setProperty(ObjectUtil.java:38)
at liquibase.parser.xml.XMLChangeLogHandler.setProperty(XMLChangeLogHandler.java:354)
at liquibase.parser.xml.XMLChangeLogHandler.startElement(XMLChangeLogHandler.java:228)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:501)
at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:179)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.emptyElement(XMLSchemaValidator.java:719)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:377)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2740)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:645)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:508)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at liquibase.parser.xml.XMLChangeLogParser.parse(XMLChangeLogParser.java:70)
at liquibase.parser.ChangeLogParser.parse(ChangeLogParser.java:28)
at liquibase.parser.xml.XMLChangeLogHandler.handleIncludedChangeLog(XMLChangeLogHandler.java:319)
at liquibase.parser.xml.XMLChangeLogHandler.startElement(XMLChangeLogHandler.java:94)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:501)
at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:179)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.emptyElement(XMLSchemaValidator.java:719)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:377)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2740)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:645)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:508)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:807)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at liquibase.parser.xml.XMLChangeLogParser.parse(XMLChangeLogParser.java:70)
at liquibase.parser.ChangeLogParser.parse(ChangeLogParser.java:28)
at liquibase.Liquibase.validate(Liquibase.java:624)
Debugging shows that the methodName calculated in ObjectUtil is “set\u0130nitiallyDeferred”.
This occurs because the String.toUpper() method used to capitalize the “i” of the initiallyDeferred propertyName uses the default locale.
On the test system, the default locale is “tr_TR”, and converting the lowercase “i” to uppercase results in the Unicode character \u0130 (LATIN CAPITAL LETTER I WITH DOT ABOVE)
I was able to work around by setting the default locale to Locale.ENGLISH in the main() of the database migration program.
This was an acceptable work-around in this case, since this program has no user interface.
It would be nice however if the LiquiBase core was not influenced by the default locale.