Java 使用 URLClassLoader 从文件加载类时出现 ClassNotFoundException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24685807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:07:21  来源:igfitidea点击:

ClassNotFoundException while loading a class from file with URLClassLoader

javareflectionurlclassloader

提问by Tony Stark

I am using the following code to create an instance of OdbcIniTargetclass which implements the Targetinterface. The OdbcIniTargetclass already exists in the application but is located in a different package and now should be loaded from the targetdirectory which is not in the class path.

我正在使用以下代码创建一个OdbcIniTarget实现该Target接口的类的实例。该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) {

    }
}

I am getting the following exception.

我收到以下异常。

java.lang.ClassNotFoundException: ch.blah.targets.nope.OdbcIniTarget
    at java.net.URLClassLoader.run(Unknown Source)
    at java.net.URLClassLoader.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 ch.blah.targets.TargetFactory.loadTargets(TargetFactory.java:74)
    at ch.blah.targets.TargetFactory.<init>(TargetFactory.java:41)
    at ch.blah.SomeOfMyClasses.<init>(SomeOfMyClasses.java:34)
    at ch.blah.TheMainClass.main(TheMainClass.java:38)

Does someone have an idea why the class is not found?

有人知道为什么找不到课程吗?

The class which is loaded looks as follows.

加载的类如下所示。

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.");
    }
}

The directory structure for targetsdirectory is as follows.

目标目录的目录结构如下。

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

采纳答案by Jigar Joshi

Problem:

问题:

It is failing to load because it doesn't contain classes at that URL, it has java source

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

Solution:

解决方案:

Compile those java classes to .class file and then pass the url to the directory which should look like

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

ch\blah\targets\nope\OdbcIniTarget.class

回答by EduSanCon

try passing the caller's classloader as a parameter in the constructor:

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

URLClassLoader classLoader = new URLClassLoader(urls, getClass().class.getClassLoader());

the class is a direct child of the dir in the url, so you need no package:

该类是 url 中 dir 的直接子类,因此您不需要包:

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