views:

238

answers:

3

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 lifecysle, 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, ect.,, 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();
}

}

A: 

Could it be that the class is loaded from different class loaders?

Kire Haglin
A: 

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.

Silence
A: 

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.

EclipseGuru