Архивы рубрики: Java

Рассматриваемая система — Ubuntu 22.04. Нужно сделать так, чтобы была возможность одной командой изменить дефолтную версию java. На самом деле оно уже есть, и чтобы изменить версию java в ubuntu, нужно лишь использовать команду: Эта команда изменит ссылку файла /usr/bin/java, которая ссылается на одну из установленных версий java (обычно в директории /usr/lib/jvm). Также переменная JAVA_HOME, которая по-умолчанию ссылается на /usr/bin/java, попадёт в выбранную версию. Всё работало до того момента, когда мне понадобилось добавить GraalVm. Во-первых, GraalVm не появляется в списке update-alternatives; Во-вторых, даже если его туда добавить, то например, Intellij Idea при попытке компилляции проекта выдает ошибку: ‘gu’ tool was not found in your JAVA_HOME.This probably means that the JDK at ‘/usr/bin/java’ is not a GraalVM distribution. Проблема с граалем заключается в том, что Idea пытается найти другие бинарные файлы грааля в одной директории с файлом java из $JAVA_HOME, но их ведь нету в /usr/bin. Проблема решается тем, чтобы удалить…

Читать дальше

Различные способы логгирования JMS сообщений: 1. Логгирование внутри конвертора (Плюс в том, что будет логгироваться тело сообщения как есть. Если сообщение невозможно распарстить, то оно тоже залоггируется (если конечно это TextMessage)): 2. Логгирование внутри jmsTemplate при отправке (Тоже тело сообщения как есть): 3. Логгирование внутри @JmsListener’а (Тоже тело сообщения как есть): 4. Установка уровня логгирования для входящих сообщений (Минус в том, что логгируется объект Message целиком, и тело сообщения может просто не влезть в максимальную длину записи лога):

Т.к. в Spring Data JDBC нет стандартных хибернейтовских аннотаций типа @OneToOne, @OneToMany и @JoinColumn, то для меня было проблематично понять можно ли там вообще организовать отношения и использовать их при получении или сохранении объектов. Оказалось это делается так: One-To-One При такой реализации объект Operation без проблем вычитывается из БД уже с смапленным внутрь TaxInfo. Так же без проблем работает сохранение нового Operation с заполненным TaxInfo (корректно заполняются поля id и operationId. One-To-Many Несколько проблематично отношение один ко многим. Здесь сложность состояла в том, что я использовал List для агрегации нескольких TaxInfo, и при сохранении получал эксепшн ConstraintViolationException. Решение состояло в том, чтобы использовать Set (или Map): При такой реализации объект Operation без проблем вычитывается из БД уже с смапленными внутрь TaxInfo. Так же без проблем работает сохранение нового Operation с заполненными TaxInfo (корректно заполняются поля id и operationId. Теперь про эксепшены. У меня были проблемы именно с аннотацией @MappedCollection в…

Читать дальше

Вариант реализации JmsListenerContainerFactory (на основе DefaultJmsListenerContainerFactory) для задержки принятия следующего jms сообщения, если был выброшен необработанный эксепшен: Инициализация выглядит следующим образом

Транзакционность используется для возвращения сообщения обратно в очередь, в случае возникновения исключения при его обработке. Для настройки транзакционности, нужно указать ContainerFactory бину — бин PlatformTransactionManager. Пример настроек JMS: Для того, чтобы rollback сообщения сработал, достаточно чтобы из метода помеченного @JmsListener выбросилось необработанное исключение. Таким образом, исходное сообщение снова появится в очереди и его хэадер JMSXDeliveryCount увеличится на 1. Но здесь есть сайд-эффект, т.к. это сообщение через секунду снова залетит в приложение. Таким образом, если исключение будет постоянно появляться — мы попадём в бесконечный цикл ( есть способ задержки принятия следующего Jms сообщения после ошибки ). По поводу транзакционности, есть пара статуй от IBM: https://community.ibm.com/community/user/integration/blogs/stephanie-wilkerson1/2021/02/25/understanding-mq-backout-queues-thresholds https://www.ibm.com/docs/en/ibm-mq/9.2?topic=applications-handling-poison-messages-in-mq-classes-jms

Допустим, имеем такую DTO: А нам нужно десериализовать из такого json: То используем над полем аннотацию @JsonDeserialize(using = ProductDtoDeserializer.class) и делаем десериализатор А теперь сделаем так, чтобы строковое поле сериализовывалось в UpperCase

Протестировать ваш jsonPath можно в сервисе https://jsonpath.com/ Кроме того, просто извлечь значение согласно указанного jsonPath можно так:

Часто бывают проблемы с десериализацией дат из строки в, например, LocalDateTime. Порой это выглядит так: Есть несколько способов решить эту проблему. Один из них е использование аннотации @JsonFormat над нужным полем в dto Но бывают случаи, когда такое решение не приемлемо. Однако, есть ещё способ — кастомизация самого ObjectMapper’а. Я имею в виду про добавление модулей для сериализации/десериализации. Например, добавление модуля поддержки jsr310: Или добавление модуля поддержки joda: Наряду с этим, есть возможность писать собственные модули для сериализации/десериализации чего угодно. Не отходя от темы дат, приведу пример десериализации даты, представленной в любом из ожидаемых форматов: где классы выглядят так:

Если приложение сжирает слишком много памяти, либо сильно грузит проц, то можно на скорую руку сделать его профилирование. Ниже представлены команды, которые, при запуске на сервере, могут дать понять — в чём проблема. Отображение потребления ресурсов потокам С помощью диспетчера процессов top, можно отобразить список потоков приложения: где 20345 — это PID запущенного процесса Вашего приложения Сэмплинг Помогает найти тормозные методы в приложении. Суть метода заключается в выполнении скоупа нескольких одинаковых запросов. Каждый запрос показывает методы, в которых в данный момент находятся потоки приложения. Таким образом, если в нескольких запросах фигурирует один и тот же метод, то можно предположить, что он является очень долгим и, возможно, требует оптимизации. Команда для выполнения одного запроса: где 20345 — это PID запущенного процесса Вашего приложения (можно узнать в диспетчере процессов top), ru.knastnt — корневое имя всех пакетов в моём приложении. Это нужно чтобы показывать только методы, написанные непосредственно мной. Потому что без grep,…

Читать дальше

10/25