4.11.1. 在 Windows 构建 widgetset

当在 Windows 构建带有 web-toolkit 模块和自定义 widgetset 时,有时候您会在控制台窗口碰到下面的错误:

Execution failed for task ':app-web-toolkit:buildWidgetSet'.
> A problem occurred starting process 'command 'C:\Program Files\AdoptOpenJDK\jdk-8.0.242.08-hotspot\bin\java.exe''

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

这个错误消息没有显示问题产生的原因。打开终端窗口(或 IntelliJ IDEA 或 CUBA Studio 的终端工具窗),在项目目录运行带有 --stacktrace 选项的命令(如果您项目前缀名不是 app,则需替换):

gradlew :app-web-toolkit:buildWidgetSet --stacktrace

错误输出如下:

...
Caused by: java.io.IOException: Cannot run program "C:\Program Files\AdoptOpenJDK\jdk-8.0.242.08-hotspot\bin\java.exe" (in directory "C:\projects\proj\modules\web-toolkit"): CreateProcess error=206, The filename or extension is too long
        at net.rubygrapefruit.platform.internal.DefaultProcessLauncher.start(DefaultProcessLauncher.java:25)
        ... 8 more
Caused by: java.io.IOException: CreateProcess error=206, The filename or extension is too long
        ... 9 more

如果 错误消息包含 "CreateProcess error=206" - 那就是说您遇上了 臭名昭著的 Windows 限制(此处链接为 Google 搜索) - 在命令行中无法创建超过 32K 字符长度的进程。

不幸的是,没有能自动避免该问题的方法。下面是几个能解决这个 "The filename or extension is too long" 问题的办法:

  • 切换至其他操作系统开发,MacOS 或 Linux。

  • 升级项目的 Gradle 版本至 6 或者更新的版本,需要修改项目中 gradle\wrapper\gradle.properties 文件的 distributionUrl 属性。Gradle 6 不会出现这个问题,因为修改了往命令行传参的方式。注意,CUBA 默认使用 5.6.4 开发并测试,所以修改 Gradle 版本可能需要您手动调整构建脚本。

  • 缩短 buildWidgetSet Gradle 任务的字符数,少于 32K 即可。

缩短 buildWidgetSet 命令

使用下列方式可以缩短 buildWidgetSet 命令:

  1. 将项目移至较短的目录,比如 C:\proj\

  2. 将 Gradle 用户 home 目录移至尽可能最短的目录。下面有详解。

  3. 移除 app-web-toolkit 模块构建 widgetset 不需要的传递依赖。下面有详解。

确定 buildWidgetSet 命令行长度

如需检测构建 widgetset 命令的 Java 进程实际长度,可以在终端运行以下命令:

gradlew -i :app-web-toolkit:buildWidgetSet --stacktrace > build.log

然后打开 build.log 文件,搜索下面内容:

GWT Compiler args:
	[...]
JVM Args:
	[...]
Starting process 'command 'C:\...\bin\java.exe''. Working directory: ... Command: C:\...\java.exe <THOUSANDS OF CHARACTERS> com.company.project.web.toolkit.ui.AppWidgetSet

"Starting process …​" 这一行,包含了所有命令以及参数,所以这行的长度基本反映了实际执行命令的长度,我们需要缩短它。

修改 Gradle 用户 home 目录

Gradle 手册 有关于 Gradle 用户 home 目录的介绍。

  1. 选择用户 home 目录的新名称,推荐使用磁盘根目录下的一个字母,比如,C:\g\

  2. 为系统添加新的环境变量 GRADLE_USER_HOME,值为上一步修改的目录,比如,C:\g

  3. 在文件管理器打开用户根目录:C:\users\%myusername%

  4. .gradle 文件夹移至新位置,并按照刚才选定的那个字母重命名,即: C:\users\%myusername%\.gradleC:\g

  5. 重新打开 IntelliJ IDEA 或 CUBA Studio IDE 使得新创建的环境变量生效。

移除 app-web-toolkit 模块不需要的传递依赖

首先,需要知道 app-web-toolkit 模块有哪些传递依赖。在终端运行:

gradlew :app-web-toolkit:dependencies > deps.log

然后打开 deps.log 文件,在依赖列表中查找 compile

然后打开 build.gradle 文件,修改 configure(webToolkitModule) { 部分。按下面示例一样添加排除依赖的规则:

configure(webToolkitModule) {
    configurations.compile {
        // library dependencies that aren't necessary for widgetset compilation
        exclude group: 'org.springframework'
        exclude group: 'org.springframework.security.oauth'
        exclude group: 'org.eclipse.persistence'
        exclude group: 'org.codehaus.groovy'
        exclude group: 'org.apache.ant'
        exclude group: 'org.eclipse.jetty'
        exclude group: 'com.esotericsoftware'
        exclude group: 'com.googlecode.owasp-java-html-sanitizer'
        exclude group: 'net.sourceforge.htmlunit'

        // add-on dependencies that don't contain web components or widgetset
        // and therefore aren't necessary for widgetset compilation
        exclude group: 'com.haulmont.addon.restapi'
        exclude group: 'com.haulmont.reports'
        exclude group: 'com.haulmont.addon.admintools'
        exclude group: 'com.haulmont.addon.search'
        exclude group: 'com.haulmont.addon.emailtemplates'
        exclude group: 'de.diedavids.cuba.metadataextensions'
        exclude group: 'de.diedavids.cuba.instantlauncher'
    }
    // ...
}

上面的示例仅供参考。您的项目中需要移除的依赖库或者插件可能更多。

多尝试几次移除依赖库直到 buildWidgetSet 命令行的长度小于 32k。