Как определить время ClassLoading - PullRequest
3 голосов
/ 06 апреля 2011

У меня есть TrirdParty API, который содержит CLass [скажем, A]. У этого есть странный статический блок, подобный следующему:

class A
{
    static
    {
        try
        {
            System.loadLibrary("libraryName");
        }
        catch(UnsatisfiedLinkError ue)
        {
            System.exit(0);
        }
    }

    //other stuff
}

Я хочу запретить вызов System.exit() с переопределением SecurityManager. Однако я хочу переопределить SecurityManager непосредственно перед тем, как этот блок static будет выполнен, и сразу после этого я хочу восстановить исходный менеджер безопасности.

Я знаю, как заменить / переопределить / восстановить SecurityManager.

Моя проблема в том, как определить, когда будет вызываться блок static [в основном, когда класс будет загружен), так что перед этим я буду использовать свой собственный SecurityManager для предотвращения System.exit() и после восстановить оригинал SecurityManager.

Обратите внимание, что важно переопределить диспетчер безопасности только на время выполнения статического блока.

EDIT:

Смена источника невозможна по причинам лицензирования.

Ответы [ 2 ]

1 голос
/ 06 апреля 2011

почему вы не можете просто заменить статический блок {} на тот, который вам нужен, с помощью некоторой библиотеки обработки байт-кода, такой как Javassist?

0 голосов
/ 06 апреля 2011

Я думаю, что вы в основном напичканы.

Да, (по крайней мере, в теории) можно заблокировать вызов System.exit() через менеджер безопасности.Но что происходит потом?

  1. Статический инициализатор в классе пытается вызвать System.exit().
  2. SecurityManager говорит, что вы не можете, и выдает исключение SecurityException
  3. Статическая инициализацияСбой класса с неперехваченным исключением
  4. Сбой инициализации класса, который вы первоначально пытались инициализировать (неявно).

Теоретически вы можете поймать исключение.Но это не очень далеко, потому что JVM только попытается выполнить статическую инициализацию один раз.Если это не удается, и вы пытаетесь снова, JVM просто выдаст ClassNotFoundError (я думаю), повторяя исходное исключение как причину.

Единственный способ заставить инициализацию класса повториться, это1022 * выбросить загрузчик классов, который первым загрузил нарушающие классы, создать новый и снова начать загрузку.И тогда вы вернетесь к исходной проблеме.

Итог: если вы действительно не можете изменить код, вы набиты.


Даже если бы вы могли сделать эту работу,это звучит как плохое решение / не решение вашей проблемы.Исключение LinkageError означает, что библиотеке не удалось загрузить собственную библиотеку, и что соответствующие вызовы метода native в библиотеку завершатся с Error.В лучшем случае вы получите библиотеку, в которой некоторые биты работают, а другие нет.

Вам следует сосредоточиться на получении правильной собственной библиотеки для вашей платформы и / или настройке JVM, чтобы она могла ее найти.,Или найти лучшую альтернативу сторонней библиотеке, которая не обременена навязчивой ерундой принудительного применения лицензий.

...