【问题标题】:ActiveMQConnectionFactory - trusted packages not taken into accountActiveMQConnectionFactory - 不考虑受信任的包
【发布时间】:2021-10-30 17:04:30
【问题描述】:

我在 Spring Boot 应用程序中有一个活动的 MQ 工厂,输入 ActiveMQConnectionFactory。 在实例化它之后,我将受信任的包设置为 java.lang,因为我希望能够在我的应用程序中通过 JMS 发送/接收字符串。

参见此处:

SpringBoot + ActiveMQ - How to set trusted packages?

https://stackoverflow.com/a/36622567/2300597

    @Bean(name="jmsConnectionFactory")
    public ConnectionFactory getJMSConnectionFactory(){
        _factory = new ActiveMQConnectionFactory(active_MQ_BrokerURL);
        ActiveMQConnectionFactory fct = ((ActiveMQConnectionFactory)_factory);
        fct.setTrustAllPackages(false);
        fct.setTrustedPackages(Arrays.asList("java.lang"));
        return _factory;
    }

但我可以发送其他对象(不是来自包 java.lang)?!
发送它们时,我没有收到某种Exception

这是为什么呢?我做错了什么?

注意:我正在使用org.springframework.jms.core.JmsTemplate 发送消息
(以防万一)。该模板已链接到该工厂。

    public void sendObjectMessage(final Serializable msg) {
        try {
            this.jmsTemplate.send(this.queue, new MessageCreator() {
                public Message createMessage(final Session session) throws JMSException {
                    return session.createObjectMessage(msg);
                }
            });
            logger.info("Success sending Object MQ message [{}]", msg);
        } catch (Exception e) {
            logger.error("Error sending Object MQ message [{}]", msg, e);
        }
    }

【问题讨论】:

  • FWIW, ObjectMessage 对象依赖于 Java 序列化来编组和解组其对象有效负载。这个过程通常被认为是不安全的(因此需要明确地“信任”某些包)。还有一些other issues 使用与安全性无关的JMS ObjectMessage,这使其成为大多数用例的糟糕选择。如果可能的话,我会鼓励你避免使用ObjectMessage。鉴于您只想使用String,我建议使用java.jms.TextMessage

标签: java spring-boot jms activemq


【解决方案1】:

您可以运行下面的代码来验证这不是 ActiveMQ 问题。

您的代码的消费者方面是什么?

您如何确认消息未发送?

如果没有收到消息,则有一个候选 - 如果 Spring JMS 使用 JMS 2.0 API jar,则有一个新的 ObjectMessage API 调用可能会在幕后轰炸。

import java.io.Serializable;
import java.util.Arrays;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;

import org.apache.activemq.ActiveMQConnectionFactory;

public class JmsUrlTest {

    private static String brokerUrl = "tcp://localhost:61616";
    private static ActiveMQConnectionFactory activemqConnectionFactory = new ActiveMQConnectionFactory("admin", "admin", brokerUrl);
    
    public static void main(String[] args) {
        
        try {
            activemqConnectionFactory.setTrustedPackages(Arrays.asList("java.lang"));
            
            Connection connection = activemqConnectionFactory.createConnection();
            connection.start();
            
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer messageProducer = session.createProducer(session.createQueue("OBJECT.TEST"));
            
            Message message = session.createObjectMessage(new String("Test object"));
            message.setJMSType("java.lang.String");
            messageProducer.send(message);
            System.out.println("Sent message " + message.getJMSMessageID());
            
            MessageConsumer messageConsumer = session.createConsumer(session.createQueue("OBJECT.TEST"));
            
            boolean stop = false;
            int loopCount = 0;
            int maxLoops = 10;
            Message recvMessage = null;
            do {
                recvMessage = messageConsumer.receive(2000l);
                
                if(recvMessage != null || loopCount >= maxLoops) {
                    stop = true;
                }
            
            } while (!stop);
        
            
            if(recvMessage != null && ObjectMessage.class.isAssignableFrom(recvMessage.getClass())) {
                ObjectMessage recvObjectMessage = ObjectMessage.class.cast(recvMessage);
                Serializable recvSerializableBody = recvObjectMessage.getObject();
                
                if(recvSerializableBody.getClass().isAssignableFrom(String.class)) {
                    System.out.println("Recieved ObjectMessage w/ String body: " + String.class.cast(recvSerializableBody));
                } else {
                    System.out.println("Received body was not a String.class");
                }
            } else {
                System.out.println("No message received");
            }
            
        } catch (JMSException e) {
            e.printStackTrace();
        } finally {
            
        }
    }
}

【讨论】:

  • 预期的行为是什么?我以为我会得到一个例外?您是说预期的行为是消息只是默默地不发送(当它们在受信任的包之外时)?
  • 我的意思是...我以为我在发送消息时会收到异常。
  • 不,我也希望有一个例外。我是说,上面的代码可以验证它不是 ActiveMQ。 Spring / Spring JMS 可能会做一些有问题的事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-05
  • 2019-07-05
  • 2018-10-22
  • 2016-01-12
  • 2019-02-26
相关资源
最近更新 更多