2012-06-19 2 views
1

Мы создаем движок, который позволит нам добавлять новые файлы jar всякий раз, загружать эти файлы jar и искать определенные функции и запускать код, который предоставляет эту функциональность. Текущий план - использовать ServiceLoader для этого (просто дополнительная деталь, я не женат на этой идее). На данный момент предположим, что мы полностью контролируем, какие файлы jar будут загружены (большое предположение - я бы предположил, что я в конце концов опубликую кое-что об этом).Запретить вызовы определенным классам в расширениях Java

Учитывая все это, я хотел бы ограничить доступ к этим расширениям определенным классам. Для поддельного примера мы хотим убедиться, что вместо использования java.io.PrintStream они используют our.better.PrintStreamSolution.

У меня действительно нет четкого представления о том, что я могу здесь сделать. Поскольку на данный момент у нас есть код, который выйдет в виде расширений, мы могли бы просто провести очень тщательные обзоры кода, но я бы предпочел сделать либо статический анализ во время установки, либо фактически выбросить ошибки во время выполнения. Любая идея, как это можно было бы сделать?

ответ

2

Вам нужно будет белым списком API. Отражающие API-интерфейсы появляются повсюду, поэтому вы не можете реалистично черным списком. Для этого вам нужно пройти через банки, используя библиотеку, такую ​​как ASM. Хотя вы можете использовать URLClassLoader с помощью специального обработчика URL-адресов, я бы предложил пользовательский загрузчик классов. Я настоятельно рекомендую избегать ничего общего с глобальным состоянием, например ServiceLoader.

+0

Что не так с ServiceLoader и что лучше/отличным способом получить класс, который реализует определенный интерфейс (или имеет известное имя, я думаю) из банки? – SirPentor

+1

@SirPentor Используется состояние ambient [global]./Возьмите имя своего класса; просмотрите его в своем загрузчике классов (укажите, какой из них); используйте 'asSubclass'; найдите «Конструктор» (не пропустите этот шаг); вызовите 'newInstance'. (Возможны варианты, такие как использование константного поля вместо конструктора.) –

1

Создайте специальный ClassLoader для чтения JAR и переопределите метод loadClass, чтобы, если загрузчик классов пытается загрузить класс из пакета java.io, он выдает SecurityException. Что-то вроде этого:

protected Class loadClass(String name, boolean resolve) 
              throws ClassNotFoundException { 
     if (name.startsWith("java.io")) 
      throw new SecurityException("java.io access not allowed on extensions"); 

     return super.loadClass(name,resolve); 
} 

Помните реализовать логику загрузки классов в переопределен метод findClass вашего ClassLoader.

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

Как показано в комментариях, альтернатива использованию SecurityManager возможна только в том случае, если менеджер безопасности может определить, что пакет подключен к внутренней линии.

+0

Пожалуйста, исправьте меня, если я ошибаюсь, но не мог расширение просто вызвать 'Object.class.getClassLoader(). LoadClass()' для обхода ваше предложение? Я уверен, что единственное решение состоит в том, чтобы возиться с SecurityManagers, но у меня тоже нет опыта, и я не думаю, что знаю кого-то, кто это делает. – Recurse

+0

Object.class.getClassLoader() должен возвращать значение null (фактически, все классы в JRE должны возвращать null, так как они были загружены загрузчиком Loadload), поэтому вы должны быть достаточно безопасными. Разумеется, они могут использовать один и тот же трюк, используя классы из вашего движка (который будет фактически загружен системным загрузчиком классов). \t Итак, да, вы правы, чек можно обойти. Так что возиться с SecurityManager это. – Soronthar

+0

Я не совсем понимаю ваш ответ, и я предполагаю, что это потому, что я недостаточно знаю об этом предмете. Любые предложения по чтению фона для этого? – SirPentor

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

  • Нет связанных вопросов^_^