在7.5中的第一个mq API调用上,我的带有链接式jdk的已编译代码应用程序失败,但无论使用classpath配置如何,都可以使用6.x API进行工作。来自mqm发行版的非常相似的示例代码在我的相同环境中工作。
在企业环境中,我暂时无法迁移到7.5以上的版本;我知道mq / 7.5自2018年4月起获得了扩展支持(不再定期支持)。
我有一个c ++编译的应用程序(solaris x86),该应用程序链接到1.7.0 jdk并调用JNI_CreateJavaVM()创建Java运行时(某些代码在c ++中,有些在Java中)。该代码在mq版本6上已经使用了很长时间。它在第一次调用“ new MQTopicConnectionFactory()”时失败,并向stderr发送了FFST报告。
Solaris / 11,jdk / 1.7.0,mq / 7.5.0.9。我已经尝试了32位和64位以及jdk / 1.8.0。我在FFST报告中收到以下错误:
com.ibm.msg.client.commonservices.CSIException:JMSCS0002
当尝试在内部调用某些方法的反射时,它是一个java.lang.NullPointerException。看来是类加载器问题,因为jdk无法通过反射调用找到该类。
但是,当我在完全相同的环境中的/ opt / mqm / samp / jms / samples / simple目录中运行SimpleWMQJMSPubSub.java程序时,该程序可以正常工作。该示例代码还将第一个(有趣的)与mq相关的调用也称为“新MQTopicConnectionFactory()”。
搜索JMSCS0002错误似乎表明这是类路径问题或环境问题,其中罐子已被复制/移动/重命名。这是我的计算机上全新安装的7.5.0.9发行版,没有任何更改。此外,我感觉由于示例程序在这种环境下可以工作,因此环境差异必须在jvm链接的二进制文件中。
我已经尝试将我的jvm的类路径环境设置为/opt/mqm/java/lib/com.ibm.mqjms.jar(与示例mqm代码完美配合),并且尝试了将类路径设置为指向/ opt / mqm / java / lib中显式的每个jar,并且我尝试将其设置为仅目录本身/ opt / mqm / java / lib / *;所有这些尝试都会导致我的代码中的相同失败,而所有这些尝试都在示例代码中成功。
在我的程序上运行truss并通过示例代码确认底层的jvm正在打开相同的jar,但有一点区别:java调用的示例打开/读取/关闭了每个jar,而与jdk链接的应用程序似乎打开/读取(但不要关闭)每个罐子。我不确定为什么这种行为会有所不同。这是桁架的过滤输出,显示了我的应用程序正在打开的罐子:
2847:19468/1: open("/system/pkg/jdk/1.7.0_72/src/x86_64-pc-solaris2.10/jdk1.7.0_72/jre/lib/rt.jar", O_RDONLY) = 10
4804:19468/1: open("/opt/mqm/java/lib/com.ibm.mqjms.jar", O_RDONLY) = 16
4871:19468/1: open("/opt/mqm/java/lib/jms.jar", O_RDONLY) = 17
4888:19468/1: open("/opt/mqm/java/lib/com.ibm.mq.jmqi.jar", O_RDONLY) = 18
4907:19468/1: open("/opt/mqm/java/lib/jta.jar", O_RDONLY) = 19
4924:19468/1: open("/opt/mqm/java/lib/com.ibm.mq.headers.jar", O_RDONLY) = 20
4941:19468/1: open("/opt/mqm/java/lib/com.ibm.mq.jar", O_RDONLY) = 21
4958:19468/1: open("/opt/mqm/java/lib/com.ibm.mq.pcf.jar", O_RDONLY) = 22
4976:19468/1: open("/opt/mqm/java/lib/connector.jar", O_RDONLY) = 23
4993:19468/1: open("/opt/mqm/java/lib/com.ibm.mq.commonservices.jar", O_RDONLY) = 24
5008:19468/1: open("/opt/mqm/java/lib/dhbcore.jar", O_RDONLY) = 25
5027:19468/1: open("/opt/mqm/java/lib/rmm.jar", O_RDONLY) = 26
5047:19468/1: open("/opt/mqm/java/lib/jndi.jar", O_RDONLY) = 27
5066:19468/1: open("/opt/mqm/java/lib/ldap.jar", O_RDONLY) = 28
5081:19468/1: open("/opt/mqm/java/lib/fscontext.jar", O_RDONLY) = 29
5098:19468/1: open("/opt/mqm/java/lib/providerutil.jar", O_RDONLY) = 30
5117:19468/1: open("/opt/mqm/java/lib/CL3Export.jar", O_RDONLY) = 31
11229:19468/93: open("/system/pkg/jdk/1.7.0_72/src/x86_64-pc-solaris2.10/jdk1.7.0_72/jre/lib/rt.jar", O_RDONLY) = 50
有效的示例代码:
public class SimpleWMQJMSPubSub {
// System exit status value (assume unset value to be 1)
private static int status = 1;
/**
* Main method
*
* @param args
*/
public static void main(String[] args) {
// Variables
MQTopicConnection connection = null;
MQTopicSession session = null;
MQTopic topic = null;
MQTopicPublisher publisher = null;
MQTopicSubscriber subscriber = null;
try {
// Create a connection factory
MQTopicConnectionFactory cf = new MQTopicConnectionFactory();
// Set the properties
cf.setHostName("mq");
cf.setPort(1414);
cf.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
cf.setQueueManager("QMAPC");
cf.setChannel("JAVA.CHANNEL");
我的失败代码:
public MQConnection(String newHostname, String newQueueManagerName,
int newPort, String newChannelName,
String newClientId, String newBrokerSubqueueName) {
this.hostname = newHostname;
this.queueManagerName = newQueueManagerName;
this.port = newPort;
this.channelName = newChannelName;
this.clientId = newClientId;
this.brokerSubqueueName = newBrokerSubqueueName;
try {
factory = new MQTopicConnectionFactory();
factory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
factory.setQueueManager(queueManagerName);
factory.setHostName(hostname);
factory.setChannel(channelName);
factory.setClientId(clientId);
factory.setPort(port);
两个块的代码都具有(几乎)相同的import子句(为简洁起见,未显示)(我的程序还有其他一些子句,因为它调用了其他API,但是mq的导入极为相似)。
这是在我的应用程序中创建jvm的方式:最大堆设置为256M,最小堆设置为64M。我也尝试过使用更大的值,没有区别。 AHIJAVA_OPTIONS_COUNT = 5
void jvmSession::initJvm() {
if (!jvmExists) {
JavaVMInitArgs vm_args;
JavaVMOption options[AHIJAVA_OPTIONS_COUNT];
JNIEnv *aThrowawayEnv;
jint result;
RWCString aClassPathOption = "-Djava.class.path=";
aClassPathOption.append(theClasspath.data());
RWCString aLibraryPathOption = "-Djava.library.path=";
aLibraryPathOption.append(theJavaLibraryPath.data());
RWCString disableJITOption = "-Djava.compiler=none";
RWCString aMaxHeapOption = "-Xmx";
aMaxHeapOption.append(theJavaMaxHeap.data());
RWCString aMinHeapOption = "-Xms";
aMinHeapOption.append(theJavaMinHeap.data());
options[0].optionString = (char *)aClassPathOption.data();
options[1].optionString = (char *)aLibraryPathOption.data();
options[2].optionString = (char *)disableJITOption.data();
options[3].optionString = (char *)aMaxHeapOption.data();
options[4].optionString = (char *)aMinHeapOption.data();
vm_args.version = 0x00010002;
vm_args.options = options;
vm_args.nOptions = AHIJAVA_OPTIONS_COUNT;
vm_args.ignoreUnrecognized = JNI_TRUE;
/* Create the Java VM */
result = JNI_CreateJavaVM(&theJvm, (void**)&aThrowawayEnv, &vm_args);
'新的MQTopicConnectionFactory()'引发NullPointerException,并且FFST报告被转储到stderr,由于StackOverflow的帖子大小限制和“这看起来像垃圾邮件”,误报,我只能发布不完整的部分:
FDCTitle
Product :- ProductName
Date/Time :- Fri Jul 12 19:31:42 EDT 2019
System time :- 1562974302503
Operating System :- SunOS
UserID :- rhb
Java Vendor :- Oracle Corporation
Java Version :- 24.72-b04
Source Class :- com.ibm.msg.client.commonservices.nls.PINLSServices
Source Method :- createException(String,HashMap)
ProbeID :- XC003001
Thread :- name=Thread-1 priority=5 group=main ccl=<ContextClassLoader is null>
Data
----
Data :- none
No Components Found
xxxxx
Stack trace to show the location of the FFST call
| FFST Location :- java.lang.Exception
| at com.ibm.msg.client.commonservices.trace.Trace.getCurrentPosition(Trace.java:2019)
| at com.ibm.msg.client.commonservices.trace.Trace.createFFSTString(Trace.java:1958)
| at com.ibm.msg.client.commonservices.trace.Trace.ffstInternal(Trace.java:1847)
| at com.ibm.msg.client.commonservices.trace.Trace.ffst(Trace.java:1660)
| at com.ibm.msg.client.commonservices.nls.PINLSServices.createException(PINLSServices.java:121)
| at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:233)
| at com.ibm.msg.client.jms.internal.JmsErrorUtils.createException(JmsErrorUtils.java:131)
| at com.ibm.msg.client.jms.internal.JmsFactoryFactoryImpl.getInstance(JmsFactoryFactoryImpl.java:172)
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
| at java.lang.reflect.Method.invoke(Method.java:606)
| at com.ibm.msg.client.jms.JmsFactoryFactory.getInstance(JmsFactoryFactory.java:182)
| at com.ibm.mq.jms.MQConnectionFactory.initialiseMQConnectionFactory(MQConnectionFactory.java:3296)
| at com.ibm.mq.jms.MQConnectionFactory.<init>(MQConnectionFactory.java:265)
| at com.ibm.mq.jms.MQTopicConnectionFactory.<init>(MQTopicConnectionFactory.java:78)
| at com.nvs.ahi.mq.MQConnection.<init>(MQConnection.java:85)
xxxxx
| connectionTypeName :- com.ibm.msg.client.wmq
| exception :- ExceptionDepth is 3
| exception :-
| | Cause:1 :- java.lang.reflect.InvocationTargetException
| | Cause:2 :- java.lang.NullPointerException
| | StackTrace:1 :- java.lang.reflect.InvocationTargetException
| | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
| | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
| | at java.lang.reflect.Method.invoke(Method.java:606)
| | at com.ibm.msg.client.jms.JmsFactoryFactory.getInstance(JmsFactoryFactory.java:182)
| | at com.ibm.mq.jms.MQConnectionFactory.initialiseMQConnectionFactory(MQConnectionFactory.java:3296)
| | at com.ibm.mq.jms.MQConnectionFactory.<init>(MQConnectionFactory.java:265)
| | at com.ibm.mq.jms.MQTopicConnectionFactory.<init>(MQTopicConnectionFactory.java:78)
| | at com.nvs.ahi.mq.MQConnection.<init>(MQConnection.java:85)
| | at com.nvs.ahi.mq.OutgoingConnection.<init>(OutgoingConnection.java:45)
| | at com.nvs.ahi.siview.AHISiViewAdapter.initMQ(AHISiViewAdapter.java:212)
| | at com.nvs.ahi.siview.AHISiViewAdapter.startIncoming(AHISiViewAdapter.java:474)
| | at com.nvs.ahi.jnibridge.AHIremote.startIncoming(AHIremote.java:105)
| | Caused by: java.lang.NullPointerException
| | at com.ibm.msg.client.jms.internal.JmsFactoryFactoryImpl.getInstance(JmsFactoryFactoryImpl.java:174)
| | ... 13 more
| |
| | StackTrace:2 :- java.lang.NullPointerException
| | at com.ibm.msg.client.jms.internal.JmsFactoryFactoryImpl.getInstance(JmsFactoryFactoryImpl.java:174)
| | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
| | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
| | at java.lang.reflect.Method.invoke(Method.java:606)
| | at com.ibm.msg.client.jms.JmsFactoryFactory.getInstance(JmsFactoryFactory.java:182)
| | at com.ibm.mq.jms.MQConnectionFactory.initialiseMQConnectionFactory(MQConnectionFactory.java:3296)
| | at com.ibm.mq.jms.MQConnectionFactory.<init>(MQConnectionFactory.java:265)
| | at com.ibm.mq.jms.MQTopicConnectionFactory.<init>(MQTopicConnectionFactory.java:78)
| | at com.nvs.ahi.mq.MQConnection.<init>(MQConnection.java:85)
| | at com.nvs.ahi.mq.OutgoingConnection.<init>(OutgoingConnection.java:45)
| | at com.nvs.ahi.siview.AHISiViewAdapter.initMQ(AHISiViewAdapter.java:212)
| | at com.nvs.ahi.siview.AHISiViewAdapter.startIncoming(AHISiViewAdapter.java:474)
| | at com.nvs.ahi.jnibridge.AHIremote.startIncoming(AHIremote.java:105)
| |
No Components Found