Java 构造函数和类的奇怪行为。应用程序永久挂起在构造函数上
更新说明:调试后,我问了另一个问题,结果是: 首先,我想不出一个更好的名字来回答我的问题,我要问的只是:奇怪的行为。如果你认为更合适,请编辑 现在,我将尽可能地简化这个过程,很遗憾,我不能给出给我带来问题的代码 我有一个a类、一个B类和一个Z类 类A和B非常相似,它们都有一个具有相同参数的构造函数,并且每个都有一个调用SOAP web服务的方法,一个用于执行操作A,另一个用于执行操作B 现在,有什么问题吗Java 构造函数和类的奇怪行为。应用程序永久挂起在构造函数上,java,Java,更新说明:调试后,我问了另一个问题,结果是: 首先,我想不出一个更好的名字来回答我的问题,我要问的只是:奇怪的行为。如果你认为更合适,请编辑 现在,我将尽可能地简化这个过程,很遗憾,我不能给出给我带来问题的代码 我有一个a类、一个B类和一个Z类 类A和B非常相似,它们都有一个具有相同参数的构造函数,并且每个都有一个调用SOAP web服务的方法,一个用于执行操作A,另一个用于执行操作B 现在,有什么问题吗Class Z实例化Class A和Class B,然后在someMethod()上调用对象
Class Z
实例化Class A
和Class B
,然后在someMethod()上调用对象的方法分别执行操作A和操作B
出于某种原因,ClassB的构造函数似乎没有被调用,并且没有System.out.println()
从调用构造函数的那一刻起打印任何内容,程序永远挂起,我是说,它从不抛出异常或继续做任何事情。看看我是如何在A类和B类的第一行打印一个标志的,它不会打印B类的标志
我尝试过的
在ClassZ
上,我更改了类A和类B的顺序->结果:它挂在同一个位置,现在甚至没有调用类A构造函数和方法
在ClassB上,我对每一条指令都进行了注释,并开始逐一取消注释,从构造函数开始,然后是MethodB,这就是我被卡住的地方,我来到这里,因为我所发现的对我和我工作场所的任何人都没有意义结果->
2.1如果我对methodB
上的所有内容都进行了注释,但最后返回false并保持构造函数的原样,则它将继续正常执行
2.2如果我对2.1中的所有内容加上methodB
中的部分都取消注释,其中它从WebService调用操作b并检查其结果,它将正常继续执行
2.3如果我再取消一点注释,当我开始处理数据库时,它会挂起
我检查了数据库的连接数,它仍然有很多可用的连接
让我困惑的是,如果它是与数据库相关的东西,为什么它会像这样挂在构造函数上?
一般事实
我正在使用JDBC连接到MySQL数据库
我有关于try{}catch(异常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;
}
}
// 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;
}
}
// 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;
}
}
挂起时的最后一个输出总是:“将调用构造函数ClassB”
谢谢
更新:
// 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;
}
}
// 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;
}
}
// 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;
}
}
我调试了我的应用程序并修复了它,但是它仍然很奇怪。明天我会详细说明,看看是否有人能告诉我发生了什么
长话短说:我在类B上导入javax.persistence.NoResultException
,在方法B内部的某个点上,我在做try{}catch(NoResultException-nre){//…}
…由于某种原因,当JVM在调用构造函数之前调用类加载器时,它抛出了前面提到的异常,此时的行为很奇怪,执行结束
有线程参与,这就是为什么我认为它挂起,它没有挂起,线程结束了,我没有注意到
另一个注意事项:ClassB没有使用JPA,导入和捕获错误地存在,一些非常旧的代码成功地保存了下来。然而,我认为这并不能证明这个错误是正确的
我问了另一个问题,一个关于调试结果的问题。您可以在中进行检查。好吧,很难说提供了哪些信息,但有些提示我将检查:
首先使用调试器,然后将步进构造函数中,以确定它挂起的位置。仅仅知道它是构造函数调用是不够的。走进去
Web服务调用挂起的可能性很大。因此,调用webmethod时,它不会永远返回。所以你的程序永远挂起
挂起可以是任何情况,但在处理数据库时,挂起很可能来自数据库锁。当您没有正确提交/回滚时,很容易在这里产生死锁
一些疯狂的猜测,但也许它有帮助
应用程序没有永远挂起。这段代码在另一个线程中运行,因此当它的执行失败时,它会在我没有注意到的情况下完成
问题实际上是在调用构造函数时。我的类路径上没有类javax.persistence.NoResultException
,因此JVM类加载器在创建实例和检查依赖项时找不到它,它崩溃了
找出问题出在哪里甚至调试都很困难,因为我有很多问题
尝试{}catch(异常e){}但即使JVM类加载器的ClassLoader.loadClass()
说它抛出了一个异常(:公共类loadClass(字符串名)抛出ClassNotFoundException
),它实际上抛出了一个不扩展异常,它扩展了Throwable,因此,我的catch(异常e){}
没有捕获,我必须执行catch(Throwable t){}
至于为什么它抛出了一些不同的东西,这是因为Java的内部类加载是如何工作的。这比打电话给loa要复杂一点