1

当数据库发生更改时,我正在使用 spring boot jmx 远程执行该方法。每件事都运行良好,当我使用原始数据类型作为返回值时,我可以在 Windows 中使用 jmc.exe 监控我的应用程序。现在我需要返回对象(不是原始数据类型,而是一个类)值作为我的方法的返回值。实际上,这个对象与我的班级在同一个包中。但是当我使用 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;
}
4

1 回答 1

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;
    }
}
于 2018-05-25T11:04:35.057 回答