2009-07-19 4 views
0

Я работаю против установленного срока, и теперь я вспотел. С прошлых нескольких дней я работал над проблемой, и теперь настало время кричать.Невозможно получить доступ к данным экземпляра класса Singleton из MBean

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

Проблема в том, что я не могу получить доступ к какой-либо структуре данных или данных из PerformanceStatistics MBean. если я проверяю структуры данных, когда добавляю данные, все структуры содержат данные. Но когда я вызываю этот экземпляр singleton из 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 Класс Когда я называть данные, как 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(); 
} 

}

ответ

0

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

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

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

0

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

0

Сначала удалите все «INSTANCE». : они вам не нужны. serviceNameSet = INSTANCE.serviceNameSet = ServicePerformanceData.INSTANCE.serviceNameSet: это то же самое.

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

Смежные вопросы