Перейти к основному содержимому

Исправление ошибки сборки «константная строка слишком длинная»

· 3 мин. чтения

1. Обзор

Когда мы пытаемся использовать переменную, которая слишком длинна для компилятора Java (больше 64 КБ), мы получаем от компилятора ошибку «слишком длинная константная строка».

В этом уроке мы собираемся показать, как решить эту ошибку.

2. Описание проблемы

Давайте воспроизведем проблему, написав небольшой тест, в котором мы объявили слишком длинную строку :

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

Строка , содержащаяся в нашей переменной stringTooLong, содержит текст длиной более 100 000 символов. Строка с этими характеристиками доступна в файле, доступном по ссылке GitHub в конце. Чтобы вызвать ошибку, скопируйте ее содержимое и замените значение stringTooLong .

Обратите внимание: если мы запустим этот тест из некоторых IDE, мы не получим никаких ошибок .

Причина в том, что 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

Это связано с тем, что длина строковой константы в файле класса ограничена 2^16 байтами в кодировке UTF-8.

3. Решение проблемы

Как только мы воспроизведем проблему, давайте найдем способ ее решить. Лучше всего хранить нашу строку в отдельном файле, а не в объявленной переменной или константе.

Давайте создадим текстовый файл для хранения содержимого нашей переменной и изменим наш тест, чтобы получить значение из файла :

@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();
}

Другой способ решить эту проблему — сохранить содержимое нашей переменной в файле свойств, а затем получить к нему доступ из нашего тестового метода:

@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();
}
}

Теперь если мы попытаемся скомпилировать наш проект или выполнить тесты, все будет работать:

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

Конечно, мы могли бы также ввести конкатенацию с нашей строкой, но это не рекомендуется. Если у нас есть такая длинная строка, наши файлы Java, вероятно, в любом случае не лучший дом для нее.

4. Вывод

В этой статье мы рассмотрели ошибку компиляции «константная строка слишком длинная». Мы увидели, что можем обойти это, сохраняя значения строк в отдельных файлах или свойствах конфигурации.

Как всегда, вы можете найти код на GitHub .