Java 使用URLClassLoader从文件加载类时发生ClassNotFoundException

Java 使用URLClassLoader从文件加载类时发生ClassNotFoundException,java,reflection,urlclassloader,Java,Reflection,Urlclassloader,我正在使用以下代码创建一个实现Target接口的OdbcIniTarget类的实例。OdbcIniTarget类已存在于应用程序中,但位于不同的包中,现在应该从不在类路径中的目标目录加载 ... // directory below is resolved to /D:/Workspace/<myproject>/targets/ private File targetsLocation = new File("targets"); ... private void loadTarg

我正在使用以下代码创建一个实现
Target
接口的
OdbcIniTarget
类的实例。
OdbcIniTarget
类已存在于应用程序中,但位于不同的包中,现在应该从不在类路径中的目标目录加载

...
// directory below is resolved to /D:/Workspace/<myproject>/targets/
private File targetsLocation = new File("targets");
...
private void loadTargets() {            

    URL url = null;
    try {
        url = targetsLocation.toURI().toURL();            
    } catch (MalformedURLException e) {

    }

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

    try {

     Target target =
     (Target)classLoader.
     loadClass("ch.blah.targets.nope.OdbcIniTarget").
     newInstance(); // <--- this fails hard  

    } catch (...) {
     ...
    }            

    try {
        classLoader.close();
    } catch (IOException e) {

    }
}
目标目录的目录结构如下所示

package ch.blah.targets.nope;

import org.apache.log4j.Logger;

import ch.blah.utils.Utils;

public class OdbcIniTarget extends Target {

    private static final Logger log = Logger.getLogger(OdbcIniTarget.class);    

    @Override
    public boolean someMethod1() {
        return false;
    }

    @Override
    public boolean someMethod2() {
        return false;
    }

    @Override
    public boolean someMethod3() {
        return false;
    }       

    @Override
    public void someMethod4() {
        log.debug("Blah.");
        Utils.getInstance().marshalClass(SomeClass.class);
        log.debug("Finished.");
    }
}
D:\Workspace\<myproject>\targets>dir
 Volume in drive D is DATA
 Volume Serial Number is 021C-EC9B

 Directory of D:\Workspace\<myproject>\targets

10.07.2014  21:20    <DIR>          .
10.07.2014  21:20    <DIR>          ..
10.07.2014  21:31             1'278 OdbcIniTarget.java
10.07.2014  20:23             3'761 OdbcIniTargetConfiguration.java
               2 File(s)          5'039 bytes
               2 Dir(s)   7'328'571'392 bytes free
D:\Workspace\\targets>dir
驱动器D中的卷是数据
卷序列号为021C-EC9B
D:\Workspace\\targets目录
10.07.2014  21:20              .
10.07.2014  21:20              ..
2014年7月10日21:31 1'278 OdbcIniTarget.java
2014年7月10日20:23 3'761 OdbcIniTargetConfiguration.java
2个文件5'039字节
2个目录7'328'571'392字节可用

尝试将调用方的类加载器作为构造函数中的参数传递:

URLClassLoader classLoader = new URLClassLoader(urls, getClass().class.getClassLoader());
该类是url中dir的直接子类,因此不需要包:

Target target =
 (Target)classLoader.
 loadClass("OdbcIniTarget").
 newInstance();

问题:

它无法加载,因为它在该URL不包含类,它有java源代码

解决方案:

将这些java类编译为.class文件,然后将url传递到目录,该目录如下所示

ch\blah\targets\nope\OdbcIniTarget.class

不,这也失败了。我还尝试了设置
Thread.currentThread().setContextClassLoader(classLoader)
但仍然失败。
/D:/Workspace//targets/
的树目录结构是什么?我在问题的末尾添加了树结构。请不要告诉我,用java及时编译是不可能的?!即时编译和源代码编译不同,如果你想在运行时将java编译成类,你可以使用编译器API来实现,但我想知道你想实现什么,为什么不能在执行它们之前编译呢?我想加载模块(想想插件)这种变化非常频繁,并作为Java源代码放入主应用程序的文件系统中,而无需重新编译整个应用程序。
ch\blah\targets\nope\OdbcIniTarget.class