2016-09-19 8 views
0

Я пытаюсь получить пользовательский загрузчик классов для работы с загрузкой случайных файлов .class, которые могут быть где угодно в файловой системе. Я написал мой загрузчик классов для расширения ClassLoader, переопределяет методы findClass() и loadClass() и читает в байтовом потоке файла класса. Проблема возникает при попытке вызвать ClassLoader.defineClass()Обход NoClassDefFoundError для неправильной структуры каталогов

Точная ошибка, я получаю:

Exception in thread "main" java.lang.NoClassDefFoundError: Test (wrong name: com/foo/bar/Test) 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800) 

Я знаю, что проблема заключается в том, что родная функция загрузки классов не нравится тот факт, что Test.class не живет в /someDir/com/foo/bar/. Есть ли способ сделать эту работу? У моего загрузчика классов уже есть код для проверки того, что определенный класс соответствует определенному пакету. Я действительно не понимаю, почему родной метод запретил бы это (кроме безопасности, который мне не нужен в этом прецеденте, а событие тогда, позвольте мне застрелить себя в ногу).

+0

Вы управляете классом для загрузки и, следовательно, можете его модифицировать? Если да, нужно ли имя пакета? Если нет, просто не определяйте имя пакета, тогда вы должны иметь возможность загрузить класс из любой требуемой директории. Название пакета на самом деле является частью класса и, следовательно, требует определенных механизмов manupulation байтов, таких как [Javassist] (http://jboss-javassist.github.io/javassist/) для загрузки байтов, а затем обновления представления класса перед фактическая загрузка через загрузчик классов. –

+0

Позже я обнаружил все загруженные классы в определенном пакете, поэтому я полагаюсь на имя пакета, являющегося чем-то конкретным. Однако id хотел бы разместить этот файл класса везде, где захочу, в структуре каталогов и загружать его. – bss36504

+0

Тогда взгляните на Javassit (или на другую структуру манипуляции с байтами) –

ответ

1

Собственный загрузчик классов, то есть ClassLoader.defineClass1, ничего не знает о структуре каталогов. Он просто загружает массив байтов.

В сообщении об ошибке указано, что двоичное имя, переданное как аргумент defineClass, не совпадает с фактическим именем, открытым из байтов данных класса. Самый простой способ - установить name=null при вызове defineClass.

Примечание: вы не можете изменить пакет класса, просто переведя его в другой каталог. Имя пакета встроено в данные файла класса. Вы должны либо перекомпилировать источники с правильной директивой package, либо изменить файлы байтов файлов с помощью инструментария байт-кода при загрузке.

+0

Ничего себе, я не могу поверить, что все было так просто. Кажется, это сработало, спасибо вам большое! – bss36504

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

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