无法从 MBean 访问 Singleton 类的实例数据
我正赶在最后期限前工作,现在我已经满头大汗了。 过去几天我一直在解决一个问题,现在是时候大声喊出来了。
我有一个应用程序(我们称之为“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();
}
}
I am working against the deadline and i am sweating now. From past few days I have been working on a problem and now its the time to shout out.
I have an application (let's call it "APP") and i have a "PerformanceStatistics" MBean written for APP. I also have a Singleton Data class (let's call it "SDATA") which provides some data for the MBean to access and calculate some application runtime stuff. Thus during the application startup and then in the application lifecycle, I will be adding data to the SDATA instance.So, this SDATA instance always has the data.
Now, the problem is that i am not able to access any of the data or data structures from the PerformanceStatistics MBean. if I check the data structures when I am adding the data, all the structures contains data. But when I call this singleton instance from the MBean, am kind of having the empty data.
Can anyone explain or have hints on what's happening ? Any help will be appreciated.
I tried all sorts of SDATA class being final and all methods being synchronized, static, etc.,, just to make sure. But no luck till now.
Another unfortunate thing is that, I some times get different "ServicePerformanceData " instances (i.e. when i print the ServicePerformanceData.getInstance() they are different at different times). Not sure whats happening. I am running this application in WebLogic server and using the JConsole.
SDATA class with single ton and data access methods
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 Class When i call the data like ServicePerformanceData .getInstance(), i have nothing in that structure. Thus i am not able to get any result with this.
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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
难道该类是从不同的类加载器加载的?
Could it be that the class is loaded from different class loaders?
首先删除所有“INSTANCE”。 : 你不需要它们。 serviceNameSet = INSTANCE.serviceNameSet = ServicePerformanceData.INSTANCE.serviceNameSet :这是同一件事。
然后您会意识到您的方法 copyAllMasterData 没有执行任何操作。 它只是从集合中取出元素并将它们放入同一集合中。 将数据放入集合中的唯一位置(例如 serviceNameSet)是在 add 方法中,我没有看到它(add 方法)在任何地方被调用。
First remove all the "INSTANCE." : you don't need them. serviceNameSet = INSTANCE.serviceNameSet = ServicePerformanceData.INSTANCE.serviceNameSet : it's the same thing.
Then you will realise that your method copyAllMasterData doesn't do anything. It just takes the elements from a set and puts them in the same set. The only place where you put data in your sets (serviceNameSet for example) is in the add method and I don't see it (add method) called anywhere.
经过大量研究并仔细研究设计后,这似乎是 Weblogic 类加载器的问题。 我的产品有 6 个不同的应用程序,并且不能保证同一个调用加载程序加载所有应用程序。
因此,在上述情况下,实际数据在由 ClassLoader_X 加载的类中更新,并且访问由 ClassLoader_Y 的类完成。 显然,数据在类加载器之间并不透明。 因此,我总是拥有同一类的不同实例,并且访问器类中的数据始终为空。
一旦我将数据创建和消费类移动到单个应用程序/Jar 中,一切都会正常运行。 我没有更改上面的任何代码。
After a lot of research and carefully looking into the design, this seems to be a problem with the Weblogic class loaders. My product has 6 different applications and it is not warranted that the same call loader loads all the applications.
Thus, in the above case, the actual data is getting updated in a class loaded by ClassLoader_X and the access is done by the class with ClassLoader_Y. Clearly, the data is not transparent across the class loaders. So, i always have the different instances of the same class and the data in the accessor class is always empty.
Once i moved both the data creation and consumption classes to a single application/Jar, everything works good. I did not change any of the above code.