无法从MBean访问单例类的实例数据

问题描述:

我正在针对截止日期工作,现在我正在出汗。从过去的几天来,我一直在努力解决问题,现在是时候大声疾呼。无法从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(); 
} 

}

经过大量研究和仔细研究设计之后,这似乎是Weblogic类加载器的一个问题。我的产品有6种不同的应用程序,并且不保证相同的调用加载程序加载所有应用程序。

因此,在上述情况下,实际数据在ClassLoader_X加载的类中得到更新,并且访问由类ClassLoader_Y完成。显然,数据在类加载器中不透明。所以,我总是拥有同一类的不同实例,并且访问器类中的数据总是空的。

一旦我将数据创建和消费类都移动到单个应用程序/ Jar,一切都很好。我没有更改任何上述代码。

难道类是从不同的类加载器加载?

首先删除所有“INSTANCE”。 :你不需要它们。 serviceNameSet = INSTANCE.serviceNameSet = ServicePerformanceData.INSTANCE.serviceNameSet:它是一样的东西。

然后您会意识到您的方法copyAllMasterData不会执行任何操作。它只是从一组中的元素并将它们放在同一组中。将数据放入集合中的唯一位置(例如serviceNameSet)位于add方法中,并且我没有看到它在任何地方调用(add方法)。