- Исправление “постоянной строки слишком долго” Ошибка сборки
- 1. Обзор
- 2. Описание проблемы
- 3. Решение проблемы
- 4. Заключение
- Исправление ошибки сборки «константная строка слишком длинная»
- 2. Описание проблемы
- 3. Решение проблемы
- 4. Вывод
- Java «constant string too long» compile error. Only happens using Ant, not when using Eclipse
- Solution 2
- Solution 3
- Solution 4
- Solution 5
- Allan
- Comments
- How can I declare a Large String( codes) in Java to avoid «Constant string too long» error?
- 3 Answers 3
Исправление “постоянной строки слишком долго” Ошибка сборки
Научитесь исправлять ошибку сборки «постоянная строка слишком долго» в Java.
1. Обзор
Когда мы пытаемся использовать переменную, которая слишком длинная для компилятора Java (больше 64 КБ), мы получаем ошибка “постоянная строка слишком длинная” от компилятора.
В этом учебнике мы покажем, как решить эту ошибку.
2. Описание проблемы
Давайте воспроизвести проблему, написав небольшой тест, где мы объявили Струнные это слишком долго:
@Test public void whenDeclaringTooLongString_thenCompilationError()
Струнные содержащиеся в нашем строкаТоЛонг переменная содержит текст с более чем 100 000 символов. Строка с этими характеристиками доступна в файле, доступном по ссылке GitHub в конце. Чтобы получить поднятую ошибку, скопировать ее содержимое и заменить строкаТоЛонг ‘S значение.
Примечание, если мы забудем этот тест от некоторых IDEs, мы не получим никаких ошибок .
Причина в том, что IDEs, как правило, более мягким. Однако при попытке компиляции проекта (пакет mvn ) или просто при попытке выполнить тесты ( 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]:[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 .
Исправление ошибки сборки «константная строка слишком длинная»
В этом уроке мы собираемся показать, как решить эту ошибку.
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 .
Java «constant string too long» compile error. Only happens using Ant, not when using Eclipse
Someone is trying to send you a message 🙂 In the time you’ve spend fiddling with compiler versions you could have loaded the data from a text file — which is probably where it belongs.
Solution 2
I found I could use the apache commons lang StringUtils.join( Object[] ) method to solve this.
public static final String CONSTANT = org.apache.commons.lang.StringUtils.join( new String[] < "This string is long", "really long. ", "really, really LONG. " >);
Solution 3
Nothing of above worked for me. I have created one text file with name test.txt and read this text file using below code
String content = new String(Files.readAllBytes(Paths.get("test.txt")));
Solution 4
The length of a string constant in a class file is limited to 2^16 bytes in UTF-8 encoding, this should not be dependent on the compiler used. Perhaps you are using a different character set in your ant file than in eclipse, so that some characters need more bytes than before. Please check the encoding attribute of your javac task.
Solution 5
A workaround is to chunk your string using new String() (yikes) or StringBuilder , e.g.
String CONSTANT = new String("first chunk") + new String("second chunk") + . + new String(". ");
String CONSTANT = new StringBuilder("first chunk") .append("second chunk") .append(". ") .toString();
These can be viable options if you’re producing this string e.g. from a code generator. The workaround documented in this answer where string literals are concatenated no longer works with Java 11
Allan
Comments
I have a few really long strings in one class for initializing user information. When I compile in Eclipse, I don’t get any errors or warnings, and the resulting .jar runs fine. Recently, I decided to create an ant build file to use. Whenever I compile the same class with ant, I get the «constant string too long» compile error. I’ve tried a number of ways to set the java compiler executable in ant to make sure that I’m using the exact same version as in Eclipse. I’d rather figure out how to get the same successful compile I get in Eclipse in Ant than try to rework the code to dynamically concatenate the strings.
How can I declare a Large String( codes) in Java to avoid «Constant string too long» error?
Problem is I am getting error «constant string too long”. I need some ideas if anyone of you have solved this issue or faced this.
where did Strings.xml come from? I mean’t, instead of saying String a = «abcdefg. «; you say String a = «ab»; String b = «cd»; .
3 Answers 3
There is limitation the Constant string but one can have a much larger String in memory as long as it is created at run-time such as by reading it through a resource.
You can try this solution.
private static String msg = null; public static String getMyString() throws IOException < if (null == msg) < try (BufferedReader br = new BufferedReader(new InputStreamReader(MyClass.class.getResourceAsStream("msg.txt")))) < msg = br.lines().collect(Collectors.joining("\n")); >> return msg; >
You can call it and save it in another string :
String str = getMyString(); System.out.println("str ") .append("").append(bodycontent) .append("") .append(""); String result = sb.toString();
Hope this is helpful. cheers
There is not so many things we can do when facing constant string too long error.
Constants are constrained to 64K elements per single String entry, but you can split your exceeding constant in a couple of smaller than 64K ones as a workaround.
In terms of software design, at the other hand, the idea of working with complete email bodies as just Strings is not ultimately perfect. Usually developers are using template engines for such purposes and do externalize email bodies to a separate files rather than String constants. Please see Chunk template engine as example which fits well into Android app, but there are lots of another such as Velocity or Freemarker. Template engine lets you clearly separate static email content from dynamically-populated pieces, separate your application data model from it’s html representation, and maintain valid architecture of your software
Being not aware of exact reason which prevents you from making a file instead of constant, there are lots of best practices to solve typical file-connected issues starting from embedding files into your jar as resources and ending in encrypting them to avoid unwanted leakage. Just ask another question on SO here.