Как я могу загрузить класс из JAR-архива, который реализует мой интерфейс?(Джава) - PullRequest
0 голосов
/ 15 сентября 2010

У меня возник вопрос: я написал Java-программу, которая реализует сервис STAF (просто инфраструктура для тестирования, http://staf.sourceforge.net/).). Для STAF все мои классы должны находиться в каталоге STAF-INF / classes. Поэтому я упаковал свою программу в JAR-файл MyProg.jar, который выглядит так:

MyProg.jar

--> STAF-INF/

-------> classes/

------------> com/

----------------->/MyClass.class

----------------->/IInterface.class

---> META-INF/

Итак, мой JAR-архив получил две директории, одну с именем META-INF и с именем STAF-INF. В STAF-INF есть еще один каталог, называемый классами, а в классах есть мой пакет "com", который содержит мой класс и мой интерфейс. это ситуация. эта штука работает очень хорошо, а структура каталогов требуется для используемой мной структуры STAF.

Теперь возникает проблема: Я хочу, чтобы другие пользователи могли взять мой JAR-файл (MyProg.jar) и включить его в собственный проект для написания классов, реализующих мой интерфейс IInterface.

Проблема 1) Когда я добавляю файл MyProg.jar в Eclipse-Java-Project, он не находит IInterface. Если даже не найдете ни одного пакета в JAR-файле. Я думаю, что что-то делать с каталогами (STAF-INF / classes) ???

Проблема 2) Когда я соединяю свой новый проект в Eclipse со своим старым MyProg-проектом, Eclipse находит IInterface, и я могу его реализовать (это может быть обходной путь для проблемы 1, но :) , Затем я экспортирую свой новый класс в виде JAR-файла, назовем его NewClassForMyProg.jar. Но когда я загружаю новый класс из NewClassForMyProg.jar в моей MyProg-программе, я получаю исключение:

NoClassDefFoundError: com.IInterface

Я думаю, это как-то связано с моими каталогами. но я не уверен. Я думаю, что это может быть проблема с URLClassLoader или ClassPath, тоже ... но я понятия не имею ...

пожалуйста, помогите. спасибо.

редактирование:

вот код метода, который должен загружать классы:

    public static ArrayList<IInterface> getExternalWorkloads(String jarName, String packageName)
{
    jarName = "c:/STAF/services/NewClassForMyProg.jar";
    packageName = "com";

    packageName = packageName.replaceAll("\\." , "/");

    ArrayList<IInterface> myClasses = new ArrayList<IInterface>();

    JarInputStream jarFile = null;
    JarEntry jarEntry = null;

    try
    {
        jarFile = new JarInputStream(new FileInputStream (jarName));

        while(true) 
        {
            jarEntry=jarFile.getNextJarEntry();

            if(jarEntry == null)
                 break;

            if((jarEntry.getName ().startsWith (packageName)) &&
               (jarEntry.getName ().endsWith (".class"))) 
            {
                String classname = jarEntry.getName().replaceAll("/", "\\.");

                classname = classname.substring(0, classname.length() - 6);

                if(classname.contains("$") == false)
                {
                    ClassLoader.getSystemClassLoader();
                    URL url = new URL("jar:file:" + jarName + "!/");

                    URLClassLoader ucl = new URLClassLoader(new URL[] { url });

                        try
                        {
                            Class<IInterface> myLoadedClass = (Class<IInterface>) ucl.loadClass(classname);

                            IInterface myClass = (IInterface) myLoadedClass.newInstance();
                            myClasses.add(myClass);
                        }
                        catch(Exception e){}
                }
            }
        }

        jarFile.close();
   }
   catch(Exception e){}

   return myClasses;
}

О, и если я загружаю этим методом класс, который находится внутри моего собственного JAR (MyProg.jar), он работает отлично. Но с помощью другого JAR (например, NewClassForMyProg.jar ") я получаю сообщение об ошибке. Но метод находит классы, проблема заключается в создании нового экземпляра и приведении его к IInterface ...

1 Ответ

0 голосов
/ 16 сентября 2010

проблема решена!Я не использовал правильный загрузчик классов.

                            ClassLoader STAFLoader = MyCurrentClass.class.getClassLoader();

                            URLClassLoader URLLoader = new URLClassLoader(jarUrl, STAFLoader);

                            Class iInterfaceClass = Class.forName(classname, true, URLLoader);

Первая линия решила проблему.

...