Ошибка разрешения Java Reflection - PullRequest
5 голосов
/ 31 октября 2011

Я пытаюсь загрузить класс через URLClassLoader (ну, он также не работает с обычным загрузчиком классов) и хочу, чтобы у них не было никакого разрешения.

Поэтому я создал свой собственный менеджер безопасности, который генерирует ключ при запуске, который может быть запрошен только один раз (в основном потоке). Менеджер безопасности имеет 2 списка: applicationThread, которому будут предоставлены любые права, и временный список, которому будет предоставлено одно право только один раз (речь идет об отражении).

Поскольку это очень сложно описать, я решил загрузить все это: посмотрите на ссылку ниже

Хорошо, возвращаюсь: я создал поток WatchDog, который проверяет, не занимает ли поток слишком много времени.

Когда я сейчас начинаю копировать два класса из URLClassLoader, я вызываю ровно 30 методов без каких-либо ошибок, но при 31-м вызове он пытается проверить Разрешения для следующего, но это просто радует после 30-го вызова.

java.lang.RuntimePermission accessClassInPackage.sun.reflect),

Кто-нибудь знает, что там происходит?

редактировать: У меня было время разобрать пример. http://myxcode.at/securitymanager.zip Я обнаружил, что SecurityManager не запрашивается синхронно. Просто запустите этот маленький кусочек кода и посмотрите на красные линии.

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

Проблема более или менее в том, что мне нужен менеджер безопасности для синхронизации. Вот мой вывод для тех, кто не может столкнуться с ошибкой (ошибка?) http://pastebin.com/E9yLRLif

edit2: может, речь идет о консоли? может консоль слишком медленная?

1 Ответ

4 голосов
/ 03 ноября 2011

Для меня проверка происходит, когда i=15:

checkPermission ((java.lang.RuntimePermission accessClassInPackage.sun.reflect)) для потока [main, 5, main]

Причиной отложенной проверки прав доступа является inflationThreshold класса ReflectionFactory, который используется методом invoke NativeMethodAccessorImpl.java:

public Object invoke(Object obj, Object[] args)
        throws IllegalArgumentException, InvocationTargetException {
    if (++numInvocations > ReflectionFactory.inflationThreshold()) {
        MethodAccessorImpl acc = (MethodAccessorImpl) new MethodAccessorGenerator()
                .generateMethod(method.getDeclaringClass(), method
                        .getName(), method.getParameterTypes(),
                        method.getReturnType(), method
                                .getExceptionTypes(), method
                                .getModifiers());
        parent.setDelegate(acc);
    }

    return invoke0(method, obj, args);
}

Чтобы отключить задержку, вы можете использовать Reflection API:)

Field hack = Class.forName("sun.reflect.ReflectionFactory").getDeclaredField("inflationThreshold");
hack.setAccessible(true);
hack.set(null, 0);
...