0

I have try catch blocks in the init() method. But i want to throw them towards the consuming class.

However, if I remove the try catch blocks and add the throws declaration for the method. I have to add it for the constructor and for the getInstance method also.

But running my application again gives me errors on where i removed the try catch blocks. I didn't got these errors before. And for the other methods with exception throwing, not being called in the constructor, there is no problem.

Any idea how to handle this correctly? Thanks in advance.

I also allready looked here: Singleton and Exception

But it did not help.

public class Communicator {
    private static Communicator instance = null;

    protected Communicator() {
        init();
    }

    public static Communicator getInstance() {
        if (instance == null) {
            instance = new Communicator();
        }
        return instance;
    }

    public void init() {
        // set up connections
    }
}

Okay so because there is a need for more specifics: this is the full code withouth the extra methods that can throw an exception=>

public class WindowsMidiCommunicator {
    private MidiDevice.Info[] devices;
    private MidiDevice outputDevice = null;
    private Receiver recvr = null;
    private MidiDevice inputDevice = null;
    private Transmitter trans = null;
    private DumpReceiver outputReceiverDump;
    private Logger log;
    private MessageQueue<Message> queue = null;
    private static WindowsMidiCommunicator instance=null;
    protected WindowsMidiCommunicator() {
        init();
    }
    public static WindowsMidiCommunicator getInstance(){
        if(instance==null){
            instance=new WindowsMidiCommunicator();
        }
        return instance;
    }
    public void init() {
        devices = MidiSystem.getMidiDeviceInfo();
        outputReceiverDump = new DumpReceiver(System.out);
        queue = new MessageQueue<Message>();
        outputReceiverDump.setMessageQueue(queue);
        Logger log = LogManager.getLogger(Saffiretest.class.getName());

        for (MidiDevice.Info info : devices) {
            if (info.getName().contains("Saffire")) {
                MidiDevice device = null;
                try {
                    device = MidiSystem.getMidiDevice(info);
                } catch (MidiUnavailableException e1) {
                    log.error("MidiUnavailableException");
                    e1.printStackTrace();
                }
                if (!device.isOpen()) {
                    try {
                        device.open();
                    } catch (MidiUnavailableException e) {
                        log.error("MidiUnavailableException");
                        e.printStackTrace();
                    }
                }
                if (device instanceof Sequencer) {
                    log.info("Device is a Sequencer");
                }
                if (device instanceof Synthesizer) {
                    log.info("Device is a Synthesizer");
                }
                log.info("Max receivers:" + device.getMaxReceivers());
                if (device.getMaxReceivers() == -1) {
                    outputDevice = device;
                    log.info(device.getDeviceInfo().getName()
                            + "obtained as outputDevice");
                }
                if (device.getMaxTransmitters() == -1) {
                    inputDevice = device;
                    log.info(device.getDeviceInfo().getName()
                            + "obtained as inputDevice");
                }
                log.info("Max transmitters:" + device.getMaxTransmitters());
                log.info("Open receivers:");
                List<Receiver> receivers = device.getReceivers();
                for (Receiver r : receivers) {
                    log.info(r.toString());
                }
                try {
                    log.info("Default receiver: "
                            + device.getReceiver().toString());

                    log.info("Open receivers now:");
                    receivers = device.getReceivers();
                    for (Receiver r : receivers) {
                        log.info(r.toString());
                    }
                } catch (MidiUnavailableException e) {
                    log.info("No default receiver");
                }

                log.info("Open transmitters:");
                List<Transmitter> transmitters = device.getTransmitters();
                for (Transmitter t : transmitters) {
                    log.info(t.toString());
                }
                try {
                    log.info("Default transmitter: "
                            + device.getTransmitter().toString());

                    log.info("Open transmitters now:");
                    transmitters = device.getTransmitters();
                    for (Transmitter t : transmitters) {
                        log.info(t.toString());
                    }
                } catch (MidiUnavailableException e) {
                    log.error("No default transmitter");
                }
            }
        }
        try {
            recvr = outputDevice.getReceiver();
        } catch (MidiUnavailableException e) {
            log.error("no receiver available");
            e.printStackTrace();
        }
        try {
            trans = inputDevice.getTransmitter();
            trans.setReceiver(outputReceiverDump);
        } catch (MidiUnavailableException e) {
            log.error("no transmitter available");
            e.printStackTrace();
        }

    }

Now when removing all of those try catch blocks i'll end up like this:

protected WindowsMidiCommunicator() throws MidiUnavailableException {
        init();
    }
    public static WindowsMidiCommunicator getInstance() throws MidiUnavailableException{
        if(instance==null){
            instance=new WindowsMidiCommunicator();
        }
        return instance;
    }
    public void init() throws MidiUnavailableException {
        devices = MidiSystem.getMidiDeviceInfo();
        outputReceiverDump = new DumpReceiver(System.out);
        queue = new MessageQueue<Message>();
        outputReceiverDump.setMessageQueue(queue);
        Logger log = LogManager.getLogger(Saffiretest.class.getName());

        for (MidiDevice.Info info : devices) {
            if (info.getName().contains("Saffire")) {
                MidiDevice device = null;

                    device = MidiSystem.getMidiDevice(info);

                if (!device.isOpen()) {

                        device.open();

                }
                if (device instanceof Sequencer) {
                    log.info("Device is a Sequencer");
                }
                if (device instanceof Synthesizer) {
                    log.info("Device is a Synthesizer");
                }
                log.info("Max receivers:" + device.getMaxReceivers());
                if (device.getMaxReceivers() == -1) {
                    outputDevice = device;
                    log.info(device.getDeviceInfo().getName()
                            + "obtained as outputDevice");
                }
                if (device.getMaxTransmitters() == -1) {
                    inputDevice = device;
                    log.info(device.getDeviceInfo().getName()
                            + "obtained as inputDevice");
                }
                log.info("Max transmitters:" + device.getMaxTransmitters());
                log.info("Open receivers:");
                List<Receiver> receivers = device.getReceivers();
                for (Receiver r : receivers) {
                    log.info(r.toString());
                }

                    log.info("Default receiver: "
                            + device.getReceiver().toString());

                    log.info("Open receivers now:");
                    receivers = device.getReceivers();
                    for (Receiver r : receivers) {
                        log.info(r.toString());
                    }


                log.info("Open transmitters:");
                List<Transmitter> transmitters = device.getTransmitters();
                for (Transmitter t : transmitters) {
                    log.info(t.toString());
                }

                    log.info("Default transmitter: "
                            + device.getTransmitter().toString());

                    log.info("Open transmitters now:");
                    transmitters = device.getTransmitters();
                    for (Transmitter t : transmitters) {
                        log.info(t.toString());
                    }

            }
        }

            recvr = outputDevice.getReceiver();
            trans = inputDevice.getTransmitter();
            trans.setReceiver(outputReceiverDump);

    }

This is the main method:

public static void main(String[] args) {
        try {
            WindowsMidiCommunicator.getInstance().testConnectivity();
        } catch (InvalidMidiDataException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (MidiUnavailableException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            WindowsMidiCommunicator.getInstance().sendCurrentPresetRequest();
        } catch (InvalidMidiDataException | MidiUnavailableException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        new java.util.Timer().schedule( 
                new java.util.TimerTask() {
                    @Override
                    public void run() {
                        try {
                            WindowsMidiCommunicator.getInstance().closeDevices();
                        } catch (MidiUnavailableException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }, 
                5000 
        );
    }

And when running , this is the stack trace:

INFO ] 2015-05-05 11:08:32.572 [main] Saffiretest - Max receivers:0
javax.sound.midi.MidiUnavailableException: MIDI IN receiver not available
    at com.sun.media.sound.AbstractMidiDevice.createReceiver(Unknown Source)
    at com.sun.media.sound.AbstractMidiDevice.getReceiver(Unknown Source)
    at WindowsMidiCommunicator.init(WindowsMidiCommunicator.java:79)
    at WindowsMidiCommunicator.<init>(WindowsMidiCommunicator.java:28)
    at WindowsMidiCommunicator.getInstance(WindowsMidiCommunicator.java:32)
    at SafferOrganizedTest.main(SafferOrganizedTest.java:9)
[INFO ] 2015-05-05 11:08:32.573 [main] Saffiretest - 2- Saffire 6USBobtained as inputDevice
[INFO ] 2015-05-05 11:08:32.574 [main] Saffiretest - Max transmitters:-1
[INFO ] 2015-05-05 11:08:32.574 [main] Saffiretest - Open receivers:
[INFO ] 2015-05-05 11:08:32.577 [main] Saffiretest - Max receivers:0
[INFO ] 2015-05-05 11:08:32.577 [main] Saffiretest - 2- Saffire 6USBobtained as inputDevice
[INFO ] 2015-05-05 11:08:32.577 [main] Saffiretest - Max transmitters:-1
[INFO ] 2015-05-05 11:08:32.577 [main] Saffiretest - Open receivers:
javax.sound.midi.MidiUnavailableException: MIDI IN receiver not available
    at com.sun.media.sound.AbstractMidiDevice.createReceiver(Unknown Source)
    at com.sun.media.sound.AbstractMidiDevice.getReceiver(Unknown Source)
    at WindowsMidiCommunicator.init(WindowsMidiCommunicator.java:79)
    at WindowsMidiCommunicator.<init>(WindowsMidiCommunicator.java:28)
    at WindowsMidiCommunicator.getInstance(WindowsMidiCommunicator.java:32)
    at SafferOrganizedTest.main(SafferOrganizedTest.java:18)
[INFO ] 2015-05-05 11:08:37.583 [Timer-0] Saffiretest - Max receivers:0
javax.sound.midi.MidiUnavailableException: MIDI IN receiver not available
[INFO ] 2015-05-05 11:08:37.584 [Timer-0] Saffiretest - 2- Saffire 6USBobtained as inputDevice
[INFO ] 2015-05-05 11:08:37.584 [Timer-0] Saffiretest - Max transmitters:-1
[INFO ] 2015-05-05 11:08:37.584 [Timer-0] Saffiretest - Open receivers:
    at com.sun.media.sound.AbstractMidiDevice.createReceiver(Unknown Source)
    at com.sun.media.sound.AbstractMidiDevice.getReceiver(Unknown Source)
    at WindowsMidiCommunicator.init(WindowsMidiCommunicator.java:79)
    at WindowsMidiCommunicator.<init>(WindowsMidiCommunicator.java:28)
    at WindowsMidiCommunicator.getInstance(WindowsMidiCommunicator.java:32)
    at SafferOrganizedTest$1.run(SafferOrganizedTest.java:28)
    at java.util.TimerThread.mainLoop(Unknown Source)
    at java.util.TimerThread.run(Unknown Source)
Community
  • 1
  • 1
Finn
  • 1
  • 3
  • 1
    What errors are you getting? You mentioned that you did not get these errors with the try-catch block. Is it possible that those errors were silently consumed by the try-catch block. In other words, did you have a printStackTrace() or similar for every exception that you caught? – nullPointer May 04 '15 at 22:23
  • 1
    Clarifying on nullPointer comment: *"I didn't got these errors before"* Maybe you did have them depending on how you were catching them. Post the previous code with the try/catch blocks, specially what you were doing in the catch. – m0skit0 May 04 '15 at 22:31

1 Answers1

0

It is not clear what your actual problem is because you haven't posted the error message. However, you singleton implementation is not really idiomatic or correct, mainly because the constructor of your class is protected. This means that anyone subclassing your class can create additional instances of it -- making the class no longer a singleton.

The simplest way to implement a singleton in Java 5 and above is to use an enum with a single value:

public enum Communicator {
    INSTANCE;

    private Connection conn;

    Communicator() {
        // set up the Connection here
    }

    /* public methods */
    public void doSomething() {
        //...
    }
}

This way, you can simply call your singleton with Communicator.INSTANCE.doSomething().

Mick Mnemonic
  • 7,808
  • 2
  • 26
  • 30
  • The init method would be executed in my case when first calling get instance. When would it be executed with the singleton enum implementation? – Finn May 05 '15 at 09:14
  • The singleton-based implementation is also [lazily-initialized](http://stackoverflow.com/a/16771449/905488). – Mick Mnemonic May 05 '15 at 10:16