java中动态类加载的问题

时间:2011-08-13 20:03:03

标签: java class dynamic classloader

嗨我有一个代码将类文件加载到我的程序中。当我从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分配

3 个答案:

答案 0 :(得分:1)

我的猜测是文件路径不再有效,你的类在.jar文件中,因此普通文件不会。 您需要做的是在.jar文件中找到类文件:

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

然后在jar中获取条目如下:

Enumeration entries = jar.entries();

现在,请参阅有关Enumeration如何列出类文件的文档。 (循环遍历所有文件,选择那些以.class结尾的文件)从这里,你知道了类名,因此可以加载它。

答案 1 :(得分:1)

实际上你需要做的就是将你的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指向eclipse中的bin目录并指向jar文件,以防您想要使用已编译的jar文件。

如果您需要发现哪些类文件可用,您可以使用FileSystem抽象层(FileSystems),它可以从目录或jar文件创建FileSystem。

答案 2 :(得分:0)

URLClassLoader查找类的目录和jar文件。无论你传入什么“file_path”都需要是一个包含你正在寻找的类的jar或目录的路径。如果是目录,则应以“/”结尾。也许你正在使用相对文件路径,根据它的运行位置,它会有不同的含义。传递的是什么,课程在哪里?