Monday, November 15, 2021

Specifying the MQ username for connecting to a remote queue

Long before your time, there was a WebSphere 7 function, for using JMS to talk to Message Queues. The connectivity made use of (we believe) a default "mqm" username for accessing messages. Both the application server and codes have no awareness of such an arrangement. Nobody had any idea about this, until we were forced to dig deep into this discrepancy.

Then along came WebSphere 9, which turns out was slightly more advanced. The default is no longer used. Instead, it uses the service account that the application server was running on. This introduced some problems. The same identity needs to exist on the remote queue server that the WAS9 is connecting to. 

For most people, this might have easily concluded by having the same account be created on the other side. Naturally, this was not what is happening to warrant this post. In light of some revelations, a username that is different from the one already running the WAS9 was to be used.

I found out that it was risky to try setting the clientID, with due consideration for resource contention in a clustered environment. We tried poking around the J2C authentication alias, but it seemed to require a lot more configuration. The other option, was the username, as suggested by IBM documentation.

In order to set the value in, I located this UserCredentialsConnectionFactoryAdapter for Spring. As suggested here as well, 

For example, when using Basic client authentication, the username and password set for the Initial Context and used for the JNDI connection are inherited from the JMS data connection. However, these properties can be overridden by a username and password provided in the Connection Factory.

 I'd followed the example approximately:

 <bean id="myTargetConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
   <property name="jndiName" value="java:comp/env/jms/mycf"/>
 </bean>

 <bean id="myConnectionFactory" class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
   <property name="targetConnectionFactory" ref="myTargetConnectionFactory"/>
   <property name="username" value="myusername"/>
   <property name="password" value="mypassword"/>
 </bean>

We fiddled a bit with it and took it for a spin. It seemed to take, so we were quite relieved that we didn't have to spend another 2 weeks rewriting a bunch of codes for a fix. At this point, we can confirm that the JMSXUserID remains as "mqm", according to our debug logs.

This had been a very obscure lesson, with nary an article that detailed what needed to be done. Our work is yet to done (will it ever?) but this was quite the wild ride that my colleagues and I took.

Thursday, September 30, 2021

Configuring JVM for Tomcat Service Manager

It's been slightly more than a year since my last post, but my team had recently ventured into preparing our own deployment script. At the behest of an eager member, we'd built up a PowerShell script using PowerShell App Deployment Toolkit, also known as "PSAppDeployToolkit", or even shorter as PSADT. This was a script meant to automate installation of a number of programs on the target Windows machines, silently and automatically. 

With the background of what we were doing established, this was about one specific setup we wanted to configure. One of the platforms we were using, was Tomcat 9. Fine, it was TomEE 9, using Tomcat 9, but you get the idea. Tomcat was to be installed as a service by the having our script chained to trigger the standard "service.install.as.admin.bat" script. 

Then we realised that the JVM would default to "auto", which means using whichever JRE it can find. We prefer to stick to our version for consistency. The easiest was for us to edit the provided batch script. After finding this page of documentation, I started poking around the script more. We need the --Jvm="/path/to/the/jvm.dll" option added in. 

The standard configuration out of the box is this:

"%EXECUTABLE%" //IS//%SERVICE_NAME% ^
--DisplayName=%SERVICE_NAME% ^
--StartClass org.apache.catalina.startup.Bootstrap ^
--StopClass org.apache.catalina.startup.Bootstrap ^
--StartParams start ^
--StopParams stop ^
--Startup auto ^
--JvmMs=512 ^
--JvmMx=1024 ^
--JvmSs=2048 ^
--StartMode jvm ^
--StopMode jvm ^
--LogLevel Info ^
--LogPrefix TomEE

So I just need to add it in, right? I tested.

"%EXECUTABLE%" //IS//%SERVICE_NAME% ^
--DisplayName=%SERVICE_NAME% ^
--StartClass org.apache.catalina.startup.Bootstrap ^
--StopClass org.apache.catalina.startup.Bootstrap ^
--StartParams start ^
--StopParams stop ^
--Startup auto ^
--Jvm=%PR_JVM% ^
--JvmMs=512 ^
--JvmMx=1024 ^
--JvmSs=2048 ^
--StartMode jvm ^
--StopMode jvm ^
--LogLevel Info ^
--LogPrefix TomEE

It seemed fine on the surface. And after more elaborate tests, I realised that doing so would break the Tomcat Service Manager. The memory values (JvmMs/JvmMx/JvmSs) would not take. Neither did the StartMode and StopMode parameters. I couldn't be certain if it was because of how the PSADT script worked. I'd only extracted the portion of our whole script for Tomcat to test on after all. After some more fumbling, I thought I could try adding it to the end, and gave it a shot. The command wouldn't recognise it past the LogPrefix parameter at that point. It was then that I decided to move it up 2 lines.

"%EXECUTABLE%" //IS//%SERVICE_NAME% ^
--DisplayName=%SERVICE_NAME% ^
--StartClass org.apache.catalina.startup.Bootstrap ^
--StopClass org.apache.catalina.startup.Bootstrap ^
--StartParams start ^
--StopParams stop ^
--Startup auto ^
--JvmMs=512 ^
--JvmMx=1024 ^
--JvmSs=2048 ^
--StartMode jvm ^
--StopMode jvm ^
--Jvm=%PR_JVM% ^
--LogLevel Info ^
--LogPrefix TomEE

Ha! It finally worked. The JVM was no longer "auto", the memory values took effect, and the start/stop modes were in as well. There was very little details surrounding this specific configuration, much less documentation relating to this particular quirk of positioning the option correctly.