Не удается получить доступ к данным экземпляра класса Singleton из MBean - PullRequest
0 голосов
/ 20 июля 2009

Я работаю против крайнего срока и сейчас потею. В последние несколько дней я работал над проблемой, и теперь пришло время кричать.

У меня есть приложение (назовем его «APP»), и у меня есть MBean «PerformanceStatistics», написанный для APP. У меня также есть класс данных Singleton (назовем его «SDATA»), который предоставляет некоторые данные для MBean для доступа и вычисления некоторых вещей времени выполнения приложения. Таким образом, во время запуска приложения, а затем в жизненном цикле приложения я буду добавлять данные в экземпляр SDATA. Итак, этот экземпляр SDATA всегда содержит данные.

Теперь проблема в том, что я не могу получить доступ к каким-либо данным или структурам данных из MBean PerformanceStatistics. если я проверяю структуры данных при добавлении данных, все структуры содержат данные. Но когда я вызываю этот экземпляр синглтона из MBean, у меня вроде бы пустые данные.

Может кто-нибудь объяснить или намекнуть на то, что происходит? Любая помощь будет оценена.

Я попробовал все виды классов SDATA, которые были окончательными, и все методы были синхронизированы, статические и т. Д., Просто чтобы убедиться. Но не повезло до сих пор.

Еще одна неприятная вещь заключается в том, что я иногда получаю разные экземпляры «ServicePerformanceData» (т.е. когда я печатаю ServicePerformanceData.getInstance (), они отличаются в разное время). Не уверен, что происходит. Я запускаю это приложение на сервере WebLogic и использую JConsole.

Класс SDATA с одной тонной и методами доступа к данным

public class ServicePerformanceData {

private Hashtable<String, ServiceExecutionDataCollector> serviceExecutionDataMap = new Hashtable<String, ServiceExecutionDataCollector>();
private HashMap<ServiceExecutionType, String> serviceTypeCountMap = new HashMap<ServiceExecutionType, String>();
private HashSet<String> serviceNameSet = new HashSet<String>();

private static final long DEFAULT_COUNT = 1;
private static final ServicePerformanceData INSTANCE = new ServicePerformanceData();
private Object SYNC = new Object();

private ServicePerformanceData() {
    // don't allow anyone to instantiate this class
}

// clearly this must be a singleton
public static ServicePerformanceData getInstance() {
    return INSTANCE;
}

public void add(ServiceExecutionDataCollector data) {
    // I just add some runtime information to the data structures in this INSTANCE
    synchronized (SYNC) {
        if (INSTANCE.serviceTypeCountMap.containsKey(data.getServiceType())) {
            String count = INSTANCE.serviceTypeCountMap.get(data.getServiceType());
            INSTANCE.serviceTypeCountMap.put(data.getServiceType(), Integer.toString(Integer.parseInt(count) + 1));
        } else {
            INSTANCE.serviceTypeCountMap.put(data.getServiceType(), Integer.toString(1));
        }

        INSTANCE.serviceExecutionDataMap.put(data.getServiceName(), data);
        INSTANCE.serviceNameSet.add(data.getServiceName());
    }
}

public int getServiceTypeCount(ServiceExecutionType type) {
    if (INSTANCE.serviceTypeCountMap.containsKey(type)) {
        return Integer.parseInt(INSTANCE.serviceTypeCountMap.get(type));
    }
    return 0;
}

public Set getNameList() {
    return INSTANCE.serviceNameSet;
}

// I am copying all the data just to make sure that data structures have data
public void copyAllMasterData() {
    synchronized (SYNC) {
        serviceExecutionDataMap.putAll(ServicePerformanceData.INSTANCE.serviceExecutionDataMap);
        serviceNameSet.addAll(ServicePerformanceData.INSTANCE.serviceNameSet);
        serviceTypeCountMap.putAll(ServicePerformanceData.INSTANCE.serviceTypeCountMap);
    }
}

}

PerformanceStatistics MBean Class Когда я вызываю данные, такие как ServicePerformanceData .getInstance (), у меня ничего нет в этой структуре. Таким образом, я не могу получить никакого результата с этим.

public class PerformanceStatistics
    implements PerformanceStatisticsMBean {

public void completeExecutionDump() {
    //
}


public int getexecuteSSCount() {
    return ServicePerformanceData.getInstance().getServiceTypeCount(ServiceExecutionType.ADD);
}

public String executionInfo(String serviceName) {
    // GIVES EMPTY LIST EVEN THOUGH THE ACTUAL instance HAS THE DATA
    return ServicePerformanceData.getInstance().getExecutionInfo(serviceName.trim());
}

public String calledServicesArray() {
    // servicePerformanceData DOES NOT CONTAIN ANY DATA EVEN THOUGH THE ACTUAL instance HAS THE DATA
    ServicePerformanceData servicePerformanceData = ServicePerformanceData.getInstance();
    servicePerformanceData.copyAllMasterData();

    System.out.println("ServicePerformanceData.INSTANCE" + ServicePerformanceData.getInstance());
    System.out.println(servicePerformanceData);

// GIVES EMPTY LIST EVEN THOUGH THE ACTUAL instance HAS THE DATA
    System.out.println("Name List" + ServicePerformanceData.getInstance().getNameList());

    return ServicePerformanceData.getInstance().getNameList().toString();
}

}

Ответы [ 3 ]

0 голосов
/ 14 августа 2009

Сначала удалите все «МОМЕНТ». : они тебе не нужны. serviceNameSet = INSTANCE.serviceNameSet = ServicePerformanceData.INSTANCE.serviceNameSet: это одно и то же.

Тогда вы поймете, что ваш метод copyAllMasterData ничего не делает. Он просто берет элементы из набора и помещает их в один и тот же набор. Единственное место, где вы помещаете данные в свои наборы (например, serviceNameSet), находится в методе add, и я не вижу, чтобы он (метод add) вызывался где-либо еще.

0 голосов
/ 05 ноября 2009

После долгих исследований и тщательного изучения дизайна, кажется, это проблема с загрузчиками классов Weblogic. У моего продукта 6 различных приложений, и нет гарантии, что один и тот же загрузчик вызовов загружает все приложения.

Таким образом, в вышеупомянутом случае фактические данные обновляются в классе, загруженном ClassLoader_X, и доступ осуществляется классом с ClassLoader_Y. Очевидно, что данные не являются прозрачными для загрузчиков классов. Итак, у меня всегда есть разные экземпляры одного и того же класса, а данные в классе доступа всегда пустые.

Как только я переместил классы создания и потребления данных в одно приложение / Jar, все работает хорошо. Я не изменил ни один из приведенных выше кодов.

0 голосов
/ 03 августа 2009

Может быть, класс загружается из разных загрузчиков классов?

...