MBean

2009-07-19 8 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); 
    } 
} 

} 난 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를 사용하여 클래스에서 액세스가 수행됩니다. 분명히 데이터는 클래스 로더 전체에서 투명하지 않습니다. 그래서 항상 동일한 클래스의 다른 인스턴스를 가지며 접근 자 클래스의 데이터는 항상 비어 있습니다.

일단 데이터 생성 및 소비 클래스를 단일 응용 프로그램/Jar로 이동하면 모든 것이 잘 작동합니다. 위 코드를 변경하지 않았습니다.

0

는이 클래스가 다른 클래스 로더에서로드되는 것을 될 수 있을까요?

0

먼저 모든 "인스턴스"를 제거하십시오. : 당신은 그 (것)들을 필요로하지 않는다. serviceNameSet = INSTANCE.serviceNameSet = ServicePerformanceData.INSTANCE.serviceNameSet : 동일한 작업입니다.

그러면 copyAllMasterData 메서드가 아무 것도하지 않는다는 것을 알 수 있습니다. 그것은 단지 집합에서 요소를 가져 와서 같은 집합에 넣습니다. 데이터를 세트 (예 : serviceNameSet)에 넣는 유일한 위치는 add 메소드에 있으며 어디서든 호출 된 (add 메소드)는 표시되지 않습니다.

관련 문제