8

何か奇妙なことが起こった。私はJavaプログラムを作成しましたが、キャッチされなかった例外を特別な方法で処理するために何もしていません。しかし、この1つの特定のプログラムをWindows 7で実行すると、mainから呼び出された静的コンテキストでこのキャッチされない例外が発生し、ウィンドウがポップアップして例外が表示されます。私はこの効果を無駄に複製する小さなプログラムを書こうとしました。1つのプログラム(私は完全に手作業で作成しました)はポップアップを生成しますが、他のプログラムは同じことをしません。

特にこれを追跡して、他のCAUGHT例外が同様の方法でスタックトレースを表示するようにするコードを追加できるようにしたいと思います。

私はIRCでこれについて尋ねましたが、人々はこれは起こらないと私に言います。まあ、それは起こりました。以下にスクリーンショットがあります。

私の唯一の希望は、誰かがこれを認識し、それがどこから来たのかを教えてくれるかどうかだと思います。

ありがとう!

Java例外

更新:コードの取得が遅れて申し訳ありません。私は疝痛のある乳児に付き添わなければなりませんでした。これはデスクトップJavaアプリであることに注意してください。これはアプレットではなく、webstartを使用しません。

これは、ダイアログを取得するプログラムからコピーして貼り付けたコードです。別の編集を行って、私の同僚(例外を取得した人)がこの場合のダイアログを取得するかどうかを通知します。私は例外に至るまでのすべてを含めるように注意してきました。IPAddressクラスの実装のみが欠落していますが、例外が発生するまで実際には使用されないため、例外には関与しません。例外が発生する行の前のアスタリスクに注意してください。このコード行は、スクリーンショットに表示されている例外に対応しています。

package staticexception;

import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import javax.swing.UIManager;

public class StaticException {
    // Don't need this fully implemented.
    public static class IPAddress {

        public static IPAddress getBroadcast(IPAddress mask, IPAddress myip) {
            return new IPAddress();
        }

        public IPAddress() {}

        public IPAddress(int maskval) {}

        public IPAddress(byte[] addr) {}

        public IPAddress mask(IPAddress netmask) {
            return this;
        }

        public int prefixLength() {
            return 0;
        }

    }

    public static class Network {
        public IPAddress broadcast, netmask, ip;
        boolean remember;

        public Network(IPAddress br, IPAddress nm, IPAddress ip) {
            broadcast = br;
            netmask = nm;
            this.ip = ip;
        }

        boolean match(IPAddress ip) {
            IPAddress a = ip.mask(netmask);
            IPAddress b = this.ip.mask(netmask);
            return (a.equals(b));
        }

        @Override
        public String toString() {
            return ip.toString() + "/" + netmask.prefixLength();
        }
    }

    static List<Network> my_networks;

    static void enumerateNetworks() {
        my_networks = new ArrayList<Network>();

        Enumeration<NetworkInterface> nets = null;
        try {
            nets = NetworkInterface.getNetworkInterfaces();
        } catch (SocketException ex) {
            ex.printStackTrace();
        }
        for (NetworkInterface netint : Collections.list(nets)) {
            for (InterfaceAddress address : netint.getInterfaceAddresses()) {
                // *** Exception would occur on the next line when 
                // *** address.getAddress() would return null
                byte[] addr = address.getAddress().getAddress();
                if (addr.length == 4 && addr[0] != 127) {
                    int prefixlen = address.getNetworkPrefixLength();
                    int maskval = -1 << (32 - prefixlen);
                    IPAddress mask = new IPAddress(maskval);
                    //my_netmask = mask;
                    System.out.println("Netmask   = " + mask);

                    IPAddress myip = new IPAddress(addr);
                    //my_ip_address = myip;
                    System.out.println("Local IP  = " + myip);

                    IPAddress broadcast = IPAddress.getBroadcast(mask, myip);
                    System.out.println("Broadcast = " + broadcast);

                    my_networks.add(new Network(broadcast, mask, myip));

                    System.out.print(address.getAddress().getAddress().length + " ");
                    System.out.print(address.getAddress() + " ");
                    System.out.print(address.getAddress().getHostAddress() + " ");
                    System.out.println(address.getNetworkPrefixLength());
                }
            }
        }
    }

    static private void setupNetwork() {
        System.setProperty("java.net.preferIPv4Stack","true");

        enumerateNetworks();

        // ... stuff that would happen after the exception
    }

    public static void main(String[] args) {
        try {         
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());     
        } catch (Exception e) {}

        setupNetwork();

        // ... stuff that would happen after the exception
    }
}

2回目の更新:私の同僚は、このプログラムがダイアログを生成しないと報告しています。これとポップアップを取得するプログラムの唯一の違いは、ポップアップを取得するプログラムがAdvancedInstallerによって生成されたexeラッパーから起動されることです。その上、Javaプログラム内では、実行の順序は同じです。私はこれをグーグルで検索しましたが、私が知る限り、AdvancedInstallerはこのポップアップが生成される結果となるようなことは何もしていません。これを実現するためにJavaプログラムの外部から何かを実行できるかどうかわからないため、Javaプログラムを変更せずに実行できるかどうかはわかりません(変更しません)。おそらくstderrをキャプチャすることを除いて、それはAdvancedInstallerによってラップされた他のプログラムがなぜしないのかを説明していません。

4

1 に答える 1

7

2番目の回答 (質問に追加情報を追加した後)

Advanced Installerには、次のように説明されている「起動失敗チェック」設定があります。

起動失敗チェック

メインスレッドからのキャッチされなかった例外は、ユーザーがアプリケーションを停止するか、例外を無視できるようにするダイアログボックスに表示されます。このオプションは、GUIアプリケーションにのみ適用されます。

詳細:http ://www.advancedinstaller.com/user-guide/java-product-settings.html 。

最初の答え

これはコンテキストに大きく依存しており、非常に具体的な回答を得るのに十分な情報を提供していません。loc2.LoC2.javaは、カスタムコードまたはプロジェクト固有のコードである可能性があります。

ただし、一般的に、捕捉されなかったハンドラーは、次の方法で管理(または照会)できます。

  • Thread.setDefaultUncaughtExceptionHandler
  • Thread.getDefaultUncaughtExceptionHandler

より詳しい情報:

于 2012-07-31T18:59:28.003 に答える