Я хочу реализовать Java-приложение как демон / службу, которая работает на моем Raspberry Pi со стандартным Debian Stretch (версия ядра 4.9).
Java-приложение запускается, но затем выдает исключение, поскольку оно не может прочитать важный файл конфигурации, который находится вне jar. Это сделано намеренно. Я хочу хранить файлы конфигурации вне банки.
Я запустил его, поместив файлы конфигурации в jar и прочитав их через InputStream. Но требования состоят в том, чтобы файлы конфигурации не находились внутри банки. Также работает ручной запуск jar через терминал. Права доступа к файлам должны быть в порядке, как указано в рабочем руководстве, запускающемся как root.
Я подозреваю, что во время запуска службы происходит сбой в рабочем каталоге. Другая догадка заключается в том, что навигация по файловой системе через FileInputStream вызывает проблемы.
Это мой служебный файл:
[Unit]
Description=collector
[Service]
User=root
CHDIR=/opt/servicedir/
#application.properties:
ExecStart=/usr/bin/java -jar /opt/servicedir/javaapp.jar
SuccessExitStatus=143
TimeoutStopSec=10
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Разрешения на файлы для всего в / opt / servicedir /: sudo chmod -R 770 / opt / servicedir /
Exception из системного журнала:
Aug 31 14:38:58 raspberrypi systemd[1]: myservice.service: Main process exited, code=exited, status=1/FAILURE
Aug 31 14:38:58 raspberrypi systemd[1]: myservice.service: Unit entered failed state.
Aug 31 14:38:58 raspberrypi systemd[1]: myservice.service: Failed with result 'exit-code'.
Aug 31 14:39:03 raspberrypi systemd[1]: myservice.service: Service hold-off time over, scheduling restart.
Aug 31 14:39:03 raspberrypi systemd[1]: Stopped service
Aug 31 14:39:03 raspberrypi systemd[1]: Started service
Aug 31 14:39:04 raspberrypi java[7982]: Exception in thread "main" java.lang.ExceptionInInitializerError
Aug 31 14:39:04 raspberrypi java[7982]: #011at foo.bar.Application.<clinit>(Application.java:20)
Aug 31 14:39:04 raspberrypi java[7982]: #011at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Aug 31 14:39:04 raspberrypi java[7982]: #011at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
Aug 31 14:39:04 raspberrypi java[7982]: #011at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
Aug 31 14:39:04 raspberrypi java[7982]: #011at java.lang.reflect.Method.invoke(Method.java:497)
Aug 31 14:39:04 raspberrypi java[7982]: #011at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
Aug 31 14:39:04 raspberrypi java[7982]: #011at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
Aug 31 14:39:04 raspberrypi java[7982]: #011at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
Aug 31 14:39:04 raspberrypi java[7982]: #011at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
Aug 31 14:39:04 raspberrypi java[7982]: Caused by: java.lang.RuntimeException: Failed to load credentials.properties.
Aug 31 14:39:04 raspberrypi java[7982]: #011at foo.bar.Config.<clinit>(Config.java:60)
Aug 31 14:39:04 raspberrypi java[7982]: #011... 9 more
Aug 31 14:39:04 raspberrypi java[7982]: Caused by: java.io.FileNotFoundException: ./res/credentials.properties (Datei oder Verzeichnis nicht gefunden)
Aug 31 14:39:04 raspberrypi java[7982]: #011at java.io.FileInputStream.open0(Native Method)
Aug 31 14:39:04 raspberrypi java[7982]: #011at java.io.FileInputStream.open(FileInputStream.java:195)
Aug 31 14:39:04 raspberrypi java[7982]: #011at java.io.FileInputStream.<init>(FileInputStream.java:138)
Aug 31 14:39:04 raspberrypi java[7982]: #011at java.io.FileInputStream.<init>(FileInputStream.java:93)
Aug 31 14:39:04 raspberrypi java[7982]: #011at foo.bar.Application.Config.<clinit>(Config.java:44)
Aug 31 14:39:04 raspberrypi java[7982]: #011... 9 more
Aug 31 14:39:04 raspberrypi systemd[1]: myservice.service: Main process exited, code=exited, status=1/FAILURE
Aug 31 14:39:04 raspberrypi systemd[1]: myservice.service: Unit entered failed state.
Aug 31 14:39:04 raspberrypi systemd[1]: myservice.service: Failed with result 'exit-code'.
Вот строка кода из java-кода:
// this does not work :
String credentialsFilePath = "./res/credentials.properties"
try (FileInputStream in = new FileInputStream(credentialsFilePath)) {
// this line works with the config file inside the jar
String credentialsInJar = "credentials.properties"
try (InputStream in = Config.class.getResourceAsStream(credentialsInJar)) {
Вы не установили рабочий каталог в модуле systemd. Похоже, вы намеревались установить его .
Я вижу:
CHDIR=/opt/servicedir/
Но такой опции конфигурации нет.
Чтобы установить рабочий каталог, с которого запускается служба, используйте ] WorkingDirectory =
. Например:
WorkingDirectory=/opt/servicedir