Мои журналы LOG4J2 видны в разработке, но больше не видны, когда приложение установлено через MSI в рабочей среде. Журналы Hibernate записываются в обоих случаях и в правильный файл (путь указан в файле конфигурации).
Вот мой файл конфигурации log4j2.xml:
<Configuration status = "INFO" name = "2024Log4j2Config">
<Properties>
<Property name = "LOG_DIR">${sys:logs}</Property>
</Properties>
<Appenders>
<RollingFile
name = "RollingFile"
fileName = "${LOG_DIR}/app.log"
filePattern = "${LOG_DIR}/app.%d{yyyy-MM-dd--HH-mm}--%i.log.gz"
ignoreExceptions = "false">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size = "5 MB"/>
<TimeBasedTriggeringPolicy/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath = "${LOG_DIR}">
<IfFileName glob = "app.*.log.gz"/>
<IfLastModified age = "P30D"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level = "INFO">
<AppenderRef ref = "RollingFile"/>
</Root>
<Logger name = "org.hibernate" level = "DEBUG" additivity = "false">
<Appender-ref ref = "RollingFile" level = "DEBUG"/>
</Logger>
<Logger level = "INFO" name = "fr.bla.fx2024" additivity = "false">
<Appender-ref ref = "RollingFile" level = "INFO"/>
</Logger>
</Loggers>
</Configuration>
Мой код класса журнала Java:
/**
* Set the default logs' path inside a logs system property
*/
private void setCurrentDefaultLogsPathInALog4j2SystemProperty() {
System.setProperty("logs", logsFolderPath);
}
/**
* Set the current Log4j2 configuration file's path
*/
private void setCurrentLog4j2ConfigurationFilePath() {
String log4j2ConfigurationPath = Objects.requireNonNull(this.getClass().getResource(ResourcesPaths.getCONFIG_LOG4J2_PATH())).toExternalForm();
Configurator.initialize("2024Log4j2Config", log4j2ConfigurationPath);
}
Я заметил, что путь getCONFIG_LOG4J2_PATH() отличается в разработке и в продакшене, но я не понимаю, как Hibernate его находит и записывает в него свои данные и особенно как решить этот момент:
Разработчик: файл:/C:/Users/MyUser/.../log4j2.xml
Продукт: jar:file:/C:/Program%20Files/MyOrganisation/app/MyApp.jar!/fr/bla/fx2024/config/log4j2.xml
Решение (если у вас подобная проблема) состоит в том, чтобы определить недостающие модули и добавить их, либо потребовав их в определении модуля , либо путем привязки сервисов при создании среды выполнения (с помощью --bind- услуги опция). Это может быть вашей проблемой, но, скорее всего, ваша логика разрешения пути неверна. Пожалуйста, предоставьте минимально воспроизводимый пример для повторения.
Вы можете удалить ошибку упаковки во время выполнения из уравнения, протестировав выполнение файлов jar для приложения в виде модулей из командной строки, используя полную среду выполнения Java, а не упакованную. Если не работает, значит, проблема не связана с упаковкой.
Вы можете избежать необходимости устранения неполадок, изменив структуру ведения журнала на logback+slf4j вместо log4j — конечно, это может вам помочь. Вам может быть довольно сложно создать минимальный воспроизводимый пример для этого, а затем чтобы кто-то воспроизвел и отладил эту проблему, чтобы помочь вам.
@jewelsea
У меня то же самое при запуске толстой банки, созданной с помощью maven-shade, так что это не проблема jpackage.
Я перешел в Logback и использовал метод ClassLoader.getResourceAsStream() для загрузки файла конфигурации в виде потока. Этот метод предназначен для загрузки ресурсов из пути к классам, включая ресурсы внутри файлов jar.
try (InputStream inputStream = Log.class.getResourceAsStream(ResourcesPaths.getCONFIG_LOGBACK_PATH())) {
...
Я не знаю, ваша ли это проблема. При использовании jpackage или jlink создаются специальные версии JRE. Когда они это делают, они удаляют то, что не понадобится. И это нормально, если вам это действительно не нужно. Но иногда это так (например, модуль cryptoki, используемый для поддержки SSL). Обычно это происходит потому, что код модуля является необязательным и загружается во время выполнения только тогда, когда он действительно необходим, и когда среда выполнения была упакована, не было сказано, что он может понадобиться.