1. Overview
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.
In this tutorial, we're going to show how to solve that error.
2. Describing the Problem
Let's reproduce the problem by writing a small test where we have declared a String that is too long:
@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.
Note, if we run this test from some IDEs, we won't receive any error. 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:
[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.
3. Solving the Problem
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.
4. Conclusion
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.