build: pin file.encoding so the Maven build works on Windows - #2565
Conversation
…indows
JJTree reads the .jjt under GRAMMAR_ENCODING but writes the intermediate .jj
with the JVM default charset. On a platform whose default is a legacy code
page the grammar's Unicode character classes are written lossily, and JavaCC
then rejects the mangled ranges:
Error: Line 2331, Column 294: Right end of character range '?' has a
lower ordinal value than the left end of character range '?'.
The Gradle build has pinned -Dfile.encoding=UTF-8 in gradle.properties since
2021, which is why only the Maven build is affected. Give it the same pin via
.mvn/jvm.config and put windows-latest back in the maven_verify matrix.
ParserKeywordsUtilsTest regenerates the .jj in-process and reads it back, so it
depends on the default charset the same way the build does. Surefire forks its
test JVMs and those do not inherit .mvn/jvm.config, leaving them on the platform
default:
ParserKeywordsUtilsTest.getAllKeywordsUsingJavaCC ... <<< ERROR!
org.javacc.parser.MetaParseException
Gradle needs no equivalent: its test workers take their encoding from the daemon,
which gradle.properties already pins.
|
Awesome! We were searching for this since months! Thank you much for figuring this out, we will test and get back asap! |
|
Sorry, one more question: why only on Windows? Why is Linux/Maven and also MacOs/Maven working fine? |
Good question. I was assuming this was already working well on the other platforms, as I remember seeing reported that this was a problem on Windows only. AFAIK, depending on the locale, UTF-8 is the default encoding on Linux and also macOS, whereas on Windows it is always cp-1252. Also note that as of JDK 18 UTF-8 is used as the default encoding on all platforms, so switching the build to run on e.g. JDK 21 would be another solution. |
|
Thanks for merging this. Does this mean that a new release could be out soon? |
Yes, because you just solved the only showstopper! |
mvn verifycannot build the parser on Windows, which is whywindows-latestsits commented out of themaven_verifymatrix. JJTree reads the.jjtunderGRAMMAR_ENCODINGbut writes the intermediate.jjwith the JVM default charset, so a legacy code page mangles the grammar's Unicode character classes and JavaCC rejects what it reads back:The asymmetry sits in
org.javacc.jjtree.IO—GRAMMAR_ENCODINGgoverns reading only:Why only the Maven build
gradle.propertieshas pinned-Dfile.encoding=UTF-8since af7bc1c (2021-11-29). Take that away and Gradle fails the same way:The two pins
.mvn/jvm.configcovers the Maven JVM, where the JavaCC plugin runs the generator in-process. Surefire then forks its test JVMs, and those inherit neitherMAVEN_OPTSnorjvm.config, soParserKeywordsUtilsTest— which regenerates the.jjin-process and reads it back — still failed on the first Windows run:Hence the second pin in the surefire
argLine. Gradle needs no equivalent: its test workers take their encoding from the daemon.With both pins, all six jobs pass — including
Maven Verify (windows-latest): https://github.com/knutwannheden/JSqlParser/actions/runs/34449425105Consider JDK 18+ instead
JEP 400 makes UTF-8 the default charset regardless of platform, so a newer JDK removes the whole class of problem with nothing to remember:
Two pins were needed here, and any future forked JVM would need a third. The exposure is wider than the generator, too:
SelectTestreads a fixture withCharset.defaultCharset(),TestUtilsandSpecialOracleTestwrite with bareFileWriter, and non-ASCII fixtures already exist (large-sql-issue-923.txt,interval01.sql,explain01.sql).maven.compiler.releaseis 11, so the toolchain bump is independent of the target;mvn verifypasses on 21 locally.I kept the pins because they also fix the JDK 17 the workflow currently pins. Happy to switch this PR to the JDK bump, or to both, if you prefer.
Or fix JJTree
One line in the javacc-8 fork this build depends on, using the call
setInputmakes a few lines above — cherry-pickable independently of this PR:getGrammarEncoding()falls back tofile.encodingwhen unset, so this is backward compatible.It also covers a silent variant the other options miss.
<#CJK>is pure ASCII in the grammar, yet JJTree decodes the escapes and emits literals:A code page representing neither endpoint turns that into
["?"-"?"]— a valid single-character range, so the build succeeds and quietly ships a parser that drops CJK identifiers. JavaCC 7 escaped everything it wrote; JavaCC 8 does not.