Claude Code начал читать `AGENTS.md`. Правила проекта для Claude и Codex теперь можно держать в одном файле.
Раньше, если в команде работали оба агента, приходилось вести два почти одинаковых файла:
В Claude Code 2.1.277 это закрыли. Но с условием, которое легко пропустить.
`AGENTS.md` читается, только если в проекте нет `CLAUDE.md`.
Проверяются три файла:
При этом в любом случае продолжают грузиться:
- пользовательский
- правила из
- managed-инструкции организации.
Если нужны оба файла сразу, режим переключается в
Оговорка: на Bedrock, Vertex и Foundry поддержки пока нет.
Я бы раскладывал так: общее для всех агентов (стек, команды тестов и сборки, конвенции, что не трогать) живёт в
Один источник правды для правил проекта. Настройки инструментов отдельно.
#ClaudeCode #Codex #AIAgents #AI
Раньше, если в команде работали оба агента, приходилось вести два почти одинаковых файла:
CLAUDE.md и AGENTS.md. Такие файлы рано или поздно разъезжаются: поправили команду сборки в одном, забыли во втором.В Claude Code 2.1.277 это закрыли. Но с условием, которое легко пропустить.
`AGENTS.md` читается, только если в проекте нет `CLAUDE.md`.
Проверяются три файла:
CLAUDE.md, .claude/CLAUDE.md и CLAUDE.local.md в рабочей директории и выше. Нашёлся хоть один, и AGENTS.md по умолчанию молча игнорируется.При этом в любом случае продолжают грузиться:
- пользовательский
~/.claude/CLAUDE.md;- правила из
.claude/rules/;- managed-инструкции организации.
Если нужны оба файла сразу, режим переключается в
/config → Project instructions. Если удалять CLAUDE.md не хочется, работает и старый приём: строка @AGENTS.md внутри него подтягивает содержимое импортом.Оговорка: на Bedrock, Vertex и Foundry поддержки пока нет.
Я бы раскладывал так: общее для всех агентов (стек, команды тестов и сборки, конвенции, что не трогать) живёт в
AGENTS.md. Hooks, разрешения и прочая специфика инструмента остаются в его собственных настройках.Один источник правды для правил проекта. Настройки инструментов отдельно.
#ClaudeCode #Codex #AIAgents #AI
👍4❤1 1
«Данные у нас и так приходят отсортированными». После этой фразы группы в отчёте однажды разваливаются.
В среду писал, что группы в JasperReports требуют отсортированных данных. Частое возражение:
Документация PostgreSQL говорит прямо: без
Что ломает это совпадение без единой правки в коде:
-
-
- вырос объём, и планировщик выбрал другой план: hash-агрегацию, другой join;
- параллельный seq scan: воркеры отдают строки, кто быстрее;
- параллельное выполнение и другие изменения плана также могут изменить порядок, даже если SQL не менялся.
Поэтому особенно опасно проверять такую зависимость на маленькой тестовой базе: запрос может годами «случайно» возвращать строки в нужном порядке, а затем изменение данных или плана запроса всё поменяет.
Правило: если порядок важен отчёту, группе, пагинации или
#PostgreSQL #SQL #JasperReports #ЛовушкаНедели
В среду писал, что группы в JasperReports требуют отсортированных данных. Частое возражение:
ORDER BY в запросе нет, а строки всё равно идут по порядку. Идут. До поры.Документация PostgreSQL говорит прямо: без
ORDER BY строки возвращаются в том порядке, который системе быстрее всего получить. Никаких гарантий. «Сегодня по порядку» — это не контракт PostgreSQL. Фактический порядок может зависеть от плана сканирования/соединения и физического расположения данных.Что ломает это совпадение без единой правки в коде:
-
UPDATE может записать новую версию строки в другое место таблицы, и порядок чтения меняется;-
VACUUM освобождает место, и новые строки занимают дыры в середине таблицы;- вырос объём, и планировщик выбрал другой план: hash-агрегацию, другой join;
- параллельный seq scan: воркеры отдают строки, кто быстрее;
- параллельное выполнение и другие изменения плана также могут изменить порядок, даже если SQL не менялся.
Поэтому особенно опасно проверять такую зависимость на маленькой тестовой базе: запрос может годами «случайно» возвращать строки в нужном порядке, а затем изменение данных или плана запроса всё поменяет.
Правило: если порядок важен отчёту, группе, пагинации или
LIMIT, он записан в ORDER BY. Всё остальное держится на удаче.#PostgreSQL #SQL #JasperReports #ЛовушкаНедели
👍4🔥2 1
splitType="Prevent" в Table Component может приводить к проблемам с разбиением строки на страницы, если ячейки содержат элементы с textAdjust="StretchHeight".
Здесь взаимодействуют два механизма JasperReports.
textAdjust="StretchHeight" позволяет textField увеличить свою высоту, если содержимое не помещается в исходный размер. Устаревший вариант этой настройки — isStretchWithOverflow. Такое поведение используется для динамического текста, длина которого заранее неизвестна.
Например:
При большом количестве текста фактическая высота textField может стать больше первоначальной.
Одновременно JasperReports должен решить, как разместить строку относительно границы страницы.
При:
первая попытка разделить строку запрещается. Если строка не помещается на текущей странице, механизм переноса пытается разместить её целиком на следующей. При этом сама строка может содержать элементы, фактическая высота которых определяется только во время формирования отчёта.
Именно сочетание динамического изменения высоты и запрета первого разрыва может приводить в отдельных сценариях к некорректному размещению содержимого при переходе через границу страницы.
Что можно сделать
1. Проверить растягивающиеся поля
Если текст должен полностью отображаться, используйте:
В старых шаблонах может встречаться:
2. Проверить splitType строки Table Component
Если строку допустимо разделять между страницами, можно использовать:
В отличие от Prevent, Immediate разрешает разрыв строки, что может быть полезно для строк с динамически растягивающимся текстом.
3. Если строка не должна разрываться
Prevent можно оставить, но тогда стоит особенно внимательно проверить сценарии, когда динамическая высота строки превышает оставшееся место на странице.
Также важно учитывать, что Prevent не означает «строка никогда не будет разделена». Он запрещает первый разрыв; на последующих страницах JasperReports может разрешить разбиение, чтобы избежать бесконечного цикла.
4. Не забывать про версию JasperReports
Здесь есть важный нюанс: возможность задавать splitType непосредственно для строк Table Component появилась в JasperReports 6.20.6.
То есть для старых версий поведение нужно анализировать уже с учётом splitType родительского band и возможностей конкретной версии.
5. Обязательно проверить реальный шаблон
Для таблиц с динамической высотой одной настройки splitType недостаточно. На результат также могут влиять stretchType, positionType, высота detailCell, несколько растягивающихся элементов в одной строке и расположение таблицы относительно границы страницы.
Поэтому после изменения настройки стоит проверить как минимум:
короткий текст;
текст, занимающий несколько строк;
строку, которая почти полностью помещается в остаток страницы;
строку, которая немного не помещается;
очень длинный текст;
несколько последовательно растягивающихся строк.
splitType="Prevent" — полезный механизм контроля разрывов, но при работе с таблицами, содержащими динамически растягивающиеся элементы, его поведение нужно проверять на реальных многостраничных данных.
#JasperReports #JRXML #JaspersoftStudio #TableComponent #SplitType
Здесь взаимодействуют два механизма JasperReports.
textAdjust="StretchHeight" позволяет textField увеличить свою высоту, если содержимое не помещается в исходный размер. Устаревший вариант этой настройки — isStretchWithOverflow. Такое поведение используется для динамического текста, длина которого заранее неизвестна.
Например:
<textField textAdjust="StretchHeight">
<reportElement width="200" height="30"/>
<textFieldExpression><![CDATA[$F{description}]]></textFieldExpression>
</textField>При большом количестве текста фактическая высота textField может стать больше первоначальной.
Одновременно JasperReports должен решить, как разместить строку относительно границы страницы.
При:
<detail splitType="Prevent">первая попытка разделить строку запрещается. Если строка не помещается на текущей странице, механизм переноса пытается разместить её целиком на следующей. При этом сама строка может содержать элементы, фактическая высота которых определяется только во время формирования отчёта.
Именно сочетание динамического изменения высоты и запрета первого разрыва может приводить в отдельных сценариях к некорректному размещению содержимого при переходе через границу страницы.
Что можно сделать
1. Проверить растягивающиеся поля
Если текст должен полностью отображаться, используйте:
textAdjust="StretchHeight"В старых шаблонах может встречаться:
isStretchWithOverflow="true"2. Проверить splitType строки Table Component
Если строку допустимо разделять между страницами, можно использовать:
<detail splitType="Immediate">В отличие от Prevent, Immediate разрешает разрыв строки, что может быть полезно для строк с динамически растягивающимся текстом.
3. Если строка не должна разрываться
Prevent можно оставить, но тогда стоит особенно внимательно проверить сценарии, когда динамическая высота строки превышает оставшееся место на странице.
Также важно учитывать, что Prevent не означает «строка никогда не будет разделена». Он запрещает первый разрыв; на последующих страницах JasperReports может разрешить разбиение, чтобы избежать бесконечного цикла.
4. Не забывать про версию JasperReports
Здесь есть важный нюанс: возможность задавать splitType непосредственно для строк Table Component появилась в JasperReports 6.20.6.
То есть для старых версий поведение нужно анализировать уже с учётом splitType родительского band и возможностей конкретной версии.
5. Обязательно проверить реальный шаблон
Для таблиц с динамической высотой одной настройки splitType недостаточно. На результат также могут влиять stretchType, positionType, высота detailCell, несколько растягивающихся элементов в одной строке и расположение таблицы относительно границы страницы.
Поэтому после изменения настройки стоит проверить как минимум:
короткий текст;
текст, занимающий несколько строк;
строку, которая почти полностью помещается в остаток страницы;
строку, которая немного не помещается;
очень длинный текст;
несколько последовательно растягивающихся строк.
splitType="Prevent" — полезный механизм контроля разрывов, но при работе с таблицами, содержащими динамически растягивающиеся элементы, его поведение нужно проверять на реальных многостраничных данных.
#JasperReports #JRXML #JaspersoftStudio #TableComponent #SplitType
👍6🤔1
Летом писал, что pageFooter в JasperReports не растягивается. Вторая половина той же истории: он и не сжимается.
Задача выглядела безобидно: колонтитул нужен только при условии. Ставим
Почему так. Движок заполняет страницу сверху вниз и заранее должен знать, где остановить detail. Поэтому высота pageFooter вычитается из доступного места ещё до первой строки данных.
Условие управляет содержимым колонтитула. Высотой - нет. Сжимающегося колонтитула в шаблоне не бывает.
Что с этим делать:
- держать pageFooter минимальным: номер страницы и то, что нужно на каждой странице без условий;
- если отличается только последняя страница, есть
- условный блок переносить в поточные секции, group footer или summary: они занимают место, только когда реально печатаются;
- если блок должен стоять внизу страницы, помогает фиктивная группа на весь отчёт и её footer с
С
А вы как решаете условные колонтитулы:
#JasperReports #JRXML #JaspersoftStudio #Отчёты
Задача выглядела безобидно: колонтитул нужен только при условии. Ставим
printWhenExpression, условие ложное, колонтитул не печатается. А место под ним остаётся, и внизу страницы появляется пустая полоса.Почему так. Движок заполняет страницу сверху вниз и заранее должен знать, где остановить detail. Поэтому высота pageFooter вычитается из доступного места ещё до первой строки данных.
printWhenExpression проверяется позже, в момент печати самого колонтитула. К этому времени место уже зарезервировано.Условие управляет содержимым колонтитула. Высотой - нет. Сжимающегося колонтитула в шаблоне не бывает.
Что с этим делать:
- держать pageFooter минимальным: номер страницы и то, что нужно на каждой странице без условий;
- если отличается только последняя страница, есть
lastPageFooter со своей высотой;- условный блок переносить в поточные секции, group footer или summary: они занимают место, только когда реально печатаются;
- если блок должен стоять внизу страницы, помогает фиктивная группа на весь отчёт и её footer с
footerPosition="ForceAtBottom".С
lastPageFooter есть нюанс: если он выше обычного, на последней странице может не хватить места, и документ получит лишнюю страницу. Проверяйте на объёме данных, который заполняет страницу почти до конца.А вы как решаете условные колонтитулы:
lastPageFooter, группа или summary?#JasperReports #JRXML #JaspersoftStudio #Отчёты
Параметр $P{REPORT_MAX_PAGES} в JasperReports не всегда останавливает генерацию отчёта на нужном количестве страниц. Часто разработчики полагаются на него как на прямое управление количеством страниц, но это не всегда так.
Механизм заключается в том, что
Симптом, с которым сталкиваются разработчики: отчёт генерируется на 10 страниц, хотя в параметре
Как проверить и исправить:
1. Проверьте
2. Проверьте
3. Используйте
Важно понимать, что
#JasperReports #JaspersoftStudio #JRXML #Java #ЛовушкаНедели
Механизм заключается в том, что
REPORT_MAX_PAGES - это переменная, которая устанавливает максимальное количество страниц, которое будет сгенерировано. Однако, если в вашем шаблоне есть элементы, которые по своей природе занимают больше одной страницы (например, длинные таблицы с splitType="Prevent" или элементы, растягивающиеся на всю высоту страницы), JasperReports может продолжать их генерацию, даже если REPORT_MAX_PAGES уже достигнут. Это происходит потому, что система сначала пытается корректно завершить текущий элемент или группу, прежде чем остановиться.Симптом, с которым сталкиваются разработчики: отчёт генерируется на 10 страниц, хотя в параметре
REPORT_MAX_PAGES установлено значение 5.Как проверить и исправить:
1. Проверьте
splitType: Для таблиц и других элементов, которые могут занимать несколько страниц, убедитесь, что splitType установлен корректно. Prevent может привести к тому, что вся группа или строка перенесется на следующую страницу, игнорируя REPORT_MAX_PAGES для текущей генерации. Рассмотрите Immediate или Stretch, если это допустимо для вашего отчёта.2. Проверьте
textField и summary band: Элементы, использующие textAdjust="StretchHeight", или контент в summary band, который может быть очень объёмным, также могут вызывать переполнение. Убедитесь, что их максимальная высота контролируется.3. Используйте
net.sf.jasperreports.engine.fill.MaxPagesType: В более поздних версиях JasperReports (начиная с 6.10.0) можно использовать свойство net.sf.jasperreports.engine.fill.MAX_PAGES_TYPE с значением STRICT. Это заставит движок останавливаться строго после достижения REPORT_MAX_PAGES, прерывая генерацию любых элементов, которые не умещаются. Это свойство можно установить в jasperreports.properties или через JasperReportBuilder.setProperty().Важно понимать, что
REPORT_MAX_PAGES — это скорее рекомендация для движка, а не абсолютный ограничитель, если элементы внутри отчёта имеют свои собственные правила разрыва и растяжения.#JasperReports #JaspersoftStudio #JRXML #Java #ЛовушкаНедели
🔥2 1
Продолжаю разбирать DeepSeek Harness. Самая инженерная идея внутри - журнал событий, из которого собирается вся сессия агента.
Всё, что видит модель, пишется в append-only лог: системный промпт, reasoning, вызовы инструментов и их результаты, запуск субагентов, каждая инъекция контекста. Resume, fork, поиск и replay работают поверх одного и того же потока событий.
Для бэкендера схема знакомая: по сути это event sourcing для агента. Отсюда почти бесплатно получаются вещи, которые в других инструментах выглядят отдельными фичами. Можно вернуться к любой точке сессии, ответвиться и попробовать другой путь, воспроизвести прогон и найти шаг, где агент свернул не туда. В Web UI для этого есть Trajectory view с записями, разложенными по источникам.
Вторая деталь - режимы работы:
- Standard - полный набор инструментов;
- Code - модель пишет код, который оркестрирует несколько раундов вызовов инструментов;
- Minimal - только shell и редактор файлов, для бенчмарков моделей.
Minimal mode для меня самый показательный. Чтобы честно сравнить модели, окружение приходится урезать до минимума. Я читаю это как признание: harness влияет на результат настолько, что с ним модели не сравнить. Ровно то, о чём писал в сентябре.
Сравнение с Codex пока отложу. История сессий и resume есть и там, но в dsh журнал лежит в основе архитектуры. Проект в developer preview, совместимость между версиями ломается, так что выводы держу до более стабильного релиза.
#DeepSeekHarness #DeepSeek #AIAgents #EventSourcing
Всё, что видит модель, пишется в append-only лог: системный промпт, reasoning, вызовы инструментов и их результаты, запуск субагентов, каждая инъекция контекста. Resume, fork, поиск и replay работают поверх одного и того же потока событий.
Для бэкендера схема знакомая: по сути это event sourcing для агента. Отсюда почти бесплатно получаются вещи, которые в других инструментах выглядят отдельными фичами. Можно вернуться к любой точке сессии, ответвиться и попробовать другой путь, воспроизвести прогон и найти шаг, где агент свернул не туда. В Web UI для этого есть Trajectory view с записями, разложенными по источникам.
Вторая деталь - режимы работы:
- Standard - полный набор инструментов;
- Code - модель пишет код, который оркестрирует несколько раундов вызовов инструментов;
- Minimal - только shell и редактор файлов, для бенчмарков моделей.
Minimal mode для меня самый показательный. Чтобы честно сравнить модели, окружение приходится урезать до минимума. Я читаю это как признание: harness влияет на результат настолько, что с ним модели не сравнить. Ровно то, о чём писал в сентябре.
Сравнение с Codex пока отложу. История сессий и resume есть и там, но в dsh журнал лежит в основе архитектуры. Проект в developer preview, совместимость между версиями ломается, так что выводы держу до более стабильного релиза.
#DeepSeekHarness #DeepSeek #AIAgents #EventSourcing
👍3 2
Записываю видео по Jaspersoft Studio и поймал себя на ошибке: считаю базой то, что для многих оказалось открытием.
Пример - две настройки textField, которые я включаю почти не глядя. Выяснилось, что про них знают далеко не все.
«Пустой, когда null» (Blank When Null)
Без неё поле с пустым значением печатает в документе слово
Есть подвох: галочка срабатывает, только если null - результат всего выражения.
«Растянуть по высоте» (Stretch Height)
Но пост скорее не про Jasper. У этого эффекта есть название - проклятие знания. Когда годами работаешь с инструментом, перестаёшь видеть ступеньки, по которым сам когда-то поднимался. Объяснять «очевидное» кажется неловко. А кто-то тем временем полдня ищет, откуда в PDF взялось слово null.
Вывод для себя сделал такой: в видео проговаривать и то, что кажется очевидным. Тридцать лишних секунд для одних экономят час другим.
Какая «очевидная» настройка когда-то стала открытием для вас?
#JasperReports #JaspersoftStudio #Обучение #Личное
Пример - две настройки textField, которые я включаю почти не глядя. Выяснилось, что про них знают далеко не все.
«Пустой, когда null» (Blank When Null)
Без неё поле с пустым значением печатает в документе слово
null. В JRXML это isBlankWhenNull="true".Есть подвох: галочка срабатывает, только если null - результат всего выражения.
"Итого: " + $F{amount} при пустой сумме вернёт строку «Итого: null», и настройка уже не поможет. Такое закрывается условием прямо в выражении.«Растянуть по высоте» (Stretch Height)
textAdjust="StretchHeight": поле растёт под длину текста вместо того, чтобы его обрезать. Как это работает в паре со splitType, разбирал в августе.Но пост скорее не про Jasper. У этого эффекта есть название - проклятие знания. Когда годами работаешь с инструментом, перестаёшь видеть ступеньки, по которым сам когда-то поднимался. Объяснять «очевидное» кажется неловко. А кто-то тем временем полдня ищет, откуда в PDF взялось слово null.
Вывод для себя сделал такой: в видео проговаривать и то, что кажется очевидным. Тридцать лишних секунд для одних экономят час другим.
Какая «очевидная» настройка когда-то стала открытием для вас?
#JasperReports #JaspersoftStudio #Обучение #Личное
👍2🔥2
Автоматизация AI-агентов — это не про копирование промптов.
Умение собирать AI-агентов в цепочки и создавать для них управляемые окружения — вот реальная инженерная практика.
Вместо того чтобы просто копировать готовые промпты для ChatGPT, сосредоточьтесь на создании систем, где агенты могут взаимодействовать друг с другом и с внешним миром. Это требует понимания архитектурных паттернов и принципов построения сложных систем.
Что делать:
- Изучите подходы к оркестрации агентов. Например, LangChain или Semantic Kernel предоставляют фреймворки для построения таких систем.
- Определите, какие задачи могут быть автоматизированы через взаимодействие нескольких специализированных агентов.
- Разработайте механизмы для оценки качества работы агентов и их цепочек.
- Поймите ограничения текущих AI-моделей: их неспособность к истинному пониманию и потенциальные проблемы с безопасностью....
#AI #Агенты #Инженерия #Автоматизация #Продуктивность
Умение собирать AI-агентов в цепочки и создавать для них управляемые окружения — вот реальная инженерная практика.
Вместо того чтобы просто копировать готовые промпты для ChatGPT, сосредоточьтесь на создании систем, где агенты могут взаимодействовать друг с другом и с внешним миром. Это требует понимания архитектурных паттернов и принципов построения сложных систем.
Что делать:
- Изучите подходы к оркестрации агентов. Например, LangChain или Semantic Kernel предоставляют фреймворки для построения таких систем.
- Определите, какие задачи могут быть автоматизированы через взаимодействие нескольких специализированных агентов.
- Разработайте механизмы для оценки качества работы агентов и их цепочек.
- Поймите ограничения текущих AI-моделей: их неспособность к истинному пониманию и потенциальные проблемы с безопасностью....
#AI #Агенты #Инженерия #Автоматизация #Продуктивность
👍1
`@Transactional` на месте, а транзакции нет. И Spring не сообщит об этом ни ошибкой, ни предупреждением.
В июле разбирал
Почему так.
Что при этом ломается, зависит от содержимого метода:
- код, рассчитывающий на cursor/fetch-size внутри транзакции, может перестать работать так, как ожидалось;
-
-
Что делать:
- вынести транзакционный метод в отдельный бин, это самый чистый вариант;
-
- самоинъекция через
Есть и родственная тонкость: в proxy mode локальный вызов внутри того же класса не перехватывается. Правила для non-public методов зависят от типа прокси и версии Spring; в современных class-based proxies protected/package-private методы могут поддерживаться.
Правило: транзакционная граница проходит между бинами. При вызове через
#Spring #Transactional #Java #ЛовушкаНедели
В июле разбирал
fetchSize, который в PostgreSQL стримит данные только внутри транзакции. Самый частый способ эту транзакцию потерять - вызвать транзакционный метод из того же класса:public void export() {
this.loadAll(); // @Transactional на loadAll() не сработает
}Почему так.
@Transactional работает через прокси: Spring оборачивает бин, и транзакцию открывает обёртка, когда вызов приходит снаружи. Вызов через this идёт напрямую в объект, мимо прокси. Аннотация на месте, код компилируется, тесты вполне могут быть зелёными.Что при этом ломается, зависит от содержимого метода:
- код, рассчитывающий на cursor/fetch-size внутри транзакции, может перестать работать так, как ожидалось;
-
LazyInitializationException там, где «всё было в транзакции»;-
REQUIRES_NEW при self-invocation не получает заявленную отдельную транзакционную границу.Что делать:
- вынести транзакционный метод в отдельный бин, это самый чистый вариант;
-
TransactionTemplate, если границу транзакции удобнее задать прямо в коде;- самоинъекция через
@Lazy работает, но читается как костыль.Есть и родственная тонкость: в proxy mode локальный вызов внутри того же класса не перехватывается. Правила для non-public методов зависят от типа прокси и версии Spring; в современных class-based proxies protected/package-private методы могут поддерживаться.
Правило: транзакционная граница проходит между бинами. При вызове через
this аннотация работает как комментарий.#Spring #Transactional #Java #ЛовушкаНедели
Неочевидное поведение
Механизм
*
*
*
Проблема возникает, когда
Для решения этой проблемы:
1. Проверьте
2. Используйте
3. Оцените содержимое ячеек: убедитесь, что в ячейках нет чрезмерно длинных текстов или элементов, которые могут вызвать проблемы с переносом. Настройка
4. Тестируйте экспорт в целевые форматы (PDF, DOCX, XLSX), так как поведение может варьироваться.
У меня сейчас правило простое:
#JasperReports #JRXML #JaspersoftStudio #ЛовушкаНедели
splitType в JasperReports может приводить к потере данных при экспорте. Разработчики часто фокусируются на textAdjust и isStretchWithOverflow, забывая про механизм, который управляет разрывом строк таблицы между страницами.Механизм
splitType определяет, как JasperReports обрабатывает строки таблицы, когда они достигают границы страницы. Основные значения:*
Stretch (по умолчанию): Секция пытается остаться единым целым, но может быть разорвана, если содержимое не помещается.*
Prevent: Вся секция (строка таблицы) принудительно переносится на следующую страницу, если она не помещается полностью.*
Immediate: Разрешает разрыв строки раньше, чем она полностью напечатается, предотвращая "отрезание" части контента.Проблема возникает, когда
splitType установлен в Prevent или Stretch, а содержимое строки превышает доступное пространство на странице. В таких случаях JasperReports может попытаться перенести всю строку на следующую страницу, но если даже одна строка не помещается, отчет может "обрезать" часть данных или некорректно разбить таблицу. Это поведение может отличаться в зависимости от версии JasperReports и используемого экспортера. Например, в версиях до 6.20.1 управление splitType для строк table component было менее гибким.Для решения этой проблемы:
1. Проверьте
splitType для строк вашей таблицы в JRXML. Убедитесь, что он соответствует требованиям к отображению данных.2. Используйте
Immediate, если необходимо гарантировать, что ни одна часть строки не будет потеряна, даже если это приведет к более раннему разрыву.3. Оцените содержимое ячеек: убедитесь, что в ячейках нет чрезмерно длинных текстов или элементов, которые могут вызвать проблемы с переносом. Настройка
textAdjust="StretchHeight" для textField может помочь, но только если splitType строки таблицы позволяет такое поведение.4. Тестируйте экспорт в целевые форматы (PDF, DOCX, XLSX), так как поведение может варьироваться.
У меня сейчас правило простое:
splitType - это первый параметр, который я проверяю, когда данные теряются на границе страницы в таблицах.#JasperReports #JRXML #JaspersoftStudio #ЛовушкаНедели
👍4 1 1
PDF/A-1a в JasperReports не включается двумя настройками. Нужна третья, и без неё не работает ничего: ICC-профиль.
Разбирали на неделе экспорт в архивный PDF. Логичный путь выглядит так:
-
-
Обе настройки на месте, а PDF/A не получается. Не хватает файла.
PDF/A требует, чтобы цвета в документе были описаны однозначно. Для этого в PDF встраивается output intent с ICC-профилем, обычно sRGB. Сам Jasper профиль не генерирует: путь к
Что ещё проверить, раз уж взялись:
- все шрифты встроены (`pdfEmbedded`), стандартный Helvetica стандарт не пропустит;
- в отчёте нет прозрачности, PDF/A-1 её запрещает;
-
Результат лучше проверять валидатором, а не глазами: бесплатный veraPDF прямо пишет, какое требование нарушено.
Отдельно для тех, кто на 7.x Community Edition: как я писал в августе, в 7.0.8 наиболее полную реализацию тегирования для PDF/A вынесли в Professional. Для уровня «a» это может оказаться важнее любых настроек.
Порядок у меня теперь такой: сначала ICC-профиль в ресурсы, потом свойства экспорта, потом veraPDF.
#JasperReports #PDFA #PDF #Отчёты
Разбирали на неделе экспорт в архивный PDF. Логичный путь выглядит так:
-
net.sf.jasperreports.export.pdfa.conformance = pdfa1a;-
net.sf.jasperreports.export.pdf.tagged = true, потому что буква «a» в PDF/A-1a означает документ со структурой тегов.Обе настройки на месте, а PDF/A не получается. Не хватает файла.
PDF/A требует, чтобы цвета в документе были описаны однозначно. Для этого в PDF встраивается output intent с ICC-профилем, обычно sRGB. Сам Jasper профиль не генерирует: путь к
.icc нужно передать в net.sf.jasperreports.export.pdfa.icc.profile.path. Нет файла, нет соответствия стандарту.Что ещё проверить, раз уж взялись:
- все шрифты встроены (`pdfEmbedded`), стандартный Helvetica стандарт не пропустит;
- в отчёте нет прозрачности, PDF/A-1 её запрещает;
-
.icc лежит в ресурсах приложения, а не на диске разработчика, иначе на сервере всё сломается снова.Результат лучше проверять валидатором, а не глазами: бесплатный veraPDF прямо пишет, какое требование нарушено.
Отдельно для тех, кто на 7.x Community Edition: как я писал в августе, в 7.0.8 наиболее полную реализацию тегирования для PDF/A вынесли в Professional. Для уровня «a» это может оказаться важнее любых настроек.
Порядок у меня теперь такой: сначала ICC-профиль в ресурсы, потом свойства экспорта, потом veraPDF.
#JasperReports #PDFA #PDF #Отчёты
Запускаю рубрику по понедельникам: Platform V Report Designer. Буду показывать, как мы с командой развиваем веб-дизайнер отчётов, отечественный аналог Jaspersoft Studio.
Начну с проблемы, которую нельзя исправить в самом JasperReports, но можно обойти в дизайнере.
При добавлении conditionalStyle Studio записывает пустую конструкцию
Раньше такая пустышка ни на что не влияла. Начиная с 6.20 она вызывает ошибку. Исправление есть только в ветке 7.x. Бэкпорта в 6.x не будет.
То есть на 6.20+ можно получить падающий отчёт на ровном месте, просто поработав со стилями в Studio. А «починить обновлением» значит перейти на семёрку, где несовместимы и JRXML, и скомпилированные
Что сделали в Report Designer. Пустой условный стиль не несёт никакой функциональной нагрузки, только ломает отчёт. Поэтому дизайнер подсказывает пользователю, что конструкция неполная, и автодополнением доводит её до корректного вида.
На этом примере хорошо видно, зачем свой дизайнер поверх JasperReports. Движок мы не контролируем. А то, как пользователь собирает шаблон, контролируем полностью, и можем не дать ему собрать заведомо сломанную конструкцию.
В среду ещё одна странность того же conditionalStyle, на этот раз с родительским стилем.
#ReportDesigner #JasperReports #Импортозамещение #JRXML
Начну с проблемы, которую нельзя исправить в самом JasperReports, но можно обойти в дизайнере.
При добавлении conditionalStyle Studio записывает пустую конструкцию
<style name="Style1">
<conditionalStyle>
<style/>
</conditionalStyle>
</style>
Раньше такая пустышка ни на что не влияла. Начиная с 6.20 она вызывает ошибку. Исправление есть только в ветке 7.x. Бэкпорта в 6.x не будет.
То есть на 6.20+ можно получить падающий отчёт на ровном месте, просто поработав со стилями в Studio. А «починить обновлением» значит перейти на семёрку, где несовместимы и JRXML, и скомпилированные
.jasper. Это уже отдельная миграция, а не патч.Что сделали в Report Designer. Пустой условный стиль не несёт никакой функциональной нагрузки, только ломает отчёт. Поэтому дизайнер подсказывает пользователю, что конструкция неполная, и автодополнением доводит её до корректного вида.
На этом примере хорошо видно, зачем свой дизайнер поверх JasperReports. Движок мы не контролируем. А то, как пользователь собирает шаблон, контролируем полностью, и можем не дать ему собрать заведомо сломанную конструкцию.
В среду ещё одна странность того же conditionalStyle, на этот раз с родительским стилем.
#ReportDesigner #JasperReports #Импортозамещение #JRXML
AI-агенты для разработчиков теперь могут самостоятельно исправлять свой код, опираясь на машинные сигналы.
Раньше AI-ассистенты могли предложить решение, но проверка его работоспособности оставалась задачей разработчика. Теперь, с внедрением обратной связи через компиляторы, тесты и статический анализ, агенты могут итерировать код до тех пор, пока он не пройдет формализованные проверки. Это значительно сокращает цикл разработки и снижает нагрузку на ревью.
Ключевые изменения, которые это влекут за собой:
1. Автоматизированная верификация: AI-агенты теперь интегрируются с инструментами сборки и тестирования. Вместо того чтобы просто "написать метод", агент может быть поставлен задача "написать метод, запустить тесты, исправить ошибки до прохождения проверок".
2. Сокращение цикла обратной связи: Компилятор мгновенно выявляет синтаксические ошибки или неправильное использование API. Тесты проверяют соответствие ожидаемому поведению. Статический анализ помогает избежать распространенных проблем. Это дает агенту возможность самостоятельно исправить код, не требуя немедленного вмешательства человека.
3. Приоритет на верификацию: Вместо бесконечного тюнинга промптов, фокус смещается на создание коротких циклов изменения и проверки. Промпт помогает понять задачу, а верификация — убедиться в ее решении по формализованным критериям.
Мой вывод: зелёная сборка — это ещё не гарантия идеального кода. Но возможность для AI-агента самостоятельно доводить код до рабочего состояния до человеческого ревью — это прорыв.
#AIAgents #CodeQuality #DeveloperTools #Testing
Раньше AI-ассистенты могли предложить решение, но проверка его работоспособности оставалась задачей разработчика. Теперь, с внедрением обратной связи через компиляторы, тесты и статический анализ, агенты могут итерировать код до тех пор, пока он не пройдет формализованные проверки. Это значительно сокращает цикл разработки и снижает нагрузку на ревью.
Ключевые изменения, которые это влекут за собой:
1. Автоматизированная верификация: AI-агенты теперь интегрируются с инструментами сборки и тестирования. Вместо того чтобы просто "написать метод", агент может быть поставлен задача "написать метод, запустить тесты, исправить ошибки до прохождения проверок".
2. Сокращение цикла обратной связи: Компилятор мгновенно выявляет синтаксические ошибки или неправильное использование API. Тесты проверяют соответствие ожидаемому поведению. Статический анализ помогает избежать распространенных проблем. Это дает агенту возможность самостоятельно исправить код, не требуя немедленного вмешательства человека.
3. Приоритет на верификацию: Вместо бесконечного тюнинга промптов, фокус смещается на создание коротких циклов изменения и проверки. Промпт помогает понять задачу, а верификация — убедиться в ее решении по формализованным критериям.
Мой вывод: зелёная сборка — это ещё не гарантия идеального кода. Но возможность для AI-агента самостоятельно доводить код до рабочего состояния до человеческого ревью — это прорыв.
#AIAgents #CodeQuality #DeveloperTools #Testing
👍3 1 1
В Jaspersoft Studio у conditionalStyle можно выбрать родительский стиль. Выбрать можно. Работать он не будет.
Наткнулись при доработке ReportDesigner. В интерфейсе Studio у условного стиля есть поле для родительского Style, его можно заполнить. Но в JRXML после этого не появляется ничего, а в самой библиотеке наследование для условного стиля тоже не срабатывает. Поле есть, функции нет.
Как устроены условные стили. conditionalStyle живёт внутри обычного стиля и при истинном условии перекрывает его атрибуты: цвет, шрифт, фон. Базовое оформление он и так берёт у стиля, внутри которого объявлен. «Наследую ещё и от вот этого» механизм не поддерживает.
Что делать, если оформление нужно переиспользовать:
- выносить общее в базовый стиль, а в условных менять только то, что отличается;
- прописывать нужные атрибуты в conditionalStyle явно, смирившись с дублированием;
- с 6.20.6 у элементов есть
Для ReportDesigner вывод простой: если поле есть в интерфейсе, пользователь ожидает, что оно работает.
Встречали в Studio другие поля, которые ни на что не влияют?
#JasperReports #JaspersoftStudio #JRXML #ReportDesigner
Наткнулись при доработке ReportDesigner. В интерфейсе Studio у условного стиля есть поле для родительского Style, его можно заполнить. Но в JRXML после этого не появляется ничего, а в самой библиотеке наследование для условного стиля тоже не срабатывает. Поле есть, функции нет.
Как устроены условные стили. conditionalStyle живёт внутри обычного стиля и при истинном условии перекрывает его атрибуты: цвет, шрифт, фон. Базовое оформление он и так берёт у стиля, внутри которого объявлен. «Наследую ещё и от вот этого» механизм не поддерживает.
Что делать, если оформление нужно переиспользовать:
- выносить общее в базовый стиль, а в условных менять только то, что отличается;
- прописывать нужные атрибуты в conditionalStyle явно, смирившись с дублированием;
- с 6.20.6 у элементов есть
styleExpression: стиль целиком выбирается выражением, а у именованных стилей наследование работает как обычно.Для ReportDesigner вывод простой: если поле есть в интерфейсе, пользователь ожидает, что оно работает.
Встречали в Studio другие поля, которые ни на что не влияют?
#JasperReports #JaspersoftStudio #JRXML #ReportDesigner
👍4
Изменение
Механизм заключается в том, как JasperReports управляет данными для
В JasperReports 6.x и более ранних версиях, а также в некоторых сценариях 7.x, поведение
В версии JasperReports 6.20.0 и выше были внесены изменения, направленные на более предсказуемое управление
Чтобы избежать проблем:
1. Проверяйте инициализацию
2. Используйте
3. Тестируйте после миграции: Если вы мигрируете с версии 6.x на 7.x, обязательно тщательно протестируйте все отчёты с
4. Изучайте документацию: Сверяйтесь с официальной документацией JasperReports по конкретной версии, которую вы используете, особенно в части работы с
Мой вывод:
#JasperReports #JaspersoftStudio #JRXML #SubDataset #ЛовушкаНедели
subDataset в JasperReports — ловушка при миграции и работе с данными. Часто встречаемая проблема — некорректное поведение данных при использовании subDataset в отчётах, особенно после обновлений версий JasperReports.Механизм заключается в том, как JasperReports управляет данными для
subDataset. В отличие от основного dataset, subDataset получает данные либо при создании JasperPrint, либо при первом обращении к нему, в зависимости от настроек. Это может привести к тому, что при повторном вызове subDataset или при изменении контекста (например, при переходе на другую запись основного dataset) данные останутся прежними или будут некорректно обновлены.В JasperReports 6.x и более ранних версиях, а также в некоторых сценариях 7.x, поведение
subDataset может зависеть от того, как он был инициализирован. Если subDataset получает данные через fillManager.fillReport() или аналогичные методы, он может кешировать результат. При использовании fillReport с параметрами, которые меняются для каждой строки основного dataset, важно убедиться, что subDataset пересоздаётся или перечитывается с новыми параметрами.В версии JasperReports 6.20.0 и выше были внесены изменения, направленные на более предсказуемое управление
subDataset, но старые шаблоны могут вести себя иначе.Чтобы избежать проблем:
1. Проверяйте инициализацию
subDataset: Убедитесь, что он получает актуальные параметры для каждого вызова. Используйте fillReport с корректными параметрами, передаваемыми из основного dataset.2. Используйте
datasetRun: Для более явного контроля над тем, когда и как subDataset получает данные, используйте элемент datasetRun. Это позволяет указать, как именно subDataset должен быть заполнен.3. Тестируйте после миграции: Если вы мигрируете с версии 6.x на 7.x, обязательно тщательно протестируйте все отчёты с
subDataset, так как поведение могло измениться. Обратите внимание на изменение атрибутов или их удаление в новых версиях.4. Изучайте документацию: Сверяйтесь с официальной документацией JasperReports по конкретной версии, которую вы используете, особенно в части работы с
subDataset и datasetRun.Мой вывод:
subDataset — мощный инструмент, но требует внимательного управления данными, чтобы избежать неожиданного поведения, особенно в сложных отчётах и при обновлении версий JasperReports.#JasperReports #JaspersoftStudio #JRXML #SubDataset #ЛовушкаНедели
На прошлой неделе я выбрал тесак вместо швейцарского ножа. Забавно, что к тесаку как раз выдали набор заточки: в Claude Code появились mods.
Mods - небольшие функции на TypeScript, которые меняют поведение Claude Code. Распространяются внутри плагинов. Часть встроенных функций теперь сама сделана как mod: например,
Это та самая гибкость, за которую я хвалил DeepSeek Harness, только с другой стороны. В dsh из плагинов собирается всё, и пока не соберёшь, работать нечем. Здесь инструмент работает из коробки, а настройка включается точечно, там, где дефолт мешает.
Мне такой порядок ближе: сначала рабочий инструмент, потом подгонка. И похоже, рынок агентов сходится к одной точке с двух сторон: гибкие harness'ы обрастают дефолтами, готовые инструменты обрастают точками расширения.
Где бы я попробовал mods первым делом: свой diff для JRXML. Стандартный построчный diff XML-шаблона читать тяжело, а изменения «сдвинули поле на 10 px» и «поменяли выражение» хочется видеть по-разному.
Одна оговорка. Mod меняет поведение агента глубже, чем промпт. Ставить чужой mod - всё равно что ставить чужой плагин в IDE с доступом ко всему коду. Сначала исходники, потом установка.
#ClaudeCode #AI #AIAgents #ClaudeMods
Mods - небольшие функции на TypeScript, которые меняют поведение Claude Code. Распространяются внутри плагинов. Часть встроенных функций теперь сама сделана как mod: например,
/diff можно выключить или заменить своей версией.Это та самая гибкость, за которую я хвалил DeepSeek Harness, только с другой стороны. В dsh из плагинов собирается всё, и пока не соберёшь, работать нечем. Здесь инструмент работает из коробки, а настройка включается точечно, там, где дефолт мешает.
Мне такой порядок ближе: сначала рабочий инструмент, потом подгонка. И похоже, рынок агентов сходится к одной точке с двух сторон: гибкие harness'ы обрастают дефолтами, готовые инструменты обрастают точками расширения.
Где бы я попробовал mods первым делом: свой diff для JRXML. Стандартный построчный diff XML-шаблона читать тяжело, а изменения «сдвинули поле на 10 px» и «поменяли выражение» хочется видеть по-разному.
Одна оговорка. Mod меняет поведение агента глубже, чем промпт. Ставить чужой mod - всё равно что ставить чужой плагин в IDE с доступом ко всему коду. Сначала исходники, потом установка.
#ClaudeCode #AI #AIAgents #ClaudeMods
👍3 2
GitHub Copilot научился принимать запросы на код-ревью через API. Теперь его проще встроить в CI/CD.
2 октября GitHub объявил о возможности запрашивать ревью кода Copilot через REST и GraphQL API. Теперь это можно делать не только вручную через интерфейс pull request, но и из собственных скриптов, рабочих процессов и внутренних инструментов.
Например, после создания PR внешний оркестратор может автоматически запросить ревью Copilot. Результат станет частью общего процесса проверки изменений, наряду с тестами и другими проверками качества.
Это не означает, что код теперь можно безопасно сливать без участия разработчика. Но интегрировать AI-ревью в существующий процесс стало проще.
Похоже, AI-инструменты постепенно переходят из категории помощников разработчика в категорию компонентов инженерной инфраструктуры.
#AICoding #GitHubCopilot #CICD #SoftwareDevelopment #DevOps
2 октября GitHub объявил о возможности запрашивать ревью кода Copilot через REST и GraphQL API. Теперь это можно делать не только вручную через интерфейс pull request, но и из собственных скриптов, рабочих процессов и внутренних инструментов.
Например, после создания PR внешний оркестратор может автоматически запросить ревью Copilot. Результат станет частью общего процесса проверки изменений, наряду с тестами и другими проверками качества.
Это не означает, что код теперь можно безопасно сливать без участия разработчика. Но интегрировать AI-ревью в существующий процесс стало проще.
Похоже, AI-инструменты постепенно переходят из категории помощников разработчика в категорию компонентов инженерной инфраструктуры.
#AICoding #GitHubCopilot #CICD #SoftwareDevelopment #DevOps
👍3🎉1 1
Java-разработчику не стоит слепо полагаться на книги по AI-агентам, если они написаны до 2023 года.
Инструменты и подходы в этой области меняются стремительно. Книга, вышедшая в 2022-м, может содержать устаревшую информацию о фреймворках или архитектурных паттернах.
Например, если книга описывает работу с AI-агентами через устаревшие версии библиотек, вроде LangChain, или не учитывает новые подходы к оркестрации агентов, её практическая ценность для современного разработчика снижается. Многие книги фокусируются на общих принципах, но детали реализации быстро устаревают.
Что стоит учитывать:
- Дата публикации: свежие издания предпочтительнее.
- Упоминаемые инструменты: проверьте актуальность версий библиотек и фреймворков.
- Фокус книги: общие концепции AI-агентов или практическое применение с конкретными инструментами.
Эта книга может быть полезна для понимания фундаментальных концепций, но для практического применения потребуется искать более актуальные ресурсы или дополнять знания самостоятельно.
Я бы сейчас сосредоточился на изучении последних версий фреймворков и практических руководств по созданию AI-агентов, а не на книгах, вышедших более года назад.
#AI #Java #Разработка #Инструменты #AIагенты
Инструменты и подходы в этой области меняются стремительно. Книга, вышедшая в 2022-м, может содержать устаревшую информацию о фреймворках или архитектурных паттернах.
Например, если книга описывает работу с AI-агентами через устаревшие версии библиотек, вроде LangChain, или не учитывает новые подходы к оркестрации агентов, её практическая ценность для современного разработчика снижается. Многие книги фокусируются на общих принципах, но детали реализации быстро устаревают.
Что стоит учитывать:
- Дата публикации: свежие издания предпочтительнее.
- Упоминаемые инструменты: проверьте актуальность версий библиотек и фреймворков.
- Фокус книги: общие концепции AI-агентов или практическое применение с конкретными инструментами.
Эта книга может быть полезна для понимания фундаментальных концепций, но для практического применения потребуется искать более актуальные ресурсы или дополнять знания самостоятельно.
Я бы сейчас сосредоточился на изучении последних версий фреймворков и практических руководств по созданию AI-агентов, а не на книгах, вышедших более года назад.
#AI #Java #Разработка #Инструменты #AIагенты
👍4 2
Здесь разбираю, почему отчёты, Java-сервисы и AI-агенты ведут себя не так, как обещает документация.
Я Анатолий, Java-разработчик (Spring, микросервисы, PostgreSQL). Много лет делаю отчёты на JasperReports / Jaspersoft Studio и участвую в разработке веб-дизайнера отчётов. В работе использую Claude Code, Codex и GigaCode.
О чём канал:
- JasperReports и BI - неочевидные детали layout, экспорта и миграций, рубрика #ЛовушкаНедели
- Java / Spring - то, что ломается не на демо, а в проде
- AI для разработчика - что реально меняют агенты и MCP, без восторгов
- иногда - книги, путешествия, спорт
С чего начать:
1. Миграция JasperReports 6.19.1 → 6.21.5 - t.me/DonToliy/142
2. Зачем делать свой аналог Jaspersoft Studio, если Jaspersoft Studio уже существует? - https://t.me/DonToliy/127
3. Claude и Codex в одной задаче - t.me/DonToliy/132
4. Lombok @Data в JPA-сущностях - t.me/DonToliy/130
5. Обрезка длинного текста: StretchHeight и splitType - t.me/DonToliy/134
Новые посты - 3-5 в неделю.
Я Анатолий, Java-разработчик (Spring, микросервисы, PostgreSQL). Много лет делаю отчёты на JasperReports / Jaspersoft Studio и участвую в разработке веб-дизайнера отчётов. В работе использую Claude Code, Codex и GigaCode.
О чём канал:
- JasperReports и BI - неочевидные детали layout, экспорта и миграций, рубрика #ЛовушкаНедели
- Java / Spring - то, что ломается не на демо, а в проде
- AI для разработчика - что реально меняют агенты и MCP, без восторгов
- иногда - книги, путешествия, спорт
С чего начать:
1. Миграция JasperReports 6.19.1 → 6.21.5 - t.me/DonToliy/142
2. Зачем делать свой аналог Jaspersoft Studio, если Jaspersoft Studio уже существует? - https://t.me/DonToliy/127
3. Claude и Codex в одной задаче - t.me/DonToliy/132
4. Lombok @Data в JPA-сущностях - t.me/DonToliy/130
5. Обрезка длинного текста: StretchHeight и splitType - t.me/DonToliy/134
Новые посты - 3-5 в неделю.
Telegram
Архитектор Хаоса
Зачем делать свой аналог Jaspersoft Studio, если Jaspersoft Studio уже существует?
Сегодня на Хабре вышла наша с Дмитрием Потаповым статья про Report Designer - браузерный редактор отчётов.
И это как раз тот случай, когда ответ «потому что захотелось написать…
Сегодня на Хабре вышла наша с Дмитрием Потаповым статья про Report Designer - браузерный редактор отчётов.
И это как раз тот случай, когда ответ «потому что захотелось написать…
👍2 1
Архитектор Хаоса pinned «Здесь разбираю, почему отчёты, Java-сервисы и AI-агенты ведут себя не так, как обещает документация. Я Анатолий, Java-разработчик (Spring, микросервисы, PostgreSQL). Много лет делаю отчёты на JasperReports / Jaspersoft Studio и участвую в разработке веб-дизайнера…»