Running IBM MQ classes for Java applications under the Java Security Manager

IBM® MQ classes for Java can run with the Java Security Manager enabled. To successfully run applications with the Security Manager enabled, you must configure your JVM with a suitable policy definition file.

The simplest way to do this is to change the policy file supplied with the JRE. On most systems this file is stored in the path lib/security/java.policy, relative to your JRE directory. You can edit policy files using your preferred editor or the policytool program supplied with your JRE.

You must give authority to the com.ibm.mq.jmqi.jar file so that it can:
  • Create sockets (in client mode)
  • Load the native library (in bindings mode)
  • Read various properties from the environment

The system property os.name must be available to the IBM MQ classes for Java when running under the Java Security Manager.

An IBM MQ queue manager can send notifications to connected clients requesting a controlled closure of conversations (connection handles), for example when the queue manager is being quiesced. If a thread within a Java client receives one of these notifications at the same time as another thread within the client requests a new conversation, a deadlock can occur as both threads need access to the internal "connectionsLock" on the RemoteConnectionSpecification object.

[V8.0.0.9 Mar 2018]From IBM MQ 8.0.0, Fix Pack 9 and with APAR IT22127, the deadlock within the IBM MQ Java client is fixed. If your Java application uses the Java Security Manager, you must add the following permission to the java.security.policy file used by the application, otherwise, exceptions will be thrown to the application:
permission java.lang.RuntimePermission "modifyThread";
This RuntimePermission is required by the client as part of managing the assignment and closure of multiplexed conversations over TCP/IP connections to queue managers.

Example policy file entry

Here is an example of a policy file entry that allows IBM MQ classes for Java to run successfully under the default security manager. Replace the string MQ_INSTALLATION_PATH in this example with the location where IBM MQ classes for Java are installed on your system.

grant codeBase "file: MQ_INSTALLATION_PATH/java/lib/*" {
//We need access to these properties, mainly for tracing
permission java.util.PropertyPermission "user.name","read";
permission java.util.PropertyPermission "os.name","read";
permission java.util.PropertyPermission "user.dir","read";
permission java.util.PropertyPermission "line.separator","read";
permission java.util.PropertyPermission "path.separator","read";
permission java.util.PropertyPermission "file.separator","read";
permission java.util.PropertyPermission "com.ibm.msg.client.commonservices.log.*","read";
permission java.util.PropertyPermission "com.ibm.msg.client.commonservices.trace.*","read";
permission java.util.PropertyPermission "Diagnostics.Java.Errors.Destination.Filename","read";
permission java.util.PropertyPermission "com.ibm.mq.commonservices","read";
permission java.util.PropertyPermission "com.ibm.mq.cfg.*","read";

//Tracing - we need the ability to control java.util.logging
permission java.util.logging.LoggingPermission "control";
// And access to create the trace file and read the log file - assumed to be in the current directory
permission java.io.FilePermission "*","read,write";

// Required to allow a trace file to be written to the filesystem.
// Replace 'TRACE_FILE_DIRECTORY' with the directory name where trace is to be written to
permission java.io.FilePermission "TRACE_FILE_DIRECTORY","read,write";
permission java.io.FilePermission "TRACE_FILE_DIRECTORY/*","read,write";

// We'd like to set up an mBean to control trace
permission javax.management.MBeanServerPermission "createMBeanServer";
permission javax.management.MBeanPermission "*","*";

// We need to be able to read manifests etc from the jar files in the installation directory
permission java.io.FilePermission "MQ_INSTALLATION_PATH/java/lib/-","read";

//Required if mqclient.ini/mqs.ini configuration files are used
permission java.io.FilePermission "MQ_DATA_DIRECTORY/mqclient.ini","read";
permission java.io.FilePermission "MQ_DATA_DIRECTORY/mqs.ini","read";

//For the client transport type.
permission java.net.SocketPermission "*","connect,resolve";

//For the bindings transport type.
permission java.lang.RuntimePermission "loadLibrary.*";

//For applications that use CCDT tables (access to the CCDT AMQCLCHL.TAB)
permission java.io.FilePermission "MQ_DATA_DIRECTORY/qmgrs/QM_NAME/@ipcc/AMQCLCHL.TAB","read";

//For applications that use User Exits
permission java.io.FilePermission "MQ_DATA_DIRECTORY/exits/*","read";
permission java.io.FilePermission "MQ_DATA_DIRECTORY/exits64/*","read";
permission java.lang.RuntimePermission "createClassLoader";

//Required for the z/OS platform
permission java.util.PropertyPermission "com.ibm.vm.bitmode","read";

// Used by the internal ConnectionFactory implementation
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";

// Used for controlled class loading
permission java.lang.RuntimePermission "setContextClassLoader";

// Used to default the Application name in Client mode connections
permission java.util.PropertyPermission "sun.java.command","read";

// Used by the IBM JSSE classes
permission java.util.PropertyPermission "com.ibm.crypto.provider.AESNITrace","read";

//Required to determine if an IBM Java Runtime is running in FIPS mode,
//and to modify the property values status as required.
permission java.util.PropertyPermission "com.ibm.jsse2.usefipsprovider","read,write";
permission java.util.PropertyPermission "com.ibm.jsse2.JSSEFIPS","read,write";
//Required if an IBM FIPS provider is to be used for SSL communication.
permission java.security.SecurityPermission "insertProvider.IBMJCEFIPS"; 

// Required for non-IBM Java Runtimes that establish secure client 
// transport mode connections using mutual TLS authentication
permission java.util.PropertyPermission "javax.net.ssl.keyStore","read";
permission java.util.PropertyPermission "javax.net.ssl.keyStorePassword","read";

[V8.0.0.9 Mar 2018]// Required for Java applications that use the Java Security Manager 
permission java.lang.RuntimePermission "modifyThread";  
};

This example of a policy file enables the IBM MQ classes for Java to work correctly under the security manager, but you might still need to enable your own code to run correctly before your applications work.

The sample code shipped with IBM MQ classes for Java has not been specifically enabled for use with the security manager; however the IVT tests run with this policy file and the default security manager in place.