Class.forName()抛出ClassNotFoundException

时间:2014-11-28 15:53:06

标签: java class classnotfoundexception

所以这是我第一次发帖,请温柔:3

概述:
我的目标是能够为我的程序提供一个XSD文件,然后程序生成一个bean,使用bean上的反射生成一个漂亮的GUI,然后我可以在文本字段中输入适当的值,然后程序用值更新bean最后将bean编组成一个漂亮的XML。

它来得非常好,但昨天我偶然发现了一个我无法弄清楚的错误..

StackTrace

java.lang.ClassNotFoundException: X.Y.Z.BEAN_FILE_WITHOUT_.JAVA
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 sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at X.Y.Z.GenerateXMLService.generateBean(GenerateXMLService.java:101)
at X.Y.Z.view.Gui$1.handle(Gui.java:56)
at X.Y.Z.view.Gui$1.handle(Gui.java:1)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
at javafx.event.Event.fireEvent(Unknown Source)
at javafx.scene.Node.fireEvent(Unknown Source)
at javafx.scene.control.Button.fire(Unknown Source)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(Unknown Source)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
at javafx.event.Event.fireEvent(Unknown Source)
at javafx.scene.Scene$MouseHandler.process(Unknown Source)
at javafx.scene.Scene$MouseHandler.access$1800(Unknown Source)
at javafx.scene.Scene.impl_processMouseEvent(Unknown Source)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
at com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
at com.sun.glass.ui.View.notifyMouse(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(Unknown Source)
at com.sun.glass.ui.win.WinApplication$4$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

generateBean

public Class generateBean(File xsd) {

    String finalDir = System.getProperty("user.dir") + "/src/main/java";
    String xsdDir = xsd.getParentFile().getAbsolutePath();

    try {
        Process p = Runtime.getRuntime().exec(
            "cmd /c cd " + xsdDir + " && xjc -d " + finalDir
                + " -p PACKAGE_PATH_GOES_HERE " + xsd.getName().toString());
        p.waitFor();

    } catch (IOException | InterruptedException e) {
        Gui.errorPopUp(e);
    }

    /**
     * Get the newly created files and put them in an array
     */
    File[] fList = new File[2];
    fList = new File("DIRECTORY_PATH_GOES_HERE").listFiles();

    /**
     * Get the file that isn't Objectfactory.java ---> that's the bean
     */
    for (File file : fList) {
        if (!"ObjectFactory.java".equals(file.getName())) {

            String beanName = file.getName();

            String beanBinaryName = "PACKAGE_PATH_GOES_HERE"
                + beanName.substring(0, beanName.length() - 5);

            Class beanClass = null;
            try {

                beanClass = Class.forName(beanBinaryName); //this is line 101
                return beanClass;

            } catch (ClassNotFoundException e) {
                Gui.errorPopUp(e);
            }

        }
    }
    return null;

}

所以我首先检查了beanBinaryName是否正确,我认为是。它具有以下格式:

com.foo.foo.some.more.foo.beanbag.bean

然后我开始在谷歌上搜索错误信息,并在这篇文章中偶然发现:
Link to the blog

但说实话,我并不真正理解他想要解释的内容。堆栈跟踪看起来很相似,但几个月前我刚刚开始使用java,并且仍然认为自己是新手。你对错误有什么建议吗?预先感谢!

编辑/解决方案:

我的第一个错误是尝试在.java文件上使用 class.forName()。这仅适用于编译文件,例如的.class。

我修复后我仍然收到错误信息,但是在玩了URLClassLoader之后它工作了:DI重命名并重构了这个方法与顶部的方法相比,所以在这一个我们真的只得到了类,而在我的第一个例子中,我也生成了.java文件。我现在采用单独的方法来保持组织有序。

public Class getClassFromBean() {

    File[] fList = new File[3];
    fList = new File("foo/beanbag").listFiles();
    Class beanClass = null;

    for (File file : fList) {

        String lastSix = file.getName().toString().substring(file.getName().length() - 6);

        if (".class".equals(lastSix)) {

            String beanBinaryName = "foo.beanbag."
                + file.getName().toString().substring(0, file.getName().toString().length() - 6);

            try {
                File root = new File(System.getProperty("user.dir") + "/src/main/java");
                URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI()
                    .toURL() });
                beanClass = Class.forName(beanBinaryName, true, classLoader);
            } catch (ClassNotFoundException | MalformedURLException e) {
                Gui.errorPopUp(e);
            }

            return beanClass;

        }

    }
    return beanClass;

}

1 个答案:

答案 0 :(得分:1)

方法Class.forName()仅适用于已编译的类,即适用于扩展名为' .class'的文件。你不能只是把' .java'文件到你的类路径。