Действительно ли возможно иметь Системную загрузку ClassLoder .class файлы, указанные во время выполнения?

У меня есть секретное оружие: оболочка-fu.

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

Тот, который я люблю (но я обманываю немного, так как я использую то, что Python установлен в большей части системы Unix теперь):

alias webshare='python -m SimpleHTTPServer'

Теперь каждый раз Вы вводите "webshare", текущий каталог будет доступен через порт 8000. Действительно хороший, когда Вы хотите совместно использовать файлы с друзьями в локальной сети без флеш-карты или удаленного dir. Потоковое видео и музыка будут работать также.

И конечно классическая fork-бомба, которая абсолютно бесполезна, но все еще большая забава:

$ :(){ :|:& };:

не пробуют это в рабочем сервере...

5
задан Michael Petch 6 February 2017 в 17:46
поделиться

6 ответов

Почти.

Если у вас есть где-то скомпилированные классы, вы можете загрузить их с помощью URLClassLoader . Затем вы можете установить этот ClassLoader как ClassLoader для текущего потока: Thread.setContextClassLoader (ClassLoader)

Пользователи могут получить загрузчик класса контекста текущего потока и использовать его для доступа к определению класса.

5
ответ дан 18 December 2019 в 09:50
поделиться

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

2
ответ дан 18 December 2019 в 09:50
поделиться

Вы можете попытаться установить «пусковую установку» при запуске вашего приложения, которая создает URLClassLoader , передавая ему местоположения в пути к классам и ваш собственный .class размещает и запускает приложение из этого загрузчика классов.

Когда SimpleVerifier загружается с помощью URLClassLoader , он также сможет загружать классы из дополнительных мест.

2
ответ дан 18 December 2019 в 09:50
поделиться

Да, вы можете использовать URLClassLoader

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

Вот код.

void testHello() throws MalformedURLException, ClassNotFoundException {
    URL[] url = {
            new URL("file:/home/oreyes/testwork/")
    };

    try {
        new URLClassLoader(url).loadClass("Hello");
        throw new AssertionError("Should've thrown ClassNotFoundException");
    } catch ( ClassNotFoundException cnfe ){}


    c.process();// create the .class file 

    new URLClassLoader(url).loadClass("Hello");

    // it works!!
}

Взято из этого вопроса .

2
ответ дан 18 December 2019 в 09:50
поделиться

Прежде всего, ASM можно использовать таким образом, чтобы он не использовал ClassLoader для получения информации о классах.

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

  • Метод ClassWriter.getCommonSuperClass () вызывается только тогда, когда используется флаг ClassWriter.COMPUTE_FRAMES, и его можно перезаписать, чтобы не использовать ClassLoader для получения информации о классах. Вы можете найти пример этого в ClassWriterComputeFramesTest , который представляет абстракцию ClassInfo
  • . Аналогичным образом метод SimpleVerifier.getClass () используется SimpleVerifier.isAssignableFrom () , и вы можете перезаписать последний и используйте абстракцию ClassInfo, чтобы найти общий супертип. Если не ошибаюсь, Проект AspectWerkz реализовал аналогичную вещь в своем коде сопоставления с шаблоном типов. Также обратите внимание, что существует метод SimpleVerifier.setClassLoader () , который можно использовать, если вы все еще хотите загрузить свои собственные классы.

Кстати, на JVM Sun загруженные классы попадают в PermGen область и не может быть выгружена, поэтому не рекомендуется загружать классы только для целей статического анализа кода, если вы можете этого избежать, особенно если инструмент будет интегрирован в долгоживущий процесс, такой как IDE.

5
ответ дан 18 December 2019 в 09:50
поделиться

Я создал свой собственный ClassLoader, он довольно простой.

 /**
 * Used to hold the bytecode for the class to be loaded.
 */
private final static ThreadLocal<byte[]> BYTE_CODE = new ThreadLocal<byte[]>();

@Override
protected Class<?> findClass(final String name) throws ClassNotFoundException {
    final byte[] bytes = BYTE_CODE.get();
    if (null == bytes) {
        throw new ClassNotFoundException(name);
    }
    return this.defineClass(null, bytes, 0, bytes.length);
}
1
ответ дан 18 December 2019 в 09:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: