0

更新メモ:デバッグ後、結果について別の質問をしました: Class Constructor fails throwing Exception on Class Loading

まず、私の質問にこれ以上の名前は思いつきませんでした。これから尋ねようとしているのは、WEIRD BEHAVIORということだけです。もっと適切なものを考えたら、編集してください。

今、私はこれをできる限り単純化しようとしていますが、悲しいことに、問題を引き起こしているコードを手放すことはできません.

クラス Aクラス Bクラス Zがあります。

クラス A と Bは非常によく似ており、どちらも同じパラメーターを持つコンストラクターを持ち、それぞれに SOAP Web サービスを呼び出すメソッドがあり、一方はOperation Aを実行し、もう一方はOperation Bを実行します。

さて、何が問題なのですか?両方をClass Zインスタンス化し、次にオブジェクトのメソッドを呼び出して操作 A と操作 B をそれぞれ実行します。Class AClass BsomeMethod()

何らかの理由で ClassB のコンストラクターが呼び出されていないようで、コンストラクターが呼び出された瞬間から何も出力されず、プログラムが永久System.out.println()にハングします。クラス A とクラス BI の最初の行でフラグが出力されているのを見てください。クラス B では出力されません。

私が試したこと

  1. ClassZクラスAとBの順序を変更しました->結果同じ場所でハングし、クラスAのコンストラクターとメソッドでさえ呼び出されません
  2. ClassB では、すべてにコメントを付け、各命令のコメントを 1 つずつ外し始めました。コンストラクターから始めて、次に MethodB で、ここで行き詰まってここに来ました。結果 ->

    2.1最後に return false 以外のすべてについてコメントしmethodB、コンストラクターをそのままにしておくと、通常どおり実行が続行されます

    2.2methodB 2.1 のすべてに加えて、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"

ありがとう!

アップデート:

アプリをデバッグして修正する必要がありましたが、それでも本当に奇妙です。明日、何が起こっていたのか誰かが教えてくれるかどうかを確認するために、さらに詳しく説明します.

簡単に言えば、私は ClassB にインポートjavax.persistence.NoResultExceptionしていて、methodB 内のある時点で私が行っていたtry{}catch(NoResultException nre){ //...}...何らかの理由で、JVM がコンストラクターを呼び出す前に ClassLoader を呼び出していたときに、前述の例外がスローされ、その時点からの動作は奇妙でした。実行は終了しました。

関連するスレッドがあります。そのため、ハングしてもハングせず、スレッドが終了し、気付かなかったのです。

追加の注意: ClassBJPA を使用しておらず、インポートとそのキャッチが誤って存在し、生き残った非常に古いコードがいくつかありました。ただし、エラーを正当化するものではないと思います。

私は別の質問をしました.1つはデバッグの結果です. Class Constructor fails throwing Exception on Class Loadingで確認できます

4

2 に答える 2

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 ClassNotFoundExceptionit実際には、例外を拡張しないNoClassDefFoundErrorをスローしていましたが、 Throwableを拡張しているため、キャッチされていませんでした。catch(Exception e){}catch(Throwable t){}
  4. なぜそれが何か違うものを投げたのかというと、それはJavaの内部クラスのロードがどのように機能するかによるものです。loadClassを呼び出すよりも少し複雑です。ロード、リンク、検証、初期化する必要があります。ある時点で、NoClassDefFoundErrorを呼び出すときにをスローすることになっていdefineClass()ます。これについての詳細は、JLSの実行部分にあります。

何が起こっているのかについてのより詳細な回答については、デバッグ後にこの問題に関する他の質問を確認してください。受け入れられた回答のクラスコンストラクターがクラスの読み込み時に例外をスローできません。

于 2012-08-03T08:29:47.580 に答える
1

まあ、提供された情報で言うのは難しいですが、私が何をチェックするかについてのいくつかのヒント:

  1. 最初にデバッガーを使用、コンストラクターにステップインして、ハングする場所を実際に確認します。それがコンストラクター呼び出しであることを知っているだけでは十分ではありません。それに足を踏み入れる。
  2. Web サービス呼び出しがハングする可能性が高くなります。したがって、webmethod を呼び出すと、永遠に返されません。したがって、プログラムは永久にハングします。
  3. ハングは何でもかまいませんが、データベースを扱うときは、データベース ロックが原因でハングが発生する可能性が高くなります。適切にコミット/ロールバックしないと、ここで簡単にデッド ロックが発生する可能性があります。

いくつかのワイルドな推測ですが、役立つかもしれません...

于 2012-07-30T17:37:23.260 に答える