#java #command-line #tomcat8 #apache-commons
Вопрос:
Используя библиотеку командной строки Aapche commons, я пытаюсь выполнить команду openssl в веб-приложении, работающем в tomcat в ОС SLES. ниже приведен фрагмент кода —
CommandLine cmd = new CommandLine("/usr/bin/openssl")
.addArgument("genrsa")
.addArgument("-out")
.addArgument("/root/testcert_tomcat.key")
.addArgument("4096");
logger.info("Command - " cmd.toString());
DefaultExecutor executor = new DefaultExecutor();
executor.setProcessDestroyer(new ShutdownHookProcessDestroyer());
executor.setStreamHandler(new PumpStreamHandler(null, null, null));
executor.setWatchdog(new ExecuteWatchdog(60000));
executor.setExitValue(0);
try {
int exitValue = executor.execute(cmd);
if(exitValue != 0 ){
logger.info("Exit value - " exitValue);
}
} catch (IOException ex) {
logger.info("Exception - " ex.getMessage());
return false;
}
команда — тест openssl genrsa -out.ключ 4096
та же команда отлично работает при запуске из обычного кода java вне веб-приложения tomcat или непосредственно из командной строки оболочки. Если у кого-то есть какие-либо идеи, пожалуйста, предложите, в чем может быть проблема.
Поймано исключение — org.apache.commons.exec.Исключение ExecuteException: Процесс завершен с ошибкой: 1 (значение выхода: 1)
Не совсем уверен, но я попытался проверить пользователя tomcat, он работает от имени root —
libv222:/usr/share/tomcat/webapps # ps auxwww | grep -v grep | grep tomcat
tomcat 13700 27.7 12.3 3610620 498412 ? Ssl 20:20 0:46 /usr/bin/java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=5000,suspend=n -XX: HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp -Djava.security.auth.login.config=/usr/share/tomcat/conf/jaas.config -Djava.library.path=/lib/emc/powerpath/remote_tools/latest/ -XX:MaxPermSize=128M -Xms512m -Xmx1536m -classpath /usr/share/tomcat/bin/bootstrap.jar:/usr/share/tomcat/bin/tomcat-juli.jar:/usr/share/java/commons-daemon.jar -Dcatalina.base=/usr/share/tomcat -Dcatalina.home=/usr/share/tomcat -Djava.endorsed.dirs= -Djava.io.tmpdir=/var/cache/tomcat/temp -Djava.util.logging.config.file=/usr/share/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager org.apache.catalina.startup.Bootstrap start
root 16591 0.0 0.0 4244 728 pts/0 S 17:34 0:00 tail -f /var/log/tomcat/catalina.out
Комментарии:
1. Можете ли вы включить в свой вопрос исключение, которое вы получаете? Вероятно, у вас проблема с разрешениями, так как Tomcat обычно не запускается от имени,
root
а/root
папка недоступна для записи другими пользователями.2. Предложение: Вы можете зарегистрировать полную трассировку стека
ex
, а не только сообщение. Часто в полной трассировке можно найти полезную информацию.3. Обновил трассировку исключений, получив только исключение в трассировке. Можно ли запустить tomcat от имени root, чтобы проверить это поведение ?
4. Вместо того, чтобы запускать его как
root
(что, безусловно, возможно), запишите закрытый ключ в доступную папку (/tmp/testcert_tomcat.key
например) или измените разрешение папок, чтобы разрешить записьtomcat
пользователем.5. Он работал как корень и изменение разрешений при написании ключа на самом деле помогло в предыдущем случае, но когда я изменил команду openssl на — « openssl x509-req-in /tmp/ppserver.csr-out /tmp/ppserver.crt-sha256-CA /tmp/powerpath-CA.crt-CAkey /tmp/powerpath-CA.ключ-CAcreateserial-дней 821` » вызвал ту же ошибку, даже у меня теперь есть разрешения на папки. Выполнение этой команды с помощью apache common exec создает пустой файл ppserver.crt и возвращает код выхода 1.
Ответ №1:
Приведенный ниже код работал на меня, мне пришлось переключиться с Apache commons на создание процесса, чтобы заставить его работать. Похоже, для успешного выполнения нам нужно выполнить эту команду в новом процессе.
Люди предположили в комментариях, что каталог должен иметь доступ для чтения и записи везде, где это необходимо, что, безусловно, необходимо для выполнения команд.
private static boolean executeOpenSslCmdProcess(String host) {
StringBuffer command = new StringBuffer();
command.append("openssl x509 -req -in /tmp/ppserver.csr -out /tmp/ppserver.crt -sha256 -CA /tmp/powerpath-CA.crt -CAkey /tmp/powerpath-CA.key -CAcreateserial -days 821");
String[] cmd = {
"/bin/sh",
"-c",
command.toString()
};
try {
Process process = Runtime.getRuntime().exec(cmd);
InputStream inputStream = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, CHAR_SET));
result = br.lines().collect(Collectors.joining(System.lineSeparator()));
exitCode = process.waitFor();
logger.info("ExitCode : {} ", exitCode);
if (exitCode != 0) {
return false;
}
} catch (IOException ex) {
logger.info("IOException - " ex);
return false;
} catch (InterruptedException ex) {
logger.info("InterruptedException - " ex);
}
}
Спасибо за предложения в комментариях!