Загрузка внутренних классов во время выполнения - PullRequest
3 голосов
/ 02 августа 2011

У меня есть программа, где я компилирую код Java, который кто-то пишет в текстовое поле, и запускаю его. Они печатают полный исходный код, класс и все

Я сохраняю класс, который они пишут, в произвольный исходный файл Java, а затем компилирую и загружаю класс через загрузчик классов. Это отлично работает.

У меня появилась новая проблема, связанная с подклассами. Я даю внешнему классу уникальное имя и загружаю этот класс.

Ex.

TEMP1110.java -> TEMP1110.class и т. Д. С внутренними классами он компилируется в TEMP1110$InnerClass.class Я пытаюсь загрузить этот класс через мой загрузчик классов, но когда внешний класс вызывает его: new InnerClass().method();

это дает мне это: java.lang.NoClassDefFoundError: TEMP1110$InnerClass

Есть какая-то странность или я что-то не так делаю?

Мой загрузчик классов:

private static class JClassLoader extends ClassLoader {
    public Class buildClass(final byte[] data, final String className) {
        return (Class) defineClass(className, data, 0, data.length);
    }
}

className - TEMPCLASS$InnerClass, а данные - байты, представляющие файл класса. Это работает для внешних классов.

Ответы [ 3 ]

0 голосов
/ 02 августа 2011

Из API-спецификации похоже, что NoClassDefFoundError генерируется, когда имя, отправляемое в defineClass, не соответствует двоичному имени класса, представленного байтами.

Вы можете попробовать передать null для className для внутреннего класса.

0 голосов
/ 12 сентября 2011

Мое возможное решение с моим интерфейсом:

ClassLoader cl = new URLClassLoader(new URL[] {new File("TEMP/").toURI().toURL()});
Class classd = cl.loadClass(className);
return (I) classd.newInstance();

Раньше я использовал более старую документацию, которая только усложнила весь процесс.

0 голосов
/ 02 августа 2011

Я полагаю, что 'new InnerClass ()' использует обычную загрузку классов и поиск по пути к классам для поиска классов.Поскольку ваш сгенерированный файл .class не находится в classpath, он не может быть найден.

Попробуйте динамически изменить classpath, чтобы добавить папку, в которой находятся ваши файлы .class:

String currentPath = System.getProperty("java.library.path");
System.setProperty( "java.library.path", current + ":/path/to/my/classfiles" );

// this forces JVM to reload "java.library.path" property
Field fieldSysPath = ClassLoader.class.getDeclaredField( "sys_paths" );
fieldSysPath.setAccessible( true );
fieldSysPath.set( null, null );
...