new
クラスの例外がjavax.persistence.NoResultException
クラスのメソッドの1つでキャッチされているため、への最初の呼び出しで失敗するコンストラクターがあります。
編集:それはNoResultExceptionではなく、NoResultExceptionは例外のメッセージでした。stackTraceは以下のとおりです
インポートを削除しjavax.persistence.NoResultException
てジェネリックだけをキャッチするとException e
、コードは機能します。
私の質問は次のとおりです。
- 呼び出されていないメソッド内のコードがコンストラクターに影響を与えているのはなぜですか?(コンストラクターでも呼び出されていません)
- ClassLoaderがスローするはずのない例外をスローするのはなぜですか?ClassLoader.loadClass()
ClassNotFoundException
は、JavaDocに従ってスローします。
javax.persistence.NoResultExceptionのキャッチとインポートは、バージョン間で存続することができた古いコードであり、削除して修正しましたが、この背後にある理由を説明したいと思います。
スタックトレース:
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
最後に移動して、デバッガーのステップバイステップのイメージと失敗した瞬間を確認します
失敗したコード:
// 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;
}
}
作業コード:
// 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;
}
}
これは、クラスコンストラクターにINTOを入力するときのデバッガーから、JVMのデフォルトのClassLoaderまで、および失敗した瞬間のステップバイステップのイメージです。
新しいClassBを呼び出すときにSTEPINTOを実行すると、loadClassInternal(String)が表示されます。
STEP INTO loadClassInternal(String)、loadClass(String、boolean)に移動します
STEP INTO loadClass(String、boolean)、私が得る限り、今はSTEP RETURN
STEP RETURNを使用すると、loadClass(String) に移動します。
STEP OVERでloadClassInternal(String)に移動します
STEPOVERでjavax.persistence.NoResultExceptionが発生します
ステップオーバーすると、コードが最後に戻り、実行が終了します