Как вернуть значение объекта при использовании пружинной загрузки jmx
Я использую пружинную загрузку jmx для удаленного выполнения метода при изменении базы данных. Все работает хорошо, и я мог контролировать свое приложение, используя jmc.exe в Windows, когда я использую примитивный тип данных в качестве возвращаемого значения. Теперь мне нужно вернуть значение 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;
}
1 ответ
Решение
Вы должны вернуть 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;
}
}