Невозможно запустить jstatd из-за ошибки разрешения
Я пытаюсь запустить инструмент мониторинга JSTATD JVM на машине Linux
jboss@hostAddr:/usr/java/jdk1.6.0_18/bin> uname -a
Linux hostAddr 2.6.16.60-0.34-smp #1 SMP Fri Jan 16 14:59:01 UTC 2009 x86_64 x86_64 x86_64 GNU/Linux
с помощью следующей команды:
jstatd -J-Djava.security.policy=~/jstatd.all.policy
jstatd.all.policy содержание
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
К сожалению, я получаю следующий вывод:
Could not create remote object
access denied (java.util.PropertyPermission java.rmi.server.ignoreSubClasses write)
java.security.AccessControlException: access denied (java.util.PropertyPermission java.rmi.server.ignoreSubClasses write)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
at java.security.AccessController.checkPermission(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at java.lang.System.setProperty(System.java:725)
at sun.tools.jstatd.Jstatd.main(Jstatd.java:122)
По какой-то причине jstatd успешно работает в Windows с тем же файлом команды и политики.
Java-версия Linux:
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)
Версия Java для Windows:
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
12 ответов
Вот что сработало для меня:
Убедитесь, что файл tools.jar существует, и у пользователя, выполняющего команду jstatd, есть права на его чтение.
Убедитесь, что URL в
jstatd.all.policy
это указывает на tools.jar правильно и объявляет протокол (файл в этом случае). Например, в зависимости от того, гдеjava.home
переменная указывает на, вам может потребоваться удалить../
участие в пути так же, как это (я должен был):grant codebase "file:${java.home}/lib/tools.jar" { permission java.security.AllPermission; };
Начиная с Java 1.4 файл политики должен быть закодирован в UTF-8 без спецификации. EOL (CRLF против LF) не должен иметь большого значения. Пожалуйста, смотрите документ "Реализация политики по умолчанию и синтаксис файла политики" от Oracle в разделе "Изменения" для получения дополнительной информации (ссылка не указана, потому что у меня недостаточно очков репутации, чтобы опубликовать более 2 ссылок, но я уверен, что вы ' смогу найти этот документ).
Используйте абсолютный путь к файлу политики при запуске команды jstatd, например
jstatd -p 12345 -J-Djava.security.policy=/absolute-path-to/jstatd.all.policy
РЕДАКТИРОВАТЬ:
-J
Параметр больше не требуется или не поддерживается в Java 1.8, поэтому вместо этой команды:jstatd -p 12345 -Djava.security.policy=/absolute-path-to/jstatd.all.policy
(спасибо @lisak за указание на это)
Наконец, когда вы пройдете этот этап, вы можете столкнуться с другими проблемами (я это сделал), и эти посты указали мне правильное направление: использование VisualVM для мониторинга удаленного экземпляра JBoss и удаленного профилирования JBoss с использованием VisualVM. В основном вам может потребоваться использовать параметр -p, чтобы использовать другой порт, если 1099 уже используется, и добавить некоторые параметры Java в JBoss
run.conf
с помощьюJAVA_OPTS
(при условии, что вы наблюдаете за экземпляром JBoss). Все объяснено более подробно в предоставленных ссылках.
РЕДАКТИРОВАТЬ: - Указанная мертвая ссылка Использование VisualVM для мониторинга удаленного экземпляра JBoss на другой странице с тем же содержимым.
Просто нашел следующий скрипт для запуска jstatd
, Мне удалось бежать jstatd
с помощью этого скрипта https://gist.github.com/nicerobot/1375032
#!/bin/sh
policy=${HOME}/.jstatd.all.policy
[ -r ${policy} ] || cat >${policy} <<'POLICY'
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
POLICY
jstatd -J-Djava.security.policy=${policy} &
Один вкладыш, использующий подстановку процесса (хотя bashism):
jstatd -p 1099 -J-Djava.security.policy=<(echo 'grant codebase "file:${java.home}/../lib/tools.jar" {permission java.security.AllPermission;};')
Облаченный:
jstatd -p 1099 -J-Djava.security.policy=<(echo 'grant codebase "file:${java.home}/../lib/tools.jar" {permission java.security.AllPermission;};')
По состоянию на jdk1.8.0_92
, префикс опции запуска Java -J
все еще требуется.
Замечания:
Первоначальная проблема, скорее всего, из-за тильды ~
, в ~/jstatd.all.policy
, не раскрывается, следовательно, не понимается Java, в то же время либо абсолютный путь или использование ${HOME}
вместо этого должно работать.
Если вы используете Java 11, вам нужно просмотреть этот ответ: Запуск jstatd в Java 9+ -
файл политики переполнения стека выглядит следующим образом:
grant codebase "jrt:/jdk.jstatd" {
permission java.security.AllPermission;
};
Просто дополнительный пункт о предыдущих ответах, который стоил мне немного времени, чтобы выяснить.
Когда я использовал относительный путь в файле политики ${java.home}/lib/tools.jar
это фактически указывало на JAVA_HOME/jre/
каталог и так как у меня был установлен JDK, я должен был использовать ${java.home}/../lib/tools.jar
вместо этого, чтобы добраться до нужного места.
РЕДАКТИРОВАТЬ Я запускал jstatd из контейнера Docker под Ubuntu с JDK 8 (JAVA_HOME был установлен правильно).
У меня такая же проблема, и вот что вы должны сделать:
- Удостоверься что
javac
в вашем $PATH - Укажите полный (абсолютный) путь к файлу политики при запуске jstatd
jstatd -J-Djava.security.policy=/path/to/jstatd.all.policy
Это помогло мне.
Вы указали свой путь неправильно (я был)?
Попробуйте поместить политику в /tmp/jstatd.all.policy и затем запустить:
jstatd -J-Djava.security.policy=/tmp/jstatd.all.policy
Я создал новую политику со следующим содержанием:
предоставить базу кодов "file:/usr/java/latest/lib/tools.jar" {разрешение java.security.AllPermission; };
и затем запустите jstatd с этой политикой с помощью следующей команды:
jstatd -J-Djava.security.policy = / usr / java / jstatd.all.policy &
Ответ @michael nesterenko в порядке.
Но если иногда вы не можете подключиться к серверу, даже если у вас есть Jstatd, вы можете попытаться присвоить 'rmi.server.hostname'
#!/bin/sh
policy=${HOME}/.jstatd.all.policy
[ -r ${policy} ] || cat >${policy} <<'POLICY'
grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
POLICY
jstatd -J-Djava.security.policy=${policy} -J-Djava.rmi.server.hostname=192.168.x.x &
имя хоста должно быть назначено как публичный ip, если вы хотите подключиться через публичную сеть.
grant codebase "jrt:/jdk.jstatd" {
permission java.security.AllPermission;
};
grant codebase "jrt:/jdk.internal.jvmstat" {
permission java.security.AllPermission;
};
Попробуйте добавить вышеуказанное в
"C:\Program Files\Java\jdk-18.0.2.1\lib\security{policyFile}"
В дополнение к ответу LightDye вы можете открыть необходимые порты в сетевом фильтре с помощью этой команды:
for port in `netstat -nlp | grep jstatd | sed -r 's/^.*\:([0-9]{4,}).*$/\1/'`; do iptables -I INPUT 1 -p tcp --dport $port -j ACCEPT -m comment --comment jstatd; done
Или вы можете использовать ejstatd вместо jstatd
которая автоматически решает эту проблему: просто запустите ее, используя mvn exec:java
внутри папки ejstatd.
Отказ от ответственности: я являюсь автором этого инструмента с открытым исходным кодом.