2009-07-19 94 views
0

我正在針對截止日期工作,現在我正在出汗。從過去的幾天來,我一直在努力解決問題,現在是時候大聲疾呼。無法從MBean訪問單例類的實例數據

我有一個應用程序(讓我們稱之爲「APP」),我有一個爲APP編寫的「PerformanceStatistics」MBean。我還有一個Singleton Data類(我們稱之爲「SDATA」),它爲MBean提供一些數據以訪問和計算某些應用程序運行時的內容。因此,在應用程序啓動期間,然後在應用程序生命週期中,我將向SDATA實例添加數據。因此,此SDATA實例始終具有數據。

現在,問題是我無法從PerformanceStatistics MBean訪問任何數據或數據結構。如果我在添加數據時檢查數據結構,則所有結構都包含數據。但是當我從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完成。顯然,數據在類加載器中不透明。所以,我總是擁有同一類的不同實例,並且訪問器類中的數據總是空的。

一旦我將數據創建和消費類都移動到單個應用程序/ Jar,一切都很好。我沒有更改任何上述代碼。

0

難道類是從不同的類加載器加載?

0

首先刪除所有「INSTANCE」。 :你不需要它們。 serviceNameSet = INSTANCE.serviceNameSet = ServicePerformanceData.INSTANCE.serviceNameSet:它是一樣的東西。

然後您會意識到您的方法copyAllMasterData不會執行任何操作。它只是從一組中的元素並將它們放在同一組中。將數據放入集合中的唯一位置(例如serviceNameSet)位於add方法中,並且我沒有看到它在任何地方調用(add方法)。