I have JNDI context in MQ queue manager, my standalone java client is able to do lookup, with initial context class, com.ibm.mq.jms.context.WMQInitialContextFactory, it is working with MQ client jars for versions before MQ 8. It also has the mqcontext.jar in my classpath.
With MQ 8 and 9, I am trying to use the relocatable jars com.ibm.mq.allclient.jar and com.ibm.mq.traceControl.jar in my classpath and the JNDI lookup is failing. If I add the old mqcontext.jar to classpath, I get below error.
javax.naming.NamingException: Caught an MQ Exception: com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCC0053: An exception occurred deserializing a message, exception: 'java.io.InvalidClassException: com.ibm.msg.client.wmq.common.WMQConnectionName; local class incompatible: stream classdesc serialVersionUID = 3226780381239434112, local class serialVersionUID = -2174857328193645055'.
For IBM MQ Classes for JMS you can find the list of files required on the Knowledge Center page "What is installed for IBM MQ classes for JMS":
Relocatable JAR files
Within an enterprise, the following files can be moved to systems that need to run IBM MQ classes for JMS:
com.ibm.mq.allclient.jar
com.ibm.mq.traceControl.jar
jms.jar
fscontext.jar
providerutil.jar
com.ibm.mq.jms.context.WMQInitialContextFactory
I would strongly recommend you not use the MQ queue manager as the resource holder for MQ JNDI. You should either use file based MQ JNDI or LDAP based MQ JNDI.
The last time I checked, using WMQInitialContextFactory would not allow the use of either MQ client-side security exit and/or TLS/SSL. Hence, you have to connect to the queue manager without any security. Bad, bad idea.
With hacks taking place everyday and private/confidential information getting dumped to the web and/or dark web, EVERY queue manager should be locked down tight.
Related
I would like to create a JMS connection from a Java SE application in a broker-agnostic way.
I'm comparing to JDBC with its URL scheme for database connections. This creates independence from the actual implementation.
For JMS I haven't found something similar. I'm aware that in Java EE the JNDI will fulfill this role, but this is Java SE.
I don't want to tie my code to any particular queue broker as my needs are pretty simple JMS 1.1 send/receive of text messages.
I've looked at Spring Boot too because it is usually good at providing some level of agnosticism. But even with Spring Boot, I do not see such possibility.
JNDI is the way you write your JMS application to connect in a broker-agnostic way. JNDI client classes are part of Java SE. Both Spring and non-Spring Java SE applications use JNDI for this kind of integration.
Any JMS implementation should also provide a JNDI implementation that can be plugged into your application. Typically this is done by placing a file named jndi.properties on your classpath and putting the proper configuration for whatever JNDI implementation you're using into that file. When you create an empty InitialContext the jndi.properties file on your classpath is read automatically. The key=value pairs in jndi.properties are put into the InitialContext so that when you perform a lookup everything works with the implementation you've chosen. You can also configure this programmatically if you like by supplying the implementation specific details to the InitialContext via a constructor.
By using both the JMS and JNDI APIs in your Java SE application and externalizing broker-specific connection details to your jndi.properties file you can effectively isolate your applications from broker-specific code so you can deploy your app and work with different brokers with a few simple changes in a properties file.
The JNDI client implementation will come from whoever is providing the JMS implementation. The JNDI client essentially comes in the form of an javax.naming.spi.InitialContextFactory implementation packaged in a jar and there is usually documentation describing the available properties.
Here are a few examples:
The ActiveMQ 5.x broker provides org.apache.activemq.jndi.ActiveMQInitialContextFactory available in their activemq-client-<version>.jar. Documentation is available here.
The ActiveMQ Artemis broker provides org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory available in their artemis-jms-client-<version>.jar. Documentation is available here.
To be clear, the JMS specification doesn't require the use of JNDI to look-up admin objects, but it establishes the convention and expectation that JMS providers will do so. Section 4.2 of the JMS 1.1 specification states:
Although the interfaces for administered objects do not explicitly depend on JNDI, JMS establishes the convention that JMS clients find them by looking them up in a namespace using JNDI.
and later it says:
It is expected that JMS providers will provide the tools an administrator needs to create and configure administered objects in a JNDI namespace. JMS
provider implementations of administered objects should be both javax.naming.Referenceable and java.io.Serializable so that they can be stored in all JNDI naming contexts.
In my experience, JMS providers are usually eager to provide a JNDI implementation because they won't be as competitive without it since any alternative solution will not be standards compliant and will force users to implement non-portable code.
If you run into a provider that doesn't provide a JNDI implementation you could implement your own following the same pattern used by ActiveMQ 5.x, ActiveMQ Artemis, and Qpid JMS. These 3 implementations are client-side only and simply instantiate the admin objects based on the configuration provided to the InitialContext. Most of the code is boiler plate, and what isn't is very straight-forward.
I am looking for a way to programmatically set client attributes inside an IBM MQ Java client application. I do realise IBM provides a way of configuring MQ Clients using a mqclient.ini file, however due to the nature of deployment and distribution of the application I'm working on it is not possible to use such a file. Hence, I want to set a stanza attribute that would normally be defined in the ini file, inside the connetion configuration block of my code.
Furthermore, I am aware that certain properties can be set as environment variables or Java command line arguments, but that would not be a viable workaround due to the same reasons mentioned above.
In particular I'm interested in the setting the KeepAlive attribute in the TCP stanza to YES.
So far I have attempted the following ways of achieving that using an MQQueueConnectionFactory :
connectionFactory.setStringProperty("KeepAlive", "YES");
connectionFactory.setStringProperty("com.ibm.mq.cfg.TCP.KeepAlive", "YES");
connectionFactory.setBooleanProperty("KeepAlive", true);
connectionFactory.setBooleanProperty("com.ibm.mq.cfg.TCP.KeepAlive", true);
However, none of those have had any effect.
For the record I am using IBM MQ classes for JMS version 8.
You can use Java system properties for this purpose.
The following Java system property will be read by IBM MQ classes for JMS to tell it to use TCP KeepAlive:
com.ibm.mq.cfg.TCP.KeepAlive=YES
To set this programmatically just use System.setProperty method for example:
System.setProperty("com.ibm.mq.cfg.TCP.KeepAlive","YES");
Oracle documents the setProperty method in the Class System:
setProperty
public static String setProperty(String key,
String value)
Sets the system property indicated by the specified key.
IBM "loosly" documents specifying a mqclient.ini setting as a system property in the IBM MQ v8 Knowledge center page The IBM MQ classes for JMS configuration file:
Overriding properties specified in an IBM MQ MQI client configuration file
An IBM MQ MQI client configuration file can also specify properties
that are used to configure IBM MQ classes for JMS. However, properties
specified in an IBM MQ MQI client configuration file apply only when
an application connects to a queue manager in client mode.
If required, you can override any attribute in a IBM MQ MQI client
configuration file by specifying it as a property in a IBM MQ classes
for JMS configuration file. To override an attribute in a IBM MQ MQI
client configuration file, use an entry with the following format in
the IBM MQ classes for JMS configuration file:
com.ibm.mq.cfg. stanza. propName = propValueCopy
The variables in the entry have the following meanings:
stanza The name of the stanza in the IBM MQ MQI client configuration file that contains the attribute
propName The name of the attribute as specified in the IBM MQ MQI client configuration file
propValue The value of the property that overrides the value of the attribute specified in the IBM MQ MQI client configuration file
Alternatively, you can override an attribute in an IBM MQ MQI client
configuration file by specifying the property as a system
property on the java command. Use the preceding format to specify
the property as a system property.
Thanks to Maarten I was able to get basic ActiveMQ JMS topics and connection factories working in WAS. He has a nice write up in his reply to this topic: ActiveMQ 5.11 with WebSphere Application Server 8.5
But I cannot find a way to define any ActiveMQ JMS Activation Specs in the WAS admin console. And of course I need those in order to trigger my MDBs. ActiveMQ simply doesn't show up as a JMS provider when creating a new AS.
How do I configure Activation Specs in WAS using ActiveMQ as the provider? Am I missing a jar file?
activemq-client-5.11.0.jar
hawtbuf-1.11.jar
slf4j-api-1.7.10.jar
If you want to use Activation specification, you need to install ActiveMQ as JCA 1.5 compliant resource adapter. As far as I know, ActiveMQ provides resource adapter as separate install.
See also:
Deploying the ActiveMQ Resource Adapter into IBM WebSphere
Managing messaging with a third-party JCA 1.5 or 1.6-compliant messaging provider
ActiveMQ resource adapter
Listener ports are stabilized, and should only be used if provider doesn't support JCA.
Really straight forward once you understand (of course).
From the IBM Redbook mentioned above, sg247770.pdf, we need to configure ActiveMQ as a Generic JMS provider in WAS. And since we want to use Activation Specs, again from the Redbook, we need to use the ActiveMQ Resource Adapter, or rar file. There is a link on the ActiveMQ page to the latest rar, I don't need to provide it here. Once the rar is installed, using the WAS Console/Resources/Resource Adapters menu, you can configure J2C CFs, ASs, and administered objects including Queues and Topics from the rar configuration page. These will all have custom properties where you will enter your destinations, etc.
I'm novice guy in JCA and JMS parts of Java EE stack, and now I'm struggling with JMS bridge configuration between two JMS providers (ActiveMQ 5.9.1 -> Weblogic 11g 10.3.5), and I need some help to understand all the moving parts and required configuration elements.
What I've done already:
JMS server configured on Weblogic 11g node
Configured Foreign Server - AMQ connection factory, and source queue objects bound to the local JNDI (OK: conn. factory and queue objects visible in server jndi tree)
Create JMS Bridge with default props (OK - I think)
Created the Bridge Destination for target destination (Weblogic) with default configuration - where possible (OK: Resource Adapter deployed)
Created the Bridge Destination for source destination (AMQ) - JNDI properties, default props where possible (FAIL - Cannot connect to the source destination)
And there is the question:
By default there are two resource adapters (XA, non-XA), do I need install the AMQ specific resource adapter?
I've assumed that yes, so I've downloaded rar file on Weblogic machine, then tried to install with Weblogic Console (Deployment -> Install), but.. another trouble - no way to achive Running state in Deployments view. I've read that all jars from rar need to be placed in Weblogic CLASSPATH, so I've copied them to Weblogic lib directory. But, with no success so far.
So, what I did wrong, where is the gap or an error in this configuration?
I have studied the Oracle documentation, but I feel still didn't get the complete understanding of the bridge config :((
Any explanatory replies very appreciated!!!
Ok, problem solved. I've used wrong JNDI names of connection factory and queue - local names defined in Foreign Server configuration instead of names on remove JMS server.
Actually, no additional configuration like Foreign Server, or Resource Adapter is needed here.
Using WebSphere MQ on z/OS for messaging and the WebSphere MQ resource adapter within JBoss EAP 6, I want to set the Application Name that appears when viewing the active handles on a queue.
The default is WebSphere MQ Client for Java and I have not managed to change it. I have no administrative access to the queue / queue manager, I am just the sender posting messages to it.
My configuration for the queues / queue manager are located in the JBoss EAP config file at the resource adapter configurations. I have tried - without success - setting the application name using a config-property inside the connection definition, for example:
<config-property name="PutApplName">
my application name
</config-property>
I have also tried names like applicationName, applName, appName, application or JMS_IBM_MQMD_PutApplName. The latter and the name from the example I have taken from here and here.
How can I change the displayed application name?
Is this even possible without using the specific WebSphere MQ classes inside the java application?
http://pic.dhe.ibm.com/infocenter/wmqv7/v7r5/index.jsp?topic=%2Fcom.ibm.mq.dev.doc%2Fq030790_.htm
Somewhere buried in there, it says its not supported for z/OS.
Note: Queue managers running on z/OSĀ® platforms do not support setting
application names.