无法使用Class.forName()找到Class但它存在

时间:2016-09-22 09:06:17

标签: java reflection classloader urlclassloader

我有一个程序,我在运行时生成类(仅包含变量和相关的getter和setter方法)。后来我想填写课程。

要获取类 - 我知道它的名称,但它不在类路径中 - 我尝试了.forName()但我总是得到一个ClassNotFoundException。

以下是我的例子:

Exception in thread "main" java.lang.ClassNotFoundException: com.test.wam.business.wsobjects.Testclass
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at gui.Application.main(Application.java:94)

代码:

URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
    DynamicURLClassLoader dynamicURLClassLoader = new DynamicURLClassLoader(urlClassLoader);
    dynamicURLClassLoader.addURL(new URL("file://C:\\dev\\Eclipse_was\\guitest\\generated"));

    Class c = Class.forName("com.test.wam.business.wsobjects.Testclass");

    Object classInstance = c.newInstance();

ClassLoader:

public class DynamicURLClassLoader extends URLClassLoader {

public DynamicURLClassLoader(URLClassLoader classLoader) {
    super(classLoader.getURLs());
}

@Override
public void addURL(URL url) {
    super.addURL(url);
}

}

文件的完全限定名称(使用eclipse创建 - >复制完全限定名称)

  

/guitest/generated/com/test/wam/business/wsobjects/Testclass.java

这里有什么问题?

2 个答案:

答案 0 :(得分:2)

我可以看到两个问题:

1)您正在创建 Class c = Class.forName("com.test.wam.business.wsobjects.Testclass"); 并向其添加URL,但您实际上并未使用它。这句话:

Class.forName(className)

将使用加载当前类的类加载器。这可能是应用程序的默认类加载器,但它肯定不是您刚刚创建的类加载器。 javadoc说:

  

[Class]返回与具有给定字符串名称的类或接口关联的Class.forName(className, true, currentLoader) 对象。调用此方法等同于:

currentLoader
     

其中Class c = Class.forName("com.test.wam.business.wsobjects.Testclass", true, dynamicURLClassLoader); 表示当前类的定义类加载器。

所以....解决方案是:

"file://C:\\dev\\Eclipse_was\\guitest\\generated"

2)这个字符串:

"file:///C:/dev/Eclipse_was/guitest/generated"

不是有效的"文件:" URL。您尝试引用的路径的正确URL是:

{{1}}

您编写URL 的方式可能有效,但这不是正确的方法。

参考:

答案 1 :(得分:1)

方法Class.forName(String)使用调用者类的ClassLoader,如果您想使用特定的ClassLoader加载您的课程,则需要使用Class.forName(String name, boolean initialize, ClassLoader loader)作为下一个:

Class c = Class.forName(
    "com.test.wam.business.wsobjects.Testclass", true, dynamicURLClassLoader
);

注意:只有当您提供给URL的{​​{1}}有效并且是您的课程所在的父文件夹的路径时,此功能才有效