Apigee Edge unable to initialize IBM MQ client classes.

I was trying to create a API Proxy in Apigee with Back-End being a Java Callout policy. The Java Callout policy refers to a custom class that i created (jar) which writes messages to IBM MQ. This custom IBM MQ client class refers to IBM MQ libraries (com.ibm.mq.commonservices.jar/com.ibm.mq.headers.jar/com.ibm.mq.jar/com.ibm.mq.jmqi.jar/connector.jar)

Added the dependent jars in API Proxy as shown in the screen shot below.

5907-apigee.jpg

I get the following error when I invoke the Apigee API proxy (from trace):

errornull
error.causeaccess denied ("javax.management.MBeanServerPermission" "createMBeanServer")
error.classjava.lang.ExceptionInInitializerErro


Response from Apigee Proxy invocation:

{"fault": {"faultstring": "Could not initialize class com.ibm.mq.internal.MQCommonServices", "detail": {

"errorcode": "Internal Server Error" }

}

}

However, when I run the client java class from eclipse, it works perfectly, posting message to IBM MQ. It seems to me that somehow Apigee is not able to load the dependent IBM jars to the memory/not able to initialize the IBM client classes.

Could anybody please help?

Thanks,

Aneesh.

0 2 1,305
2 REPLIES 2

I feel confident that you are running into a security exception.

Apigee Edge does not allow arbitrary classes to run. The MBeanServer class is restricted, according to the Java Security Policy file which is in place for the Java callouts.

This means you cannot load that JAR.

If you search for answers on the internet about running the MQ client in a container (like a Servlet container), many of them suggest modifying the security policy file for the container.

For Customer-Managed installations of Apigee Edge

If you are using a customer-managed Apigee Edge, of course you have access to the security policy file. The location is /opt/apigee/edge-message-processor-4.17.01-0.0.967/conf/security.policy . I believe you can override this via CWC.

You would need to add a grant section like this:

grant codeBase "file:${javacallout.dir}/-"  {
    permission com.apigee.securitypolicy.AllExcept "5000";
    permission javax.management.MBeanServerPermission "createMBeanServer";
    permission java.io.FilePermission "${javacallout.dir}/-" , "read";
}

Then you'd need to restart the MPs.

But as this is a security change, please be aware of the implications of the change.

For Edge SaaS

You cannot modify the Security policy that applies to a Java callout in Apigee Edge SaaS. That policy file is under the control of Apigee and it will not change.

You may be able to workaround the problem by turning off diagnostics for the MQ client. I found this article describing the properties file that applies. According to my quick reading, Diagnostics.MQ is enabled by default. It's possible that if you set it to "disabled" then the library won't try to start the MBean server. I'm not sure how you would provide this properties file to a Java callout - a Java callout cannot read regular filesystem files. You may be able to provide the properties to the MQ client via a resource embedded in your callout JAR. But even if you get that to work, it still may not solve the problem. I'm only guessing.

A better approach might be to build an HTTP service that wraps MQ, and then invoke the HTTP service. The HTTP service would need to be hosted somewhere that is accessible to the Edge message processor.

Good luck!

Hi Dino,

Thanks for the explanation.

I tried a similar pattern with Kafka. The only external library/jar that i had to refer was "kafka-clients-1.0.0.jar". I am getting similar kind of error with Kafka pattern. Anything I can try to get this working?

<code>java.security.AccessControlException: access denied ("javax.management.MBeanServerPermission" "createMBeanServer")

Thanks,
Aneesh.