java - 无法通过 Java 主程序向队列发送消息

标签 java spring jms listener spring-jms

我从 Main 方法调用 sendMessage 函数,它在创建对象队列 (this.queue) 时给出空指针异常。

主要方法:

public void start()
    {
        AuthorisationServiceImpl authorisationServiceImpl = new AuthorisationServiceImpl();
        try {
            authorisationServiceImpl.fromMain();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    public static void main(String[] args) throws InterruptedException {
        System.out.println("Starting Client Application");
        AbstractApplicationContext context = new FileSystemXmlApplicationContext("resources/applicationContext.xml");
        System.out.println("Spring context loaded.");
        context.registerShutdownHook();
        System.out.println("ShutdownHook registered.");

        MainTestClient mainTestClient = new MainTestClient();
        mainTestClient.start();



    }

我在另一个类中调用的方法是

public class AuthorisationServiceImpl {

    @Autowired
    private MessageSender messageSender;


    private MessageReceiver messageReceiver;

    private JmsTemplate jmsTemplate;
    private Queue queue;


    public JmsTemplate getJmsTemplate() {
        return jmsTemplate;
    }



    public void setJmsTemplate(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }



    public Queue getQueue() {
        return queue;
    }



    public void setQueue(Queue queue) {
        this.queue = queue;
    }



    public MessageReceiver getMessageReceiver() {
        return messageReceiver;
    }



    public void setMessageReceiver(MessageReceiver messageReceiver) {
        this.messageReceiver = messageReceiver;
    }

    private ConfigProperties configProperties;


    public void fromMain() throws InterruptedException {
        System.out.println("Init method called");
        String message = "AAA-MM-CCC";
        long count = new Long("000001").longValue();
        while (true)
        {
            //container.start();
            StringBuffer corelationId = new StringBuffer();

            if (count == 1000000) {
                count = new Long("000001").longValue();
            }

            corelationId.append(message);
            corelationId.append(String.format("%6s", String.valueOf(count)).replace(' ', '0'));
            byte[] myvar = "Message".getBytes();
            System.out.println("Writing message having correlationId: " + corelationId.toString() + " to the queue.");
            sendMessage(corelationId.toString(),myvar);
            count++;
            Thread.sleep(5000);
        }


    }



    /*public boolean sendMessage(String correlationId) throws ServiceException {
        byte[] myvar = "Message".getBytes();
        boolean response = false;
        try {
            MessageSender messageSenderVar = new MessageSender();
            System.out.println("Writing message having correlationId: " + correlationId + " to the queue.");
            // writing message to the request queue. 
            sendMessage(correlationId,myvar);
            //messageReceiver.getMessage();

        }catch(Exception e) {

            throw new ServiceException("Exception:",e);
        }
        return response;
    }
    */
    public void sendMessage(final String correlationId, final byte[] bytes) {
        this.jmsTemplate.send(this.queue, new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                BytesMessage bytesMessage = session.createBytesMessage();
                bytesMessage.setJMSCorrelationID(configProperties.getPREFIX_VALUE() + correlationId);

                // message will follow expiration time as configured in properties
                bytesMessage.writeBytes(bytes);
                return bytesMessage;
            }
        });
        System.out.println("Message " + configProperties.getPREFIX_VALUE() + correlationId + " with correlation id: " + configProperties.getPREFIX_VALUE() + correlationId + " written to the queue.");
    }



    public MessageSender getMessageSender() {
        return messageSender;
    }

    public void setMessageSender(MessageSender messageSender) {
        this.messageSender = messageSender;
    }



    public ConfigProperties getConfigProperties() {
        return configProperties;
    }

    public void setConfigProperties(ConfigProperties configProperties) {
        this.configProperties = configProperties;
    }

}

我在调用 sendMessage 方法时遇到空指针异常。静态方法调用非静态方法有问题吗?

Starting Client Application
Nov 23, 2015 12:49:53 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@5ba28182: startup date [Mon Nov 23 12:49:53 UTC 2015]; root of context hierarchy
Nov 23, 2015 12:49:53 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from file [/app/dev-data/node1/support/tactical_tools/gwatest/client1/resources/applicationContext.xml]
Nov 23, 2015 12:49:54 PM org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
INFO: Loading properties file from URL [file:resources/config.properties]
Nov 23, 2015 12:49:54 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6b915330: defining beans [propertyConfigurer,configProperties,jndiTemplate,connectionFactory,paymentRequestQueue,paymentResponseQueue,jmsTemplate,messageSender,authorisationResponseHandler,authorisationServiceImpl,jmsContainer]; root of factory hierarchy
Nov 23, 2015 12:49:55 PM org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup start
INFO: Starting beans in phase 2147483647
Spring context loaded.
ShutdownHook registered.
Init method called
Writing message having correlationId: AAA-MM-CCC000001 to the queue.
Exception in thread "main" java.lang.NullPointerException
        at aero.sita.uatp.client.AuthorisationServiceImpl.sendMessage(AuthorisationServiceImpl.java:114)
        at aero.sita.uatp.client.AuthorisationServiceImpl.fromMain(AuthorisationServiceImpl.java:86)
        at aero.sita.uatp.client.MainTestClient.start(MainTestClient.java:15)
        at aero.sita.uatp.client.MainTestClient.main(MainTestClient.java:31)

当我通常在没有 Main 方法的情况下调用 sendMessage 时,我就能够成功连接。我正在使用 Spring ApplicationContext 来初始化队列,如下所示

<!-- Config property -->
<bean id="propertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>file:resources/config.properties</value>
        </list>
    </property>
    <property name="ignoreUnresolvablePlaceholders" value="true" />
    <property name="order" value="0" />
</bean>

<!-- App config properties -->

<bean id="configProperties" class="aero.sita.uatp.server.utilities.ConfigProperties">
    <property name="properties">
        <props>
                    <prop key="prefix.correlation">${prefix.correlation}</prop>
        </props>
    </property>
</bean>


<!-- jndi Template -->
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">${broker.initialContexFactory}</prop>
            <prop key="java.naming.provider.url">${broker.provide.url}</prop>
        </props>
    </property>
</bean>

<!-- JMS Connection factory -->
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate">
        <ref bean="jndiTemplate" />
    </property>
    <property name="jndiName">
        <value>${broker.connectionFactory}</value>
    </property>
</bean>

<!-- Auth (Payment) Request queue -->
<bean id="paymentRequestQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate">
        <ref bean="jndiTemplate" />
    </property>
    <property name="jndiName">
        <value>${payment.request}</value>
    </property>
</bean>

<!-- Auth (Payment) Response queue -->
<bean id="paymentResponseQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiTemplate">
        <ref bean="jndiTemplate" />
    </property>
    <property name="jndiName">
        <value>${payment.response}</value>
    </property>
</bean>

<!-- JMS Template -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="explicitQosEnabled" value="true" />
    <property name="timeToLive" value="${payment.request.expiration}" />
    <property name="receiveTimeout" value="${payment.response.receive.timeout}" />
</bean>

<bean id="messageSender" class="aero.sita.uatp.server.MessageSender">
    <property name="jmsTemplate" ref="jmsTemplate" />
    <property name="queue" ref="paymentResponseQueue" />
    <property name="configProperties" ref="configProperties" />
</bean>

<bean id="authorisationServiceImpl" class="aero.sita.uatp.server.AuthorisationServiceImpl">
    <property name="messageSender" ref="messageSender" />
    <property name="configProperties" ref="configProperties" />
</bean>


<bean id="authorisationResponseHandler" class="aero.sita.uatp.server.AuthorisationResponseHandler">
    <property name="configProperties" ref="configProperties" />
    <property name="messageSender" ref="messageSender" />
</bean>



<!-- and this is the message listener container -->

<bean id="jmsContainer" class="org.springframework.jms.listener.SimpleMessageListenerContainer">
    <property name="autoStartup" value="TRUE" />
    <property name="connectionFactory" ref="connectionFactory" />
    <property name="destination" ref="paymentRequestQueue" />
    <property name="messageListener" ref="authorisationResponseHandler" />

</bean>

最佳答案

尝试调用 this.jmsTemplate.send(...) 方法时,您会收到 NullPointerException 错误,因为您的 jmsTemplate 变量是NULL,或者从未初始化。另一件事是,您没有使用 spring bean authorizationServiceImpl,但您正在手动实例化该类。

首先,您需要在 bean 中设置 jmsTemplate:

<bean id="authorisationServiceImpl" class="aero.sita.uatp.server.AuthorisationServiceImpl">
    <property name="jmsTemplate" ref="jmsTemplate" />
    <property name="messageSender" ref="messageSender" />
    <property name="configProperties" ref="configProperties" />
</bean>

其次,您不应该实例化该类:

AuthorisationServiceImpl authorisationServiceImpl = new AuthorisationServiceImpl();
try {
    authorisationServiceImpl.fromMain();
} 

但是从您刚刚创建的应用程序上下文中获取它

AuthorisationServiceImpl authorisationServiceImpl = context.getBean("authorisationServiceImpl", AuthorisationServiceImpl.class );

关于java - 无法通过 Java 主程序向队列发送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33885571/

相关文章:

java - 我应该在 Eclipse 中关闭 "Build Automatically"

java - AspectJ 加载时间编织不适用于 Spring bean

java - 在 Java 中将 ActiveMQBytesMessage 转换为 ActiveMQTextMessage

java - 集成 .net 和 java 应用程序的架构建议

java - 独立 Java 程序的数据库连接池

java - java.time 中 Calendar.roll 的等价物是什么?

java - Spring AOP 自定义注解

java.lang.NumberFormatException :For input string :""

java - 从 Java 启动 Spring 应用程序的异常

java - org.springframework.beans.factory.NoSuchBeanDefinitionException : No bean named 'itemAttrService' is defined