Не удается найти класс с Class.forName(), но он существует

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

Чтобы получить класс - я знаю его имя, но его нет в пути к классам - я пробовал .forName(), но всегда получаю исключение ClassNotFoundException.

Вот мой пример:

Exception in thread "main" java.lang.ClassNotFoundException: com.test.wam.business.wsobjects.Testclass
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at gui.Application.main(Application.java:94)

И код:

URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
    DynamicURLClassLoader dynamicURLClassLoader = new DynamicURLClassLoader(urlClassLoader);
    dynamicURLClassLoader.addURL(new URL("file://C:\\dev\\Eclipse_was\\guitest\\generated"));

    Class c = Class.forName("com.test.wam.business.wsobjects.Testclass");

    Object classInstance = c.newInstance();

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

public class DynamicURLClassLoader extends URLClassLoader {

public DynamicURLClassLoader(URLClassLoader classLoader) {
    super(classLoader.getURLs());
}

@Override
public void addURL(URL url) {
    super.addURL(url);
}

}

Полное имя файла (создано с помощью eclipse -> скопировать полное имя)

/guitest/generated/com/test/wam/business/wsobjects/Testclass.java

Что здесь не так?


person Lasirana    schedule 22.09.2016    source источник
comment
но его нет в пути к классам. Это.   -  person Andy Turner    schedule 22.09.2016
comment
Class.forName нужно class файлов, Testclass.java нет.   -  person passion    schedule 22.09.2016
comment
что я могу сделать в этом случае - у меня есть только сгенерированные файлы Java и нет файлов классов?   -  person Lasirana    schedule 22.09.2016
comment
Просто создание этого DynamicURLClassLoader ничего не делает, Class.forName(...) каким-то образом автоматически не будет использовать этот загрузчик классов. И, конечно, исходный код Java должен быть сначала скомпилирован.   -  person Jesper    schedule 22.09.2016
comment
Я добавил код для DynamicURLClassLoader в вопрос   -  person Lasirana    schedule 22.09.2016


Ответы (2)


Я вижу две проблемы:

1) Вы создаете DynamicURLClassLoader и добавляете к нему URL-адрес, но на самом деле вы его не используете. Это утверждение:

 Class c = Class.forName("com.test.wam.business.wsobjects.Testclass");

будет использовать загрузчик классов, который загрузил текущий класс. Вероятно, это загрузчик классов по умолчанию для приложения, но это точно НЕ тот загрузчик классов, который вы только что создали. javadoc говорит:

[Class.forName(className)] возвращает объект Class, связанный с классом или интерфейсом с заданным строковым именем. Вызов этого метода эквивалентен:

Class.forName(className, true, currentLoader) 

где currentLoader обозначает определяющий загрузчик класса текущего класса.

Итак.... решение:

Class c = Class.forName("com.test.wam.business.wsobjects.Testclass",
                        true, dynamicURLClassLoader);

2) Эта строка:

"file://C:\\dev\\Eclipse_was\\guitest\\generated"

не является допустимым URL-адресом "file:". Правильный URL-адрес для пути, на который вы пытаетесь сослаться, будет следующим:

"file:///C:/dev/Eclipse_was/guitest/generated"

Способ, которым вы написали URL, может работать, но это неправильный способ.

Ссылка:

person Stephen C    schedule 22.09.2016

Метод Class.forName(String) использует ClassLoader класса вызывающего объекта, если вы хотите использовать определенный ClassLoader для загрузки своего класса, вам нужно использовать Class.forName(String name, boolean initialize, ClassLoader loader) вместо следующего:

Class c = Class.forName(
    "com.test.wam.business.wsobjects.Testclass", true, dynamicURLClassLoader
);

Примечание: это будет работать тогда и только тогда, когда URL, который вы предоставляете своему DynamicURLClassLoader, действителен и является путем к родительской папке, в которой находится ваш класс.

person Nicolas Filotto    schedule 22.09.2016