private void receiveAndDispatch() throws Exception {
        try {
            Session session = receiveTemplate.getSession();
            MessageConsumer consumer = receiveTemplate.getMessageConsumer();
            Message msg = consumer.receive(500);
            if (msg != null) {
                if (MSG_TYPE_REQUEST.equals(msg.getJMSType())) {
                    // Handle decoding the message in the dispatch thread.
                    getDispatchThreads().execute(new DispatchTask(this, (ObjectMessage) msg, false));
                } else if (MSG_TYPE_ONEWAY.equals(msg.getJMSType())) {
                    // Handle decoding the message in the dispatch thread.
                    getDispatchThreads().execute(new DispatchTask(this, (ObjectMessage) msg, true));
                } else if (MSG_TYPE_RESPONSE.equals(msg.getJMSType())) {
                    try {
                        long request = msg.getLongProperty(MSG_PROP_REQUEST);
                        RequestExchange target = requests.remove(request);
                        if (target != null) {
                            Response response = null;
                            try {
                                Thread.currentThread().setContextClassLoader(getUserClassLoader(target));
                                response = (Response) ((ObjectMessage) msg).getObject();
                                response.fromRemote = true;
                            } catch (JMSException e) {
                                target.setResponse(new Response(request, null, new UnmarshalException("Could not unmarshall response: " + e.getMessage(), e)));
                            }
                            target.setResponse(response);
                        }
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (TemplateClosedException tce) {
            //TODO we should probably just eat this.
            tce.printStackTrace();
            throw tce;
        } catch (Exception e) {
            e.printStackTrace();
            receiveTemplate.reset();
            throw e;
        }
    }