Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Mysterious Java uncaught exception handler [with code]

Something weird has happened. I've written a Java program, where I've done nothing to handle uncaught exceptions in any special way. But when I run this one particular program in Windows 7, there is this uncaught exception in a static context called from main that causes a window to pop up, displaying the exception. I have tried to write a small program to duplicate this effect to no avail. One program (which I have written entirely by hand) produces a popup, while no others will do the same.

I'd like to track this down particularly so that I can add code that makes other CAUGHT exceptions display the stack trace in a similar way.

I've asked about this in IRC, but people tell me that this doesn't happen. Well, it DID happen. There is a screenshot below.

I think my only hope is if someone else recognizes this and can tell me where it comes from.

Thanks!

Java exception

UPDATE: Sorry for the delay getting some code. I had to attend to a colicky infant. Please note that this is a desktop Java app. It's not an applet, and it doesn't use webstart.

Here is code copied and pasted from the program that gets the dialog. I'll do another edit to let you know whether or not my colleague (who gets the exception) gets the dialog for this case. I've been careful to include everything leading up to the exception. Only the IPAddress class implementation is missing, but that doesn't participate in the exception, because it's not actually used until after the exception occurs. Note the asterisks before the line where the exception occurs. That line of code corresponds with the exception you can see in the screenshot.

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
    }
}

SECOND UPDATE: My colleague reports that this program does NOT produce the dialog. The only difference between this and the program that gets the pop-up is that the program that gets the pop-up is being launched from an exe wrapper produced by AdvancedInstaller. Besides that, within the Java program, the sequence of execution is identical. I've googled this, and as far as I can find, AdvancedInstaller does nothing at all that would result in this pop-up being generated. I'm not sure that it CAN without modifying the Java program (which it doesn't), because I'm not sure that you can do anything from outside the Java program to make this happen. Except perhaps capture stderr, but that doesn't explain why other programs wrapped by AdvancedInstaller don't produce this pop-up or why later exceptions produced by this application also do not produce this pop-up.

like image 327
Timothy Miller Avatar asked Jul 31 '12 18:07

Timothy Miller


1 Answers

2nd Answer (After additional information added to question)

Advanced Installer has a "Startup failure check" setting described as follows:

Startup failure check

Any uncaught exception from the main thread is described in a dialog box that will allow the user either to stop the application or to ignore the exception. This option applies only to GUI applications.

More info: http://www.advancedinstaller.com/user-guide/java-product-settings.html .

1st Answer

This is highly dependent on context and you have not provided enough information to get a very specific answer. The loc2.LoC2.java is likely custom or project specific code.

Generally though, the uncaught handler can be managed (or queried) via:

  • Thread.setDefaultUncaughtExceptionHandler and
  • Thread.getDefaultUncaughtExceptionHandler

More info:

  • http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.UncaughtExceptionHandler.html
like image 53
kaliatech Avatar answered Nov 09 '22 10:11

kaliatech