Приведение из суперкласса с динамическим классом загрузки JAR - PullRequest
0 голосов
/ 08 января 2012

У меня есть несколько классов с этой организацией

--> : Inherit 

TwittEntititesNetwork --> TwitterGephiStreamer

TwittGrapher          --> TwitterGephiStreamer

TwitterGephiStreamer is Abstract 
TwitterGephiStreamer have a method : myMethod()

Directory
    ./myApp.jar
    ./NetworkLogicDirectory/TwittGrapher.jar
    ./NetworkLogicDirectory/TwittEntititesNetwork.jar

Я использую этот код для динамической загрузки классов дочерей (которые находятся в другом файле .jar)

public static TwitterGephiStreamer LoadNetworkLogicJar() throws Exception
    {
        File dir = new File(NetworkLogicDirectory);
        URL[] urls = new URL[dir.listFiles().length];
        for(int i = 0;i < dir.listFiles().length;i++)
        {
            File s = dir.listFiles()[i];
            String url  = "file:///"+s.getAbsolutePath();
            urls[i] = new URL(url);

        }
        ClassLoader = new URLClassLoader(urls);

        if(defaultProps.containsKey("NetworkLogic") &&  !defaultProps.getProperty("NetworkLogic").isEmpty())
        {
            Class<?> networkLogicClassLoader = ClassLoader.loadClass("org.naoyun.gephistream.networklogic."+defaultProps.getProperty("NetworkLogic"));
            Object object = networkLogicClassLoader.newInstance();



            return (TwitterGephiStreamer) object;
        }
        else
        {
            throw new Exception("blabalbalbal ");
        }
    }

Так что этовернуть TwitterGephiStreamer, который я могу использовать в качестве обычного класса, и я могу использовать myMethod () в обычном режиме.

Когда я запускаю eclispe, все работает хорошо, ошибок нет.

КогдаЯ экспортирую свое приложение как исполняемый файл .jar (myApp.jar), оно выдает мне эту ошибку:

java.lang.ClassCastException: org.naoyun.gephistream.networklogic.TwittEntitiesNetwork cannot be cast to org.naoyun.gephistream.TwitterGephiStreamer
        at org.naoyun.utils.ConfigurationTools.LoadNetworkLogicJar(ConfigurationTools.java:62)
        at org.naoyun.TwitterStreamer.<init>(TwitterStreamer.java:34)
        at org.naoyun.TwitterStreamer.main(TwitterStreamer.java:26)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)

Итак, я не знаю, как решить эту проблему.Мой код жуткий, но Eclispe может справиться с ним на лету, или есть другие вещи, о которых я не знаю?

Спасибо за ваше время!

Ответы [ 2 ]

0 голосов
/ 08 января 2012

Вы не должны использовать Eclipse для сборки исполняемого файла jar, а делать его вручную, например. используя скрипт сборки Ant.

Когда Eclipse создает исполняемый файл jar, он упаковывает все вместе в один пакет tidy, загружая зависимые файлы jar через свой собственный загрузчик классов, найденный в пакете "jarinjarloader", который вы видите в трассировке стека. Этот загрузчик классов не может найти ваш внешний jar, если он не является частью "omni-jar", который создает Eclipse.

Я использовал URLClassLoader в прошлом, чтобы успешно делать то, что вы пытаетесь сделать: загружать внешние файлы JAR во время выполнения. Вот вопрос о SO, который объясняет, как его использовать: Можно ли динамически «добавить» путь к классам в Java?

Этот урок должен помочь с использованием Ant для создания исполняемого jar: Создайте исполняемый файл JAR, ссылаясь на ваши зависимости

Этот учебник Ant похож и показывает, как это сделать с Eclipse, хотя он не устанавливает зависимости в манифесте. Это необходимо сделать для основных классов приложения, а не для загрузки внешних jar-файлов во время выполнения.

0 голосов
/ 08 января 2012

Возможно, вы включили org.naoyun.gephistream.TwitterGephiStreamer несколько раз в динамический путь к классам.Когда подкласс загружается, он загружает копию TwitterGephiStreamer, которая конфликтует с предыдущей загруженной копией.

Поскольку TwittGrapher.jar и TwittEntititesNetwork.jar зависят от одних и тех же базовых классов / интерфейсов (то есть TwitterGephiStreamer), я быпредлагая поместить эти типы в отдельную утилиту.Это должно помочь устранить все дублированные типы в пути к классам и обеспечить чистое дерево зависимостей jar:

           myApp
          /     \
TwittGrapher  TwittEntitiesNetwork
        \         /
         TwittUtil
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...