2009-04-17 5 views
16

Есть ли способ полностью отключить диспетчер безопасности Java?
Как отключить диспетчер безопасности Java?

Я экспериментирую с исходным кодом db4o. Он использует отражение для сохранения объектов, и кажется, что диспетчер безопасности не позволяет отражать чтение и запись частных или защищенных полей.

Мой код:

public static void main(String[] args) throws IOException { 
    System.out.println("start"); 
    new File(DB_FILE_NAME).delete(); 
    ObjectContainer container = Db4o.openFile(DB_FILE_NAME); 
    String ob = new String("test"); 
    container.store(ob); 
    ObjectSet result = container.queryByExample(String.class); 
    System.out.println("retrieved (" + result.size() + "):"); 
    while(result.hasNext()) { 
     System.out.println(result.next()); 
    } 
    container.close(); 
    System.out.println("finish"); 
} 

Выход:

 
start 
[db4o 7.4.68.12069 2009-04-18 00:21:30] 
AccessibleObject#setAccessible() is not available. Private fields can not be stored. 
retrieved (0): 
finish 


This thread предлагает модифицировать файл java.policy, чтобы отражение, но это не похоже на работу для меня.

Я начинаю JVM с аргументами
-Djava.security.manager -Djava.security.policy==/home/pablo/.java.policy
так указанный файл политики будет только файл политики используется

файл выглядит следующим образом:

 
grant { 
    permission java.security.AllPermission; 
    permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; 
}; 

я провел последние 3 часа на это и не имеет никаких идей, как сделать эту работу. Любая помощь приветствуется.

+0

Вы пробовали вызывать setAccessible или другие привилегированные действия из своего собственного кода? –

+0

Полная командная строка также может быть полезна. –

+1

Правильны ли ваши аргументы VM? У вас, похоже, есть -Djava.security.policy ==? –

ответ

5

У вас действительно есть два знака «=» в вашей командной строке java.security.policy? Это не сработает. Убедитесь, что вы устанавливаете свойство, как

-Djava.security.policy=/home/pablo/.java.policy 

Чтобы действительно отключить SecurityManager, просто убрав свойство java.security.manager системы в целом должно быть достаточно.


Update: Как я читал документацию для файлов политики, чтобы узнать больше о «==» синтаксис, я заметил, что, если файл политики не находится в текущем рабочем каталоге, он должен быть указан как URL (включая схему). Пробовали ли вы префикс пути политики с помощью схемы «файл:»?

Я также был озадачен тем, что (при условии, что вы работаете как пользователь «pablo»), похоже, что эта политика должна быть загружена по умолчанию из вашего домашнего каталога, поэтому вам не нужно указывать ее вообще. С другой стороны, если вы не работаете как пользователь «pablo», возможно, файл не читается.

+4

Это не работает. Также не передаются аргументы JVM. BTW '==' означает, что указанный файл будет единственным используемым файлом. Single '=' означает, что файл будет использоваться вместе со стандартными файлами политики. По крайней мере, это то, что я читал. –

6

Вы можете попробовать добавить это основной() вашей программы:

System.setSecurityManager(null); 

Работал для меня «доверенного» WebStart приложение, когда я был возникли проблемы менеджера безопасности. Не уверен, что он будет работать для вашего дела db4o, но, возможно, стоит попробовать.

EDIT: Я не предполагаю, что это общее решение проблем диспетчера безопасности. Я просто предлагал это, чтобы помочь отладить проблему оригинального плаката. Очевидно, что если вы хотите воспользоваться менеджером безопасности, вы не должны его отключать.

+1

Это, как правило, не рекомендуется, поскольку он может использоваться вредоносным кодом для снятия защиты и получения привилегий локального пользователя. –

+8

Оригинальный плакат * * * «полностью отключить» менеджера безопасности! :-) –

+0

Не работает:/thanks anyway –

4

Я нашел этот пример того, как make private fields and methods accessible вашему коду. В основном, он отходит до использования поля .setAccessible (истина) и Method.setAccessible (правда) пример

поле:

Field privateStringField = PrivateObject.class. 
      getDeclaredField("privateString"); 

privateStringField.setAccessible(true); 

Метод пример:

Method privateStringMethod = PrivateObject.class. 
     getDeclaredMethod("getPrivateString", null); 

privateStringMethod.setAccessible(true); 

Вы также можете посмотреть на использование Groovy с Java кодом, как он (в настоящее время) обходит многие ограничения уровня доступа Java-кода. Хотя, это сообщение на доске объявлений, кажется, предлагает эту «функцию» may change in future versions of Groovy.

+7

Отключив диспетчера безопасности, вы получите разрешение на вызов setAccessible (true). Без отключения менеджера безопасности у вас не было бы молитвы. – extraneon

+0

@Kevin: Я могу вызвать setAccesible для личных полей в моем собственном коде. И по «моему собственному коду» я подразумеваю класс, который я добавил в источники db4o. –

+0

Вы должны иметь возможность называть это кодом, если вы не запускаете его в апплете или в какой-либо другой среде с помощью диспетчера безопасности, который может быть как раз (+1) @extraneon. Это сообщение artima имеет хорошее объяснение Java Security Manager: http://www.artima.com/underthehood/securitymanager.html –

Смежные вопросы