如何在使用 Spring 引导 JMX 时返回对象值



当数据库中发生更改时,我正在使用 spring boot jmx 远程执行该方法。一切都运行良好,当我使用原始数据类型作为返回值时,我可以在窗口中使用 jmc.exe 监控我的应用程序。现在我需要返回 Object(不是原始数据类型,而是类(值作为我的方法的返回。实际上,这个对象与我的类位于同一包中。但是当我使用 jmx 远程运行该方法时,我得到

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;
}
}

KeyValue类如下:

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;
}

必须返回 CompositeData 或 TabularDataSupport 作为返回类型。以下代码演示了两者,应该适合您。如果您有任何问题,请告诉我。

package com.example.demo;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedOperationParameter;
import org.springframework.jmx.export.annotation.ManagedOperationParameters;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.stereotype.Component;
import javax.management.openmbean.*;
@Component
@ManagedResource(objectName="com.example.demo.jmx:name=ServerManager",
description="Server manager.")
public class SampleOperation {
private static final String[] itemNames = new String[] { "name", "age" };
private static final String[] itemDescription = new String[] { "Your name", "Your age" };
private static final OpenType<?>[] itemTypes = new OpenType[] {
SimpleType.STRING,
SimpleType.INTEGER
};
public static final String IAC_CHARGE_CODE = "IacChargeCode";
public static final String BANK_CHARGE_CODE = "BankChargeCode";
public static final String TOP_UP_PROVIDER = "TopUpProvider";
public static final String[] rowItemNames = new String[] { IAC_CHARGE_CODE, BANK_CHARGE_CODE, TOP_UP_PROVIDER };
public static final String[] rowItemDescriptions = new String[] {
"Iac charge code",
"Bank charge code",
"Top up provider"
};
@ManagedOperation(description="Get the complex object.")
@ManagedOperationParameters({
@ManagedOperationParameter(name="name", description= "Your name."),
@ManagedOperationParameter(name="age", description= "Your age.")})
public CompositeData simpleData(String name, int age) throws Exception {
CompositeType compositeType = new CompositeType(
"NameAndAge",
"name and age",
itemNames, itemDescription, itemTypes);
CompositeData data = new CompositeDataSupport(compositeType, itemNames, new Object[] {
name, age
});
return data;
}
@ManagedOperation(description="Retrieve recodes from DB.")
public TabularDataSupport tabular() throws OpenDataException {
OpenType<?>[] rowItemTypes = new OpenType[]{
SimpleType.STRING, SimpleType.STRING, SimpleType.STRING
};
CompositeType compositeRowType = new CompositeType(
"chargeRow",
"some row",
rowItemNames,
rowItemDescriptions,
rowItemTypes);
TabularType tabularType = new TabularType(
"charge table",
"Sample table of charge",
compositeRowType,
rowItemNames);
TabularDataSupport rows = new TabularDataSupport(tabularType);
rows.putAll(new CompositeData[]{
new CompositeDataSupport(compositeRowType, rowItemNames, new Object[]{
"charge code #1", "bank charge code #1", "Top up #1"
}),
new CompositeDataSupport(compositeRowType, rowItemNames, new Object[]{
"charge code #2", "bank charge code #2", "Top up #2"
}),
new CompositeDataSupport(compositeRowType, rowItemNames, new Object[]{
"charge code #3", "bank charge code #3", "Top up #3"
}),
});
return rows;
}
}

最新更新