类构造函数无法在类加载上抛出异常 [英] Class Constructor fails throwing Exception on Class Loading

查看:219
本文介绍了类构造函数无法在类加载上抛出异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个构造函数在第一次调用 new 时失败,因为类的异常 javax.persistence.NoResultException 抓住其中一种类别的方法。



编辑:这不是NoResultException,NoResultException是Exception的消息。 stackTrace低于



如果我将导入删除到 javax.persistence.NoResultException 并且只捕获一般的例外e ,代码可以工作。



我的问题是:


  1. 为什么未调用的方法中的代码会影响构造函数? (也没有在构造函数中调用)

  2. 为什么ClassLoader抛出一个不应该抛出的异常?






    STEP OVER给了我javax.persistence.NoResultException



    我最后回到最后的代码并结束执行

    解决方案


    1. 班级在第一次访问时加载到ClassLoader中。代码中的第一个new语句将类加载到ClassLoader中,ClassLoader随后会检查它是否实际上可以访问类的所有依赖项(即NoResultException)。

    2. 你我没有明确说明ClassLoader抛出了什么,但我的猜测是它会抛出一个ClassNotFoundException,详细说明NoResultException不在你的类路径上,因此无法加载。这也是为什么当你删除有问题的导入和捕获时它起作用的原因。


    I have a constructor that fails on the first call to new because an Exception of class javax.persistence.NoResultException being catch in one of the Class' methods.

    EDIT: It was not a NoResultException, the NoResultException was the message of the Exception. The stackTrace is below

    If I remove the import to javax.persistence.NoResultException and catch just a generic Exception e, the code works.

    My questions are:

    1. Why is the code inside a method which hasn't been called is affecting the Constructor? (is not being called in the constructor either)
    2. Why is the ClassLoader throwing an exception which is not supposed to throw? ClassLoader.loadClass() throws ClassNotFoundException according to JavaDoc.

    that catch for javax.persistence.NoResultException as well as the import are old code which managed to survive between versions, I removed it and it's fixed, however I'd like to now the reason behind this.

    STACKTRACE:

    java.lang.NoClassDefFoundError: javax/persistence/NoResultException
        at xxx.xxxxxx.xxxxxxx.xxxx.xxxx.xxxxxxxxxxxx.xxxxxxxxxxxxxxx(ClassB.java)
        ...
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:619)
    Caused by: java.lang.ClassNotFoundException: javax.persistence.NoResultException
        at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
        ... 10 more
    

    Go to the end to see the step by step images of the debugger and the moment it fails

    FAILING CODE:

    // ClassB.java
    
    import javax.persistence.NoResultException; // NOTICE THE IMPORT
    
    public ClassB{
        private UserInfo user;
        private WebServiceBDelegate port;
        private Connection conn;
    
        public ClassB (UserInfo user, Connection conn) throws Exception {
            System.out.println("CLASS B CONSTRUCTOR");
            this.user = user;
            this.conn = conn;
            this.port = new WebServiceBService().getForwardingPort();
        }
    
        public boolean methodB(List<String> list){
            try{
                // Check some stuff on database using this.conn
            } catch(NoResultException nre){         // NOTICE THE CATCH
                String something = getSomething();
            }
            // Get the values to invoke SOAP service using this.conn
            status = port.operationB(values);
            if(status > 0)
                return true;
            return false;
        }
    }
    

    WORKING CODE:

    // ClassB.java
    
    public ClassB{
        private UserInfo user;
        private WebServiceBDelegate port;
        private Connection conn;
    
        public ClassB (UserInfo user, Connection conn) throws Exception {
            System.out.println("CLASS B CONSTRUCTOR");
            this.user = user;
            this.conn = conn;
            this.port = new WebServiceBService().getForwardingPort();
        }
    
        public boolean methodB(List<String> list){
            try{
                // Check some stuff on database using this.conn
            } catch(Exception e){         // THIS IS THE CHANGED CATCH
                String something = getSomething();
            }
            // Get the values to invoke SOAP service using this.conn
            status = port.operationB(values);
            if(status > 0)
                return true;
            return false;
        }
    }
    

    Here are the step by step images from the debugger when entering INTO the class constructor, to the JVM default ClassLoader and the moment it fails:

    STEP INTO when calling new ClassB gets me to loadClassInternal(String)

    STEP INTO loadClassInternal(String), gets me to loadClass(String,boolean)

    STEP INTO loadClass(String,boolean), as far as I can get, now STEP RETURN

    STEP RETURN gets me to loadClass(String)

    STEP OVER gets me to loadClassInternal(String)

    STEP OVER gives me javax.persistence.NoResultException

    STEP OVER TAKES ME BACK TO A FINALLY IN MY CODE AND ENDS EXECUTION

    解决方案

    1. The class is loaded into the ClassLoader on first access. The first 'new' statement in your code loads the class into the ClassLoader, which subsequently checks whether it actually has access to all the dependencies of your class (ie. the NoResultException).
    2. You're not making it clear what is being thrown by the ClassLoader, but my guess is it does throw a ClassNotFoundException detailing that the NoResultException is not on your classpath, so it cannot be loaded. That's also why it works when you remove the offending import and catch.

    这篇关于类构造函数无法在类加载上抛出异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆