Проблема с Java Class.forName - PullRequest
       15

Проблема с Java Class.forName

2 голосов
/ 09 декабря 2010

Я пытаюсь использовать Class.forName для динамической загрузки класса из файла .jar в файловую систему во время выполнения.Класс, который я пытаюсь загрузить, реализует интерфейс в другом файле .jar, поэтому я использую свой собственный URLClassLoader для ссылки на два .jars.

Код работает, когда он вызывается не в контексте Интернета.app (я проверил это, скопировав и вставив метод в отдельную программу и вызвав его из main).Однако, когда я запускаю / отлаживаю веб-приложение (я использую NetBeans), код завершается ошибкой.Метод newInstance генерирует исключение ClassCastException, когда я пытаюсь привести экземпляр к интерфейсу, указанному в моем jar_file_dependencies.jar.

Вот соответствующий код, если это помогает:

       File gameJar = new File("C:\\file_path\\jar_file.jar");

       File gameDependenciesJar = new File("C:\\file_path\\jar_file_dependencies.jar");

        URLClassLoader cl = new URLClassLoader(new URL[]
                {
                    gameJar.toURI().toURL(),
                    gameDependenciesJar.toURI().toURL()
                });

        Class clazz = Class.forName("MyClass", true, cl);

        IMyClass myClass = (IMyClass)clazz.newInstance();

        System.out.println(game);

    } catch (Exception e)
    {
        System.out.println(e.getMessage());
    }

Любые предложения какпочему этот код работает в одной программе, а не в другой, будет принята с благодарностью.

Большое спасибо, Дэн

Ответы [ 2 ]

2 голосов
/ 09 декабря 2010

короткий ответ, не вдаваясь в подробности: один или оба из gameJar и gameDependenciesJar, вероятно, содержат определение класса / интерфейса IMyClass. Основное правило при использовании дочерних загрузчиков классов заключается в том, что дочерний загрузчик классов должен , а не содержать какие-либо «общие» классы - они должны существовать только в родительском загрузчике классов.

частичное объяснение: загрузчики классов веб-приложений обычно имеют политики делегирования, отличные от обычных загрузчиков классов. часто они предпочитают класс ребенка родителю. нормальные загрузчики классов обычно предпочитают родительский класс детскому. в вашем веб-приложении вы получаете два отдельных определения класса IMyClass (одно определение в родительском загрузчике классов, другое в дочернем). в вашем обычном приложении определение IMyClass в дочернем загрузчике классов игнорируется, поэтому загружается только одно определение (в родительском загрузчике классов), и все устраивает.

0 голосов
/ 09 декабря 2010

Возможно, это поможет, (не проверено) :

ClassLoader clsLoader = Thread.currentThread().getContextClassLoader();
if (clsLoader == null) {
    clsLoader = this.getClass().getClassLoader();
}

URLClassLoader cl = new URLClassLoader(new URL[]
                {
                    gameJar.toURI().toURL(),
                    gameDependenciesJar.toURI().toURL()
                }, clsLoader);

Кроме того, вы должны передать декларативное имя класса MyClass полное просто называю это MyClass в Class.forName().

Например

Class clazz = Class.forName("com.xxxx.yyy.MyClass", true, cl);
...