Ответ 1
Вы должны использовать AccessController.doPrivileged(), чтобы предоставить определенные права на код, которые ранее были в коде вызывающего стека, но у которых есть привилегированные коды, в силу того, что привилегия предоставляется в политике.
Например, предположим, что ClassA вызывает методы в ClassB, а ClassB должен прочитать системное свойство java.home(заимствовать из вашего примера) и предположить, что вы указали, что SecurityManager присутствует в вашем примере.
Также предположим, что ClassB загружается из jar с именем "classb.jar" (но для того, чтобы сделать пример работы ClassA, НЕ загружается из этого баннера), в файле политики безопасности должно быть указано следующее:
grant codeBase "file:/home/somebody/classb.jar" {
permission java.util.PropertyPermission "java.home", "read";
};
Теперь, когда ClassB запускается и пытается сделать System.getProperty(), который НЕ завернут в AccessController.doPrivileged() на "java.home". диспетчер безопасности проверяет стек, чтобы узнать, имеет ли каждый класс выше в стеке свойство PropertyPermission (прямо или косвенно) для "java.home". Если нет, доступ завершится неудачно.
Однако, если ClassB обертывает System.getProperty() в AccessController.doPrivileged(), менеджер безопасности только заботится о том, чтобы файл политики предоставил ClassB эту привилегию, и поэтому доступ разрешен.
Здесь фрагмент, чтобы показать это:
public void doStuff() {
try {
/*
* this will fail even if this class has permission via the policy file
* IF any caller does not have permission
*/
System.out.println(System.getProperty("java.home"));
} catch (Exception e1) {
System.out.println(e1.getMessage());
}
AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
try {
/*
* this will be allowed if this class has permission via the policy
* file even if no caller has permission
*/
System.out.println(System.getProperty("java.home"));
} catch (Exception e) {
System.out.println(e.getMessage());
}
return Boolean.TRUE;
}
});
Таким образом, в случае вашего примера вам просто нужно указать файл политики, содержащий нечто похожее на строфу гранта, на которую я ссылался выше.