#java #база_данных #postgresql #spring #kotlin
Дано: БД postgresql на Mac. В ней есть данные и я могу сделать BackUp из консоли вызвав /Library/PostgreSQL/10/bin/pg_dump -U db_user_name -w -c -f my_db_name.sql my_db_name, что создаст файл my_db_name.sql в папке где я вызываю команду. Задача: Настроить периодический BackUp БД через Spring. Проблема: При вызове вышеуказанного скрипта программно получаю ошибку Файл не найден Вопрос: Как же это реализовать? Кажется, проблема в правах доступа к файлам/папкам, но непонятно какая именно и как узнать конкретно. Пробовал: Пробовал указывать абсолютный путь типа {ПУТЬ_К_ПРОЕКТУ_СПРИНГА}/my_db_name.sql или /Users/myusername/my_db_name.sql - не помогает. Код: @Scheduled(cron = "0 * * * * *") fun backUpDb() { val executeCmd = "/Library/PostgreSQL/10/bin/pg_dump -U $dbUserName -w -c -f $database.sql $database" val runtimeProcess: Process try { val pb = ProcessBuilder(executeCmd) pb.redirectOutput(Redirect.INHERIT) pb.redirectError(Redirect.INHERIT) runtimeProcess = pb.start() val processComplete = runtimeProcess.waitFor() if (processComplete == 0) { println("Backup created successfully") } else { println("Could not create the backup") } } catch (ex: Exception) { ex.printStackTrace() } } Лог: java.io.IOException: Cannot run program "/Library/PostgreSQL/10/bin/pg_dump -U db_user_name -w -c -f my_db_name.sql my_db_name": error=2, No such file or directory at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048) at ru.scp.quiz.service.quiz.QuizServiceImpl.backUpDb(QuizServiceImpl.kt:75) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65) at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: java.io.IOException: error=2, No such file or directory at java.lang.UNIXProcess.forkAndExec(Native Method) at java.lang.UNIXProcess.(UNIXProcess.java:247) at java.lang.ProcessImpl.start(ProcessImpl.java:134) at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
Ответы
Ответ 1
Проблема оказалась в том, что команда в одной строке не распознаётся и надо составлять массив из каждой её части и тогда оно работает. Т.е. надо команду в массив превратить при передаче ProcessBuilder-у: val pb = ProcessBuilder(executeCmd.split(" "))