为什么要指定 file.encoding = UTF-8 ?

如果不指定字符集编码,那么在 Java程序中,从字节换为字符时会使用系统属性 file.encoding,这个属性会从操作系统中继承,例如中文windows一般会设置为 GBK 字符编码。

这样会有什么问题呢?因为 Grails 的 JSON View 需要将 .gson 文件编译为 class。在编译时如何对待文件的编码呢?Grails 就使用了系统属性 file.encoding,于是当代码是 UTF-8 编码而被 Grails 用 GBK 进行编译时就会出错。

如何指定 Grails 命令行启动的服务的 file.encoding ?

如果在 windows 命令行用安装好的 grails 启动开发服务,那么需要指定 file.encoding=UTF-8,但要修改 build.gradle 中的 bootRun 配置,像这样:

bootRun {
    jvmArgs(
            '-Dspring.output.ansi.enabled=always',
            // 解决 view 编译时使用 GBK 字符集导致异常的问题
            '-Dfile.encoding=UTF-8',
            '-noverify',
            '-XX:TieredStopAtLevel=1',
            '-Xmx1024m')
    sourceResources sourceSets.main
    String springProfilesActive = 'spring.profiles.active'
    systemProperty springProfilesActive, System.getProperty(springProfilesActive)
}

执行启动命令

grails run

就可以看到效果了。

解决 gradle build 时,因为字符编码未指定而导致运行测试失败的问题

在 windows 命令行窗口执行 gradlew.bat clean build 失败

错误提示

java.lang.reflect.InvocationTargetException
        at org.grails.testing.runtime.support.ActionSettingMethodHandler.invoke(ActionSettingMethodHandler.groovy:29)
        at chess_api.UserControllerSpec.注册用户(UserControllerSpec.groovy:53)
Caused by: grails.views.ViewCompilationException: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
chess_api_api_apiResponse_gson: 16: [Static type checking] - The variable [鏁版嵁楠岃瘉澶辫触] is undeclared.
@ line 16, column 30.
       if (apiResponse.code in [鏁版嵁楠岃瘉澶辫触.code, 璇锋眰鍙傛暟鏃犳晥.code] && apiResponse.info) {
                                ^
chess_api_api_apiResponse_gson: 16: [Static type checking] - The variable [璇锋眰鍙傛暟鏃犳晥] is undeclared.
@ line 16, column 46.
   onse.code in [鏁版嵁楠岃瘉澶辫触.code, 璇锋眰鍙傛暟鏃犳晥.
                                 ^

分析:
这是在编译 json view class 时报告的错误,因为使用了中文枚举名,所以需要告诉 gradle 执行 grails test 任务时将 file.encoding 设置为 UTF-8。

解决方案:
设置启动 gradle 的 JVM 的 file.encoding=UTF-8,方法是修改 gradlew.bat 文件,添加一行:

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

或者在执行 gradle 命令时添加 -Dfile.encoding=UTF-8 选项。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐