Spring boot 如何在使用spring boot jmx时返回对象值
我使用SpringBootJMX在数据库发生更改时远程执行该方法。当我使用原始数据类型作为返回值时,我可以在windows中使用jmc.exe监控我的应用程序。现在我需要返回对象(不是基元数据类型,而是类)值作为方法的返回。实际上,这个对象和我的类在同一个包中。但是当我使用jmx远程运行该方法时,我得到Spring boot 如何在使用spring boot jmx时返回对象值,spring-boot,jconsole,spring-jmx,jmc,Spring Boot,Jconsole,Spring Jmx,Jmc,我使用SpringBootJMX在数据库发生更改时远程执行该方法。当我使用原始数据类型作为返回值时,我可以在windows中使用jmc.exe监控我的应用程序。现在我需要返回对象(不是基元数据类型,而是类)值作为方法的返回。实际上,这个对象和我的类在同一个包中。但是当我使用jmx远程运行该方法时,我得到 java.rmi.UnmarshalException: error unmarshalling return; nested exception is: java.lang.ClassNot
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: com.ff.KeyValue (no security manager: RMI class loader disabled).
我的代码如下
@Service
@ManagedResource(description = "JMX managed resource for updating map when database is updated",
objectName = "chargeCode:name=ChargeCodeService")
public class ChargeCodeService {
private static final Logger logger = LoggerFactory.getLogger(ChargeCodeService.class);
private final ChargeCodeRepository chargeCodeRepository;
private Map<String, KeyValue<String,String>> chargeCodeMap = new HashMap<>();
@Autowired
public ChargeCodeService(ChargeCodeRepository chargeCodeRepository) {
this.chargeCodeRepository = chargeCodeRepository;
}
@PostConstruct
@ManagedOperation
public Map<String, KeyValue<String,String>> chargeCodMapInitial() {
logger.info("ready to read chargeCode data from database. this operation will do when an update occure in database");
List<ChargeCode> chargeCodes = chargeCodeRepository.findAll();
for (ChargeCode chargeCode : chargeCodes) {
chargeCodeMap.put(chargeCode.getIacChargeCode(),new KeyValue<>( chargeCode.getBankChargeCode(),chargeCode.getTopupProvider()));
}
return chargeCodeMap;
}
@ManagedAttribute
public Map<String, KeyValue<String, String>> getChargeCodeMap() {
return chargeCodeMap;
}
}
必须将CompositeData或TablerDataSupport作为返回类型返回。下面的代码演示了这两种方法,应该适用于您。如果您有任何问题,请告诉我
package com.example.demo;
导入org.springframework.jmx.export.annotation.ManagedOperation;
导入org.springframework.jmx.export.annotation.ManagedOperationParameter;
导入org.springframework.jmx.export.annotation.ManagedOperationParameters;
导入org.springframework.jmx.export.annotation.ManagedResource;
导入org.springframework.stereotype.Component;
导入javax.management.openmbean.*;
@组成部分
@ManagedResource(objectName=“com.example.demo.jmx:name=ServerManager”,
description=“服务器管理器”。)
公共类抽样操作{
私有静态最终字符串[]itemNames=新字符串[]{“name”,“age”};
私有静态最终字符串[]itemDescription=新字符串[]{“您的姓名”、“您的年龄”};
私有静态最终OpenType[]itemTypes=新OpenType[]{
SimpleType.STRING,
SimpleType.INTEGER
};
公共静态最终字符串IAC\U CHARGE\u CODE=“IacChargeCode”;
公共静态最终字符串BANK\u CHARGE\u CODE=“BankChargeCode”;
公共静态最终字符串TOP\u UP\u PROVIDER=“TopUpProvider”;
公共静态最终字符串[]rowItemNames=新字符串[]{IAC\u费用\u代码、银行费用\u代码、充值\u提供者};
公共静态最终字符串[]rowItemDescriptions=新字符串[]{
“Iac费用代码”,
“银行收费代码”,
“充值提供程序”
};
@ManagedOperation(description=“获取复杂对象”)
@ManagedOperationParameters({
@ManagedOperationParameter(name=“name”,description=“Your name”),
@ManagedOperationParameter(name=“age”,description=“Your age.”)的名称)
public CompositeData simpleData(字符串名称,整数年龄)引发异常{
CompositeType CompositeType=新的CompositeType(
“姓名和年龄”,
“姓名和年龄”,
项目名称、项目描述、项目类型);
CompositeData数据=新的CompositeDataSupport(compositeType、ItemName、新对象[]{
姓名、年龄
});
返回数据;
}
@ManagedOperation(description=“从数据库检索重编码”)
public tablerDataSupport tabular()引发OpenDataException{
OpenType[]行项目类型=新OpenType[]{
SimpleType.STRING,SimpleType.STRING,SimpleType.STRING
};
CompositeType compositeRowType=新的CompositeType(
“chargeRow”,
“某一行”,
行项目名称,
行项目描述,
行项目类型);
TABLARTYPE TABLARTYPE=新TABLARTYPE(
“收费表”,
“收费表样本”,
复合式,
行项目名称);
TablerDataSupport行=新的TablerDataSupport(TablerType);
rows.putAll(新合成数据[]{
新的CompositeDataSupport(compositeRowType、rowItemNames、新对象[]{
“费用代码#1”、“银行费用代码#1”、“充值#1”
}),
新的CompositeDataSupport(compositeRowType、rowItemNames、新对象[]{
“费用代码#2”、“银行费用代码#2”、“充值#2”
}),
新的CompositeDataSupport(compositeRowType、rowItemNames、新对象[]{
“费用代码#3”、“银行费用代码#3”、“充值#3”
}),
});
返回行;
}
}
JVM(发出JMX命令的JVM)不知道您的类。只有服务器知道您的类,因此您将得到错误。谢谢,但是如何通过编程让JVM知道我的类呢。这两个类都在同一个应用程序和同一个包中Hank的很多。这正是我想要的。你为我节省了很多时间。
public class KeyValue<K, V> implements Map.Entry<K, V>, Serializable {
private static final long serialVersionUID = -2610138893852455839L;
private K key;
private V value;
public KeyValue() {
}
public KeyValue(K key, V value)
{
this.key = key;
this.value = value;
}
getter,setter;
}