IBM MQ create .binding file

The IBM JMSAdmin tool can be used to create the .binding file that can be used to connect to the IBM MQ Server.

Following are the steps to create the binding file:

  • Download and install the IBM MQ or atleast following jar files are required to use the JMSAdmin tool. Basically all of the following needs to be in your CLASSPATH enviornment variable.
C:\Dev\sw\IBM\WebSphere MQ\Java\lib;;C:\Dev\sw\IBM\WebSphere MQ\Java\lib\com.ibm.mqjms.jar;;C:\Dev\sw\IBM\WebSphere MQ\Java\lib\com.ibm.mqjms.jar;C:\Dev\sw\IBM\WebSphere MQ\Java\lib\jms.jar;C:\Dev\sw\IBM\WebSphere MQ\Java\lib\jndi.jar;;C:\Dev\sw\IBM\WebSphere MQ\Java\lib\com.ibm.mq.jar;;C:\Dev\sw\IBM\WebSphere MQ\Java\lib\com.ibm.mqbind.jar;;C:\Dev\sw\IBM\WebSphere MQ\Java\lib\jndi.jar;;C:\Dev\sw\IBM\WebSphere MQ\Java\lib\providerutil.jar;;C:\Dev\sw\IBM\WebSphere MQ\Java\lib\connector.jar;;C:\Dev\sw\IBM\WebSphere MQ\Java\lib\fscontext.jar;;C:\Dev\sw\IBM\WebSphere MQ\Java\lib\ldap.jar;

If you dont have rights to modify the PATH variable set it in command prompt for the current session 🙂

echo %CLASSPATH%
set CLASSPATH=%CLASSPATH%;C:\Dev\sw\IBM\WebSphere MQ\Java\lib\providerutil.jar;

Following in PATH varaible
;C:\Dev\sw\IBM\WebSphere MQ\Java\lib; C:\Dev\sw\IBM\WebSphere MQ\Java\lib\com.ibm.mqjms.jar;;C:\Dev\sw\IBM\WebSphere MQ\Java\bin
  • Create a JMSAdmin.config file and following should be added to it
INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory
#Directory where binding is created
PROVIDER_URL=file:/C:/Dev/sw/IBM/WebSphere MQ/Java/binding
SECURITY_AUTHENTICATION=simple
  • Cretae intsetup file and add following contents basically define the IBM MQ connection
def qcf(ivtQCF) qmgr(QMGR) transport(CLIENT) host(192.168.0.1) channel(QMGRChannel) port(2222) DEFINE Q(OUTQ) QUEUE(OUTQ) TC(MQ) end
  • Run the admin tool
java com.ibm.mq.jms.admin.JMSAdmin < intsetup.scp
  • The binding file is created
  • In case you change any configuations always delete the .binding file and run the above command again

TLS1.2 slowness

We switched ove to TLS 1.2 btween two of our integrations and things started to become too slow. We investigated various issues like slow algorithem etc but it turned out to be that new TLS 1.2 add some headers where the length is more then the default length allowed by the network TCP-MSS.

This caused packets to be dropped fixing this value improved the network performance.

Apache tomcat easy deployment script

Following is the script that can be used to deploy application to Apache tomcat running on a Linux machine.

Also this script can be called from a Jenkins to automate the deployment process.

The script file can be downloaded from HotDeployScript

#/bin/bash#/bin/bash
# . ~/.profile
export APP_ID=$1export URL1="http://localhost:8257/myWebApp/mvc/"
export CHECK_URLS="$URL1"
export CATALINA_HOME=/opt/myWebApp/tomcat7/
export CATALINA_BASE=$CATALINA_HOME
echo CATALINA_HOME: $CATALINA_HOME
echo CATALINA_BASE: $CATALINA_BASE
export STOP_SCRIPT="$CATALINA_BASE/bin/shutdown.sh"
export START_SCRIPT="$CATALINA_BASE/bin/startup.sh"
echo STOP_SCRIPT: $STOP_SCRIPTecho START_SCRIPT: $START_SCRIPT
export DEPLOY_SRC=~/autodeploy/tmp/${APP_ID}/${APP_ID}-*.war
export DEPLOY_WAR=${APP_ID}.warexport DEPLOY_DIR=${APP_ID}
echo DEPLOY_SRC: $DEPLOY_SRCecho DEPLOY_WAR: $DEPLOY_WAR
echo DEPLOY_DIR: $DEPLOY_DIR
cd $CATALINA_BASE/webapps/
rm -f $CATALINA_BASE/webapps/${DEPLOY_WAR}
while [ -d "$CATALINA_BASE/webapps/${DEPLOY_DIR}" ]; do  
  echo "$(date +'%Y-%m-%d_%H:%M:%S'): Waiting for ${DEPLOY_DIR} to undeploy..." 
  sleep 5
done
echo "$(date +'%Y-%m-%d_%H:%M:%S'): === Undeploy completed."
${STOP_SCRIPT}sleep 5
cp -ip $DEPLOY_SRC $CATALINA_BASE/webapps/${DEPLOY_WAR}
${START_SCRIPT}
sleep 5
while [ ! -d "$CATALINA_BASE/webapps/${DEPLOY_DIR}" ]; do  
  echo "$(date +'%Y-%m-%d_%H:%M:%S'): Waiting for ${DEPLOY_DIR} hot-deploy to start..."  
  sleep 5
done
echo "$(date +'%Y-%m-%d_%H:%M:%S'): === Hot-deploy started..."
mkdir -p /tmp/${APP_ID}/
TEMP_FILE=/tmp/${APP_ID}/${APP_ID}.$$
rm -f $TEMP_FILE
for url in $CHECK_URLS; do 
curl_check=FAIL echo "$(date +'%Y-%m-%d_%H:%M:%S'): Verifying url: $url" 
# Wait 6 * 5secs = 30secs for url to become accessible... 
for loop_count in 1 2 3 4 5 6 7 8; do   
  curl -k -L "$url" > $TEMP_FILE 2> /dev/null   
  grep 'myWebApp version:' $TEMP_FILE > /dev/null   
  result=$?   
  if [ "$result" == "0" ]; then     
   echo "$(date +'%Y-%m-%d_%H:%M:%S'): === url is OK: $url"     
   curl_check="OK" 
    break;   
  fi   
  echo "$(date +'%Y-%m-%d_%H:%M:%S'): Waiting for hot-deploy to complete for: $url"   
  sleep 5 
done 
if [ "$curl_check" == "FAIL" ]; then      
echo "$(date +'%Y-%m-%d_%H:%M:%S'): === Hotdeploy FAILED for: $url"   
exit 1 
fi
done

echo "$(date +'%Y-%m-%d_%H:%M:%S'): === Hotdeploy completed."

 

TIBCO Java Event Source

TIBCO Java event source activity gives you the flexibility to write custom process starters. In following post we will create a simple project where we use the event source plugin.

The java source code and the tibco project can be found here.

Sample github project code

Do a maven clean install on the java project a jar file is created that should be imported as alias library to the tibco project.

The java project consist of the class “ProcessStarter” which extends the tibco process starter.

/**
 *
 * @param processName sampleInputParam
 * @throws Exception exception
 */
public void initProcess(final String processName) throws Exception {
    this.processName = processName;
    init();
}

@Override
public void init() throws Exception {
    LOGGER.info("[ProcessStarter] Initializing " + processName + " Proces Starter");
    //Some init code
    LOGGER.info("[ProcessStarter] Successfully Initialized Proces Starter");
}

Following is how its called from tibco

Capture1

The out put from event source is a java object we convert it to a string using the java method activity the code is

public String getMessageBodyAsString(final Object message) {
    final MessageDataType messageDataType = (MessageDataType) message;
    return messageDataType.toString();
}

and tibco activity configuration is

Capture2

When you run the process it is executed 10 times and a string plus the thread index string is the output.

Hotswap for Java using DCEVM+Hotswap Agent

Here is an opensource setup that does the job as JRebel which offcourse is not free.

Download HotswapAgent latest release from this url

https://github.com/HotswapProjects/HotswapAgent/releases

Download DCEVM jar from the following url

https://github.com/dcevm/dcevm/releases

Install DCEVM as an administrator

java -jar DCEVM-light-8u112-installer.jar

dcevm

Create a new run configuration in intelliJ with following VM option
-XXaltjvm=dcevm -javaagent:C:\Dev\sw\HotswapAgent-0.3\hotswap-agent.jar -Xms1G -Xmx5G

Now you can modify the Java code on the fly and don’t need to restart the whole application. Just don’t forget to compile the file that you modified.

For more information

https://groups.google.com/forum/#!topic/hotswapagent/BxAK_Clniss

TDD with java a good overview book

Was contacted recently by PACKT publishing to act as technical reviewer for Test driven java development book by Viktor Farcic and Alex Garcia. I accepted the challenge and reviewed around 10 chapters.

It a nice overview book which touch almost all the concerns in test driven application development without diving deep into details and you also get introduction to some new tools that can help in test automation. I definatly recommend this book

Thanks to PACKT for living up to the promise and providing free hard copy of the book.

XML Schema generation from Java 8 code and Gradle integration

Using Java 8 and Gradle I had to generate XSD schema. Most of the Gradle plugins out there are not compatible with Java 8 yet. So I tweaked my way and following is how I did it.

I had following model class supporting both JAXB and JSON.
@XmlType(namespace = "http://com.invalid/1.0/request/schema")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Person")
@JsonRootName(value = "Person")
@JsonInclude(Include.NON_NULL)
public class Person {
	private String name;

private Gender gender;

public String getName() {
 return name;
 }

public void setName(String name) {
 this.name = name;
 }

public Gender getGender() {
 return gender;
 }

public void setGender(Gender gender) {
 this.gender = gender;
 }
 }

Following is the Gender enumeration
public enum Gender {
	MALE, FEMALE
}
Create a package-info.java file (if this file is not created and namespace is not same in every where multiple schema files are generated.)
@javax.xml.bind.annotation.XmlSchema(namespace = "http://com.invalid/1.0/request/schema", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.test;
Add the schema generation task in your gradle build script
configurations {
  jaxb
}
task schemagen () {
 doLast {
 ext.schemasDir = file("${buildDir}/schemas")
 project.ant {
 mkdir(dir: schemasDir)
 }
ant.taskdef(name: 'schemagen', classname: 'com.sun.tools.jxc.SchemaGenTask', classpath: configurations.jaxb.asPath)
 ant.schemagen(srcdir: new File('src/main/java/com/test'), destdir: schemasDir, includeAntRuntime:'false') {
 schema {
 namespace = 'http://com.invalid/1.0/request/schema'
 //Known issue: due to some internal jaxb issue the file name property doesn't take effect
 file = 'request.xsd'
 }
 classpath {
 pathElement(path: configurations.jaxb.asPath )
 }
 }
 }
 }

dependencies {
 //other dependencies
 //Add following dependency this overrides the jaxb (jakson, and findbugs are added as schemagen fails
 to find definitions of some annotations)

jaxb (
 'org.codehaus.mojo:jaxb2-maven-plugin:2.1',
 'org.apache.avro:avro-tools:1.7.5',
 'org.apache.avro:avro:1.7.5' ,
 'com.fasterxml.jackson.core:jackson-annotations:2.6.0',
 'com.google.code.findbugs:jsr305:3.0.0'
 )
 }
Now do a Gradle build and following schema is generated in the build/schemas directory
<xs:schema elementFormDefault="qualified" version="1.0" targetNamespace="http://com.invalid/1.0/request/schema" xmlns:tns="http://com.invalid/1.0/request/schema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Person" type="tns:person"/>
<xs:complexType name="person">
 <xs:sequence>
 <xs:element name="name" type="xs:string" minOccurs="0"/>
 <xs:element name="gender" type="tns:gender" minOccurs="0"/>
 </xs:sequence>
 </xs:complexType>
<xs:simpleType name="gender">
 <xs:restriction base="xs:string">
 <xs:enumeration value="MALE"/>
 <xs:enumeration value="FEMALE"/>
 </xs:restriction>
 </xs:simpleType>
 </xs:schema>