Не удается найти класс с помощью 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();

ClassLoader:

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

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

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, может работать, но это не правильный способ сделать это.

Ссылка:

Метод 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
);

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

Другие вопросы по тегам