Fixing “constant string too long” Build Error – 修复“常量字符串太长”构建错误

最后修改: 2020年 3月 27日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

When we try to use a variable that is too long for the Java compiler (larger than 64 KB) we receive a “constant string too long” error from the compiler.

当我们试图使用一个对Java编译器来说太长的变量时(大于64KB),我们会收到编译器发出的“常量字符串太长 “的错误。

In this tutorial, we’re going to show how to solve that error.

在本教程中,我们将展示如何解决这一错误。

2. Describing the Problem

2.描述问题

Let’s reproduce the problem by writing a small test where we have declared a String that is too long:

让我们通过写一个小测试来重现这个问题,我们声明了一个太长的String

@Test
public void whenDeclaringTooLongString_thenCompilationError() {
    String stringTooLong = "stringstringstring ... 100,000 characters ... string";  
    assertThat(stringTooLong).isNotEmpty();
}

The String contained in our stringTooLong variable contains text with more than 100,000 characters. A string with these characteristics is available in a file available via the GitHub link at the end. To get the error raised, copy its content and replace the stringTooLong‘s value.

我们的stringTooLong变量中所包含的String含有超过100,000个字符的文本。具有这些特征的字符串可以通过结尾处的GitHub链接获得一个文件。要获得提出的错误,复制其内容并替换stringTooLong的值。

Note, if we run this test from some IDEs, we won’t receive any error.

注意,如果我们从某些IDE运行这个测试,我们不会收到任何错误

The reason is that IDEs are usually more lenient. However, when trying to compile the project (mvn package) or just trying to execute the tests (mvn test) from the command line we will receive the following output:

原因是IDE通常比较宽松。然而,当试图编译项目(mvn package)或只是试图从命令行执行测试(mvn test)时,我们将收到以下输出。

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  5.058 s
[INFO] Finished at: 2020-03-14T17:56:34+01:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:testCompile (default-testCompile) on project core-java-strings: Compilation failure
[ERROR] <path to the test class>:[10,32] constant string too long

This is because the length of a string constant in a class file is limited to 2^16 bytes in UTF-8 encoding.

这是因为在UTF-8编码中,类文件中的字符串常量的长度被限制为2^16字节。

3. Solving the Problem

3.解决问题

Once we have the problem reproduced, let’s find a way to solve it. The best way is to store our string in a separate file instead of in a declared variable or constant.

一旦我们重现了这个问题,就让我们找到一个解决它的方法。最好的方法是将我们的字符串存放在一个单独的文件中,而不是存放在一个已声明的变量或常量中。

Let’s create a text file to store the content of our variable and modify our test to get the value from the file:

让我们创建一个文本文件来存储我们的变量内容,并将我们的测试修改为从该文件中获取值

@Test
public void whenStoringInFileTooLongString_thenNoCompilationError() throws IOException {
    FileInputStream fis = new FileInputStream("src/test/resources/stringtoolong.txt");
    String stringTooLong = IOUtils.toString(fis, "UTF-8");
    assertThat(stringTooLong).isNotEmpty();
}

Another way to solve this problem is to store the content of our variable in a properties file and then access it from our test method:

解决这个问题的另一个方法是将我们的变量内容存储在一个属性文件中,然后从我们的测试方法中访问它。

@Test
public void whenStoringInPropertiesString_thenNoCompilationError() throws IOException {
    try (InputStream input = new FileInputStream("src/main/resources/config.properties")) {         
        Properties prop = new Properties();
        prop.load(input);
        String sValue = prop.getProperty("stringtoolong");
        assertThat(sValue).isNotEmpty();
    }  
}

Now if we try to compile our project or execute the tests, everything will work:

现在,如果我们尝试编译我们的项目或执行测试,一切都会正常。

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  6.433 s
[INFO] Finished at: 2020-03-14T18:23:54+01:00
[INFO] ------------------------------------------------------------------------

Of course, we could also introduce concatenation with our string, but such isn’t recommended. If we have such a long string, our Java files are likely not the best home for it anyway.

当然,我们也可以用我们的字符串引入连接法,但不建议这样做。如果我们有这么长的字符串,我们的Java文件很可能不是它的最佳归宿。

4. Conclusion

4.结论

In this article, we looked at the “constant string too long” compile error. We saw that we can work around it by storing the value of the Strings in separate files or configuration properties.

在这篇文章中,我们研究了 “常量字符串太长 “的编译错误。我们看到,我们可以通过将字符串的值存储在单独的文件或配置属性中来解决这个问题。

As always, you can find the code over on GitHub.

一如既往,你可以在GitHub上找到代码