Q:

Setting Trusted Packages (ActiveMQ)

I am trying to send receive ActiveMQ messages.  But I see the messages come back with this message in them. 
JMSException in onMessage(): javax.jms. JMSException: Failed to build body from content.  Serializable class not available to broker.  Reason: java.lang. ClassNotFoundException: Forbidden class com.logicalprovisioning.common.gtc.shared. GTCMessage!  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. 

So I read the link in the message.  And I tried to follow the instructions.  Although I must say its not very well written on where to put the configuration. 
So what I did was:
1.  I edited the ACTIVEMQ_OPTS line in activemq.bat file in the bin folder to 
if "%ACTIVEMQ_OPTS%" == "" set ACTIVEMQ_OPTS=-Xms1G -Xmx1G -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config="%ACTIVEMQ_CONF%\login.config" -Dorg.apache.activemq. SERIALIZABLE_PACKAGES=com.logicalprovisioning.common.gtc.shared. GTCMessage

It didn't work. 

I added the above line in the activemq.bat of the win64 folder as well.  It didn't work. 
I modified my subscriber object creation to add the Trusted Packages.  Like:
String providerEndpoints = "tcp://" + host + ":" + port + "? wireFormat.maxInactivityDuration=7200000";

// Set the trusted packages/classes to move back and forth on the ActiveMQ JMS service. 
ArrayList<String> trustedClasses = new ArrayList<String>();

trustedClasses.add("com.logicalprovisioning.common.gtc.shared. GTCMessage");

// Obtain the factory
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();

activeMQConnectionFactory.setBrokerURL(providerEndpoints);

// Add the trusted packages/classes to the ActiveMQ consumer. 
activeMQConnectionFactory.setTrustedPackages(trustedClasses);

//Create the connection
setConnection(activeMQConnectionFactory.createQueueConnection());
getConnection().setClientID(this.getName());

// Make a session
setSession(getConnection().createQueueSession(false, Session. AUTO_ACKNOWLEDGE));

getSession().createQueue(jmsDestination);

// Create the destination
Destination destination = getSession().createQueue(jmsDestination);

String selector = "JMSCorrelationID = '" + getActionRequest().getOriginId() + "_" + getActionRequest().getRequestId() + "'" ;

setConsumer(getSession().createConsumer(destination, selector));
getConsumer().setMessageListener(new DefaultMessageListener(this));

// Start ...
gtcMessages = new GTCMessageQueue<GTCMessage>();  // We'll need a message store now
getConnection().start();

And I added something similar in my producer as well for good measure:
    Context initialContext = new InitialContext();
        Context environmentContext = (Context) initialContext.lookup("java:comp/env");

        String queueConnectionFactoryNameLookup = PalInit.getProperty("jms.queue.connection.factory");

        // Set the trusted packages/classes to move back and forth on the ActiveMQ JMS service. 
        ArrayList<String> trustedClasses = new ArrayList<String>();

        trustedClasses.add("com.logicalprovisioning.common.gtc.shared. GTCMessage");

        ActiveMQConnectionFactory activeMQConnectionFactory = (ActiveMQConnectionFactory) environmentContext.lookup(queueConnectionFactoryNameLookup);

        activeMQConnectionFactory.setTrustedPackages(trustedClasses);
        // Create connection
        QueueConnection queueConnection = activeMQConnectionFactory.createQueueConnection();
        queueConnection.start();

        // Create session and producer
        setSession(queueConnection.createSession(false, Session. AUTO_ACKNOWLEDGE));

        String queueName = PalInit.getProperty("jms.destination");
        Queue jmsQueue = getSession().createQueue(queueName);

        setProducer(getSession().createProducer(jmsQueue));
        setQueueConnection(queueConnection);

        // Set Message "Time to Live" to the request timeout plus 10 minutes
        getProducer().setTimeToLive(getTimeout() + (10 * 60 * 1000L));

But nothing seems to work.  I have the ActiveMQ-All jar in the Tomcat's lib folder and so too the jar where the GTCMessage class resides.  Can anyone please tell me what am I doing wrong?  Is it a problem of a missing class or my bad configuration?  Any help would be appreciated.  Thanks! 
The application is running on Tomcat 9, JAVA 1.8 and Active MQ 5.15.11. 

A:

I think your problem is that you're setting the name of the specific class rather than the package of the class.  The code looks at the package name, not the class name.  Try this:
// Set the trusted packages to move back and forth on the ActiveMQ JMS service. 
ArrayList<String> trustedPackages = new ArrayList<String>();
trustedPackages.add("com.logicalprovisioning.common.gtc.shared");
ActiveMQConnectionFactory activeMQConnectionFactory = (ActiveMQConnectionFactory) environmentContext.lookup(queueConnectionFactoryNameLookup);
activeMQConnectionFactory.setTrustedPackages(trustedPackages);        

I don't think you'll need to set this on the broker itself.  
Aside from that I would strongly discourage you from using JMS ObjectMessage.  They depend on Java serialization to marshal and unmarshal their object payload.  This process is generally considered unsafe, because a malicious payload can exploit the host system.  Lots of CVEs have been created for this which is why most JMS providers force users to explicitly whitelist packages that can be exchanged using ObjectMessage messages. 
There are also a number of other issues with using JMS ObjectMessage not related to security that you should read about.  This article has a good suggestion for how to replace ObjectMessage - define a data representation for the payload (JSON, protobuf, XML) and use TextMessage or BytesMessage to carry it.