2009-07-19 13 views
0

締め切りに反対しており、今発汗しています。過去数日から私は問題に取り組んできましたが、今はその時を振り返ります。MBeanからシングルトンクラスのインスタンスデータにアクセスできません

私はアプリケーション(「APP」と呼ぶ)を持っており、APP用に「PerformanceStatistics」MBeanを作成しています。私はまた、Singleton Dataクラス( "SDATA"と呼ぶ)を持っています。これは、MBeanがいくつかのアプリケーション実行時のものにアクセスして計算するためのデータを提供します。したがって、アプリケーションの起動時に、アプリケーションのライフサイクル中に、SDATAインスタンスにデータを追加します。このSDATAインスタンスには常にデータがあります。

ここで問題は、PerformanceStatistics MBeanのデータ構造またはデータ構造にアクセスできないことです。データを追加するときにデータ構造をチェックすると、すべての構造にデータが含まれます。しかし、私がこのシングルトンインスタンスをMBeanから呼び出すと、空のデータを持っています。

何が起こっているのか説明したりヒントを挙げたりできますか?どんな助けもありがとう。

私はあらゆる種類のSDATAクラスが最終的で、すべてのメソッドが同期されていること、静的なものなどを試してみました。しかし今まで運がない。

また別の「ServicePerformanceData」インスタンス(ServicePerformanceData.getInstance()が異なる時刻に異なる場合)が表示されることがあります。何が起こっているかわからない。私は、WebLogic Serverと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); 
    } 
} 

} iがServicePerformanceData .getInstance()のようなデータを呼び出すと、私は

PerformanceStatistics MBeanのクラスその構造には何もない。したがって、私はこれで何の結果も得られません。

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を使用してクラスによってアクセスが行われます。明らかに、データはクラスローダー間で透過的ではありません。だから、私はいつも同じクラスの異なるインスタンスを持ち、アクセサークラスのデータは常に空です。

データ作成と消費の両方のクラスを1つのアプリケーション/ Jarに移動すると、すべて正常に動作します。私は上記のコードを変更しませんでした。

0

それはクラスが別のクラスローダからロードされていることだろうか?

0

最初にすべての「インスタンス」を削除します。あなたはそれらを必要としません。 serviceNameSet = INSTANCE.serviceNameSet = ServicePerformanceData.INSTANCE.serviceNameSet:同じことです。

あなたはcopyAllMasterDataメソッドが何もしないことに気付きます。それは単に要素から要素を取り出し、同じ要素に置きます。あなたのセット(例えばserviceNameSet)にデータを入れる唯一の場所はaddメソッドであり、どこでも呼び出される(addメソッド)はありません。