0

更新注意:调试后,我问了另一个问题的结果:Class Constructor failed throwing Exception on Class Loading

首先,我想不出一个更好的名字来回答我的问题,我要问的是:WEIRD BEHAVIOR。如果您认为更合适的内容,请编辑。

现在,我将尽可能地简化它,遗憾的是我不能放弃给我带来问题的代码。

我有一个A 类、一个B 类和一个Z 类

A 类和 B 类非常相似,都有一个具有相同参数的构造函数,并且每个都有一个调用 SOAP Web 服务的方法,一个执行Operation A,另一个执行Operation B

现在,有什么问题?Class Z实例化两者Class AClass B然后 onsomeMethod()调用对象的方法分别执行操作 A 和 B。

由于某种原因,似乎没有调用 ClassB 的构造函数,并且从调用构造函数的那一刻起没有打印任何内容,程序永远System.out.println()挂起,我的意思是,它永远不会抛出异常或继续做任何事情。看看 A 类和 BI 类的第一行如何打印一个标志,它不为 B 类打印。

我试过的

  1. ClassZ我更改了 Class A 和 B -> RESULTS的顺序:它挂在同一个地方,现在甚至没有调用 Class A 构造函数和方法
  2. 在 ClassB 上,我评论了所有内容,并开始逐条取消评论,从 Constructor 开始,然后是 MethodB,这就是我卡住并来到这里的地方,因为我发现的内容对我和我工作场所的任何人都没有意义。结果->

    2.1如果我评论所有内容,methodB但最后返回 false 并保持 Constructor 原样,它会继续正常执行

    2.2如果我取消注释 2.1 上的所有内容,加上methodB它从 WebService 调用 operationB 并检查其结果的部分,它会继续正常执行

    2.3如果我再取消注释,当我开始使用数据库时,它就会挂起。

  3. 我检查了到数据库的连接数,它仍然有很多可用的

让我感到困惑的是,如果它与数据库相关,为什么它会像这样挂在构造函数上?

普遍事实

  1. 我正在使用 JDBC 连接到 MySQL 数据库
  2. 我有 try{}catch(Exception e){} 周围的所有内容,并且我在 e 上打印所有内容,但它只是不打印任何内容,没有抛出异常。

这是他们的样子:

A类:

// ClassA.java

public ClassA{
    private UserInfo user;
    private WebServiceADelegate port;
    private Connection conn;

    public ClassA (UserInfo user, Connection conn) throws Exception {
        System.out.println("CLASS A CONSTRUCTOR");
        this.user = user;
        this.conn = conn;
        this.port = new WebServiceAService().getForwardingPort();
    }

    public boolean methodA(List<String> list){
        // Check some stuff on database using this.conn
        // Get the values to invoke SOAP service using this.conn
        status = port.operationA(values);
        if(status > 0)
            return true;
        return false;
    }

}

B类:

// 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){
        // Check some stuff on database using this.conn
        // Get the values to invoke SOAP service using this.conn
        status = port.operationB(values);
        if(status > 0)
            return true;
        return false;
    }

}

Z类:

// ClassZ.java

public ClassZ{
    private Connection conn;
    // ...        
    // ...
    public boolean someMethod (){
        System.out.println("GONNA CALL CONSTRUCTOR ClassA");
        ClassA webservice = new ClassA(user, conn);
        System.out.println("GONNA CALL METHOD FROM ClassA");
        if (!webservice.methodA(list) ){
            return false;
        }

        System.out.println("GONNA CALL CONSTRUCTOR ClassB");
        ClassB webservice2 = new ClassB(user, conn);
        System.out.println("GONNA CALL METHOD FROM ClassB");
        if (!webservice2.methodB(list) ){
            return false;
        }
        return true;
    }
}

挂起时的最后一个输出总是:"GONNA CALL CONSTRUCTOR ClassB"

谢谢!

更新:

我调试了我的应用程序并修复了它,但它仍然很奇怪。明天我会详细说明,看看是否有人可以告诉我发生了什么。

长话短说:我javax.persistence.NoResultException在 ClassB 上导入,并且在 methodB 内部的某个点上我正在做try{}catch(NoResultException nre){ //...}......由于某种原因,当 JVM 在调用 Constructor 之前调用 ClassLoader 时,它抛出了上述异常,并且从那时起的行为很奇怪,执行结束。

涉及线程,这就是为什么我虽然挂了,但没有挂,线程结束了,我没有注意到。

附加说明:ClassB没有使用 JPA,并且它的导入和捕获不正确,一些非常旧的代码设法幸存下来。但是我认为这并不能证明错误是合理的。

我问了另一个问题,一个与调试结果有关的问题。您可以在Class Constructor failed throwing Exception on Class Loading中检查它

4

2 回答 2

1

好吧,很难用提供的信息说,但一些提示我会检查:

  1. 首先使用调试器并进入构造函数以真正确定它挂在哪里。知道它是构造函数调用是不够的。走进去。
  2. Web 服务调用很有可能挂起。所以你调用一个 webmethod,它不会永远返回。所以你的程序永远挂起。
  3. 挂起可以是任何东西,但是当您处理数据库时,挂起很可能来自数据库锁。当您没有正确提交/回滚时,您很容易在此处产生死锁。

一些疯狂的猜测,但也许它有帮助......

于 2012-07-30T17:37:23.260 回答
1
  1. 该应用程序并没有永远挂起。这段代码在另一个线程中运行,所以当它执行失败时它在我没有注意到的情况下完成。
  2. 问题实际上是在调用构造函数时。我的类路径中没有该类javax.persistence.NoResultException,因此 JVM ClassLoader 在创建实例时找不到它,并且在检查依赖项时它崩溃了。
  3. 即使调试也很难找出问题所在,因为我有很多 try{}catch(Exception e){} 但即使ClassLoader.loadClass()JVM ClassLoader 说它会抛出异常ClassLoader.loadClass() 签名是:)public Class<?> loadClass(String name) throws ClassNotFoundException它实际上是抛出一个NoClassDefFoundError,它不会扩展异常,它扩展了 Throwable,因此没有被我捕获catch(Exception e){},我必须这样做catch(Throwable t){}
  4. 至于为什么它会抛出一些不同的东西,那是因为 Java 的内部类加载是如何工作的。它比仅仅调用 loadClass 要复杂一些。它必须加载、链接、验证和初始化它。在某些时候,它应该NoClassDefFoundError在调用时抛出一个defineClass()。更多信息可以在 JLS 的执行部分找到

有关正在发生的事情的更详细答案,请在调试后检查我关于此问题的其他问题,并且接受的答案Class Constructor failed throwing Exception on Class Loading

于 2012-08-03T08:29:47.580 回答