Я хочу реализовать приложение Java в виде демона / службы, которая работает на моем Raspberry Pi со стандартным Debian Stretch (версия ядра 4.9).
Приложение java запускается, но затем выдает исключение, поскольку оно не может прочитать важный файл конфигурации, который находится за пределами 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 /
Исключение из системного журнала:
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