проблема с динамической загрузкой классов в Java - PullRequest
2 голосов
/ 14 августа 2011

привет, у меня есть код, который загружает файл класса в мою программу.когда я запускаю / отлаживаю его из eclipse, я всегда выбираю файл класса из моего каталога bin.когда я скомпилировал свою программу в файл JAR, загрузка не работает.это строки, которые загружают файл класса

public void load_dynamic_tag(String file_path)
            throws MalformedURLException, ClassNotFoundException,
            InstantiationException, IllegalAccessException {
        File f = new File(file_path);// some folder's path
        URI uri = f.toURI();
        URL url = uri.toURL();
        URL[] urls = new URL[] { url };
        // create a new class loader for this directory
        ClassLoader cl = new URLClassLoader(urls);
        // load the class file "MyAlgo.class"
        String name = f.getName();
        name = name.substring(0, name.lastIndexOf("."));
        name = "Tagging." + name;
        @SuppressWarnings("unchecked")
        Class<TaggingStrategy> c = (Class<TaggingStrategy>) cl.loadClass(name);
        // TaggingStrategy tag=c.newInstance();
        tag = c.newInstance();
    }

это ошибка, которую я получаю

java.lang.ClassNotFoundException: Tagging.Tag_by_lenght_filename
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at Tagging.Tags_all.load_dynamic_tag(Tags_all.java:233)
        at Command.LoadTagCommandExecutor.execute(LoadTagCommandExecutor.java:24
)
        at GUI.DropBox$2.handleEvent(DropBox.java:248)
        at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
        at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
        at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4066)
        at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3657)
        at GUI.DropBox.showGUI(DropBox.java:168)
        at GUI.Try_control$5.handleEvent(Try_control.java:135)
        at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
        at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
        at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4066)
        at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3657)
        at GUI.Try_control.<init>(Try_control.java:161)
        at GUI.NewSWTApp$2$1$2.run(NewSWTApp.java:121)
        at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
        at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
        at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4041)
        at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3660)
        at Service.Main.main(Main.java:79)
        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)

что я делаю не так?tnx allot

Ответы [ 3 ]

1 голос
/ 14 августа 2011

Я предполагаю, что путь к файлу больше не работает, ваш класс находится внутри файла .jar, и, следовательно, обычный файл не подойдет. Что вам нужно сделать, это найти файл класса в файле .jar:

File myFile = new File(YourClass.class.getProtectionDomain().getCodeSource().getLocation().toURI()));
JarFile myJar = new JarFile(myFile);

Затем получите записи внутри банки следующим образом:

Enumeration entries = jar.entries();

Теперь смотрите документацию по Enumeration, как составить список файлов классов. (Зациклите все файлы, выберите те, которые заканчиваются на .class) Отсюда вы знаете имя класса и, следовательно, можете его загрузить.

1 голос
/ 24 июля 2014

На самом деле все, что вам нужно сделать, это поместить файл jar в путь к классу и вызвать

Class<TaggingStrategy> c = (Class<TaggingStrategy>)Class.forName("Tagging.MyAlgo");

Если "Tagging.Tag_by_lenght_filename" является правильным именем класса, который вы хотите загрузить, ваша проблема, скорее всего, заключается просто в том, что ваш jar не находится в пути к классу.

Если вы не хотите, чтобы файл jar содержался в вашем пути к классам, вам нужно создать URLClassLoader с URL-адресом, указывающим на файл jar:

URLCLassLoader myCL = new URLClassLoader(new URL[]{new File("path/to/myjar.jar").toURI().toURL()});

Если вы хотите, чтобы ваш код работал в обоих случаях, вам нужно убедиться, что ваш URL указывает на каталог bin в eclipse и указывает на файл jar, если вы хотите использовать скомпилированный файл jar.

Если вам необходимо выяснить, какие файлы классов доступны, вы можете использовать уровень абстракции FileSystem ( FileSystems ), который может создать файловую систему из каталога или файла jar.

0 голосов
/ 14 августа 2011

URLClassLoader ищет в каталогах и jar-файлах класс. Что бы вы ни указали в качестве "file_path", это должен быть путь к jar или каталогу, содержащему искомый класс. Если каталог, он должен заканчиваться на «/». Возможно, вы используете относительный путь к файлу, который будет иметь разные значения в зависимости от того, откуда он запускается. Что передается и где живет класс?

...