SpringBoot + ActiveMQ - How to set trusted packages?
Asked Answered
C

6

20

I'm creating two springboot server & client applications communicating using JMS, and everything is working fine with the release 5.12.1 for activemq, but as soon as I update to the 5.12.3 version, I'm getting the following error :

org.springframework.jms.support.converter.MessageConversionException: Could not convert JMS message; nested exception is javax.jms.JMSException: Failed to build body from content. Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: Forbidden class MyClass! This class is not trusted to be serialized as ObjectMessage payload. Please take a look at http://activemq.apache.org/objectmessage.html for more information on how to configure trusted classes.

I went on the URL that is provided and I figured out that my issue is related to the new security implemented in the 5.12.2 release of ActiveMQ, and I understand that I could fix it by defining the trusted packages, but I have no idea on where to put such a configuration in my SpringBoot project.

The only reference I'm making to the JMS queue in my client and my server is setting up it's URI in application.properties and enabling JMS on my "main" class with @EnableJms, and here's my configuration on the separate broker :

@Configuration
@ConfigurationProperties(prefix = "activemq")
public class BrokerConfiguration {

    /**
     * Defaults to TCP 10000
     */
    private String connectorURI = "tcp://0.0.0.0:10000";
    private String kahaDBDataDir = "../../data/activemq";

    public String getConnectorURI() {
        return connectorURI;
    }

    public void setConnectorURI(String connectorURI) {
        this.connectorURI = connectorURI;
    }

    public String getKahaDBDataDir() {
        return kahaDBDataDir;
    }

    public void setKahaDBDataDir(String kahaDBDataDir) {
        this.kahaDBDataDir = kahaDBDataDir;
    }

    @Bean(initMethod = "start", destroyMethod = "stop")
    public BrokerService broker() throws Exception {
        KahaDBPersistenceAdapter persistenceAdapter = new KahaDBPersistenceAdapter();
        persistenceAdapter.setDirectory(new File(kahaDBDataDir));

        final BrokerService broker = new BrokerService();
        broker.addConnector(getConnectorURI());
        broker.setPersistent(true);
        broker.setPersistenceAdapter(persistenceAdapter);
        broker.setShutdownHooks(Collections.<Runnable> singletonList(new SpringContextHook()));
        broker.setUseJmx(false);

        final ManagementContext managementContext = new ManagementContext();
        managementContext.setCreateConnector(true);
        broker.setManagementContext(managementContext);

        return broker;
    }
}

So I'd like to know where I'm supposed to specify the trusted packages.

Thanks :)

Carcinomatosis answered 14/4, 2016 at 9:47 Comment(0)
L
25

Add the following bean:

@Bean
public ActiveMQConnectionFactory activeMQConnectionFactory() {
    ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("your broker URL");
    factory.setTrustedPackages(Arrays.asList("com.my.package"));
    return factory;
}

The ability to do this via a configuration property has been added for the next release: https://github.com/spring-projects/spring-boot/issues/5631

Linnell answered 14/4, 2016 at 12:5 Comment(4)
Thanks :) I just had to edit your answer since setTrustedPackage only takes a List<String> as parameter and not a String.Carcinomatosis
Doh! Sorry, of course it does. The ActiveMQConnectionFactory also has a setTrustAllPackages(boolean) method so you don't have to set them individually.Linnell
I tried the same solution but it is not working for meBurglarize
setTrustedPackages and setTrustedPackage does not exists in 2020Electroencephalogram
E
34

You can just set one of the below spring boot properties in application.properties to set trusted packages.

spring.activemq.packages.trust-all=true

or

spring.activemq.packages.trusted=<package1>,<package2>,<package3>

Exterior answered 26/8, 2016 at 19:38 Comment(1)
I assume it's only available in the newer Spring-Boot versions?Carcinomatosis
L
25

Add the following bean:

@Bean
public ActiveMQConnectionFactory activeMQConnectionFactory() {
    ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("your broker URL");
    factory.setTrustedPackages(Arrays.asList("com.my.package"));
    return factory;
}

The ability to do this via a configuration property has been added for the next release: https://github.com/spring-projects/spring-boot/issues/5631

Linnell answered 14/4, 2016 at 12:5 Comment(4)
Thanks :) I just had to edit your answer since setTrustedPackage only takes a List<String> as parameter and not a String.Carcinomatosis
Doh! Sorry, of course it does. The ActiveMQConnectionFactory also has a setTrustAllPackages(boolean) method so you don't have to set them individually.Linnell
I tried the same solution but it is not working for meBurglarize
setTrustedPackages and setTrustedPackage does not exists in 2020Electroencephalogram
S
4

Method: public void setTrustedPackages(List<String> trustedPackages)

Description: add all packages which is used in send and receive Message object.

Code : connectionFactory.setTrustedPackages(Arrays.asList("org.api","java.util"))

Implementated Code:

private static final String DEFAULT_BROKER_URL = "tcp://localhost:61616";

private static final String RESPONSE_QUEUE = "api-response";

@Bean
public ActiveMQConnectionFactory connectionFactory(){
    ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
    connectionFactory.setBrokerURL(DEFAULT_BROKER_URL);
    connectionFactory.setTrustedPackages(Arrays.asList("org.api","java.util"));
    return connectionFactory;
}

@Bean
public JmsTemplate jmsTemplate(){
    JmsTemplate template = new JmsTemplate();
    template.setConnectionFactory(connectionFactory());
    template.setDefaultDestinationName(RESPONSE_QUEUE);
    return template;
}
Shortlived answered 28/8, 2017 at 10:21 Comment(0)
T
2

If any one still looking for an answer, below snippet worked for me

@Bean
public ActiveMQConnectionFactory connectionFactory() {
    ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
    connectionFactory.setBrokerURL(BROKER_URL);
    connectionFactory.setPassword(BROKER_USERNAME);
    connectionFactory.setUserName(BROKER_PASSWORD);
    connectionFactory.setTrustAllPackages(true); // all packages are considered as trusted 
    //connectionFactory.setTrustedPackages(Arrays.asList("com.my.package")); // selected packages
    return connectionFactory;
}
Theis answered 16/12, 2019 at 11:4 Comment(0)
H
1

I am setting Java_opts something like below and passing to java command and its working for me.

JAVA_OPTS=-Xmx256M -Xms16M -Dorg.apache.activemq.SERIALIZABLE_PACKAGES=*
java $JAVA_OPTS -Dapp.config.location=/data/config -jar <your_jar>.jar --spring.config.location=file:/data/config/<your config file path>.yml
Hibbard answered 20/11, 2018 at 21:8 Comment(0)
F
0

Yes I found it's config in the new version

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.RELEASE</version>
</parent>

spring:
profiles:
    active: @profileActive@
cache:
  ehcache:
    config: ehcache.xml
activemq:
  packages:
    trusted: com.stylrplus.api.model
Fructiferous answered 29/8, 2016 at 10:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.