Page 1 of 1
sharing runtime objects between java server extensions
Posted: 31 Oct 2007, 21:15
by zood
Hi there,
We have run into a scenario where a couple of our zone-level extensions need to share some java objects at runtime. We assumed that creating a get_instance() method and passing a reference from one extension to the other would do the trick, but the reference to the target extension does not point to the same instance as desired.
When accessing static members of the target class, data is not as expected, leading us to believe that the extension loaders are segregated in some way.
Is this correct? Is there some way we can work around it?
Thanks so much!
~zood
Posted: 01 Nov 2007, 09:22
by Lapo
I should see the code to better understand what you're doing anyways it seems to me that you're on the right track.
All you have to do is create a
Singleton and then reference it from any of your extension.
Code: Select all
When accessing static members of the target class, data is not as expected, leading us to believe that the extension loaders are segregated in some way.
No, all extension can see the other classes.
Posted: 01 Nov 2007, 23:43
by zood
We tried using Singletons, but there seem to be multiple instances of static members depending on which extension references them. For example, we have FirstExtension, SecondExtension, and HelperSingleton class (not an sfs Extension).
HelperSingleton successfully initializes its static member HelperSingleton._instance. After FirstExtension references HelperSingleton, when examined in the debugger from SecondExtension, HelperSingleton._instance is still uninitialized. We found Zone.getExtManager() and successfully retrieved a reference to a FirstExtension, which looks perfectly valid in the debugger, but when we try to cast the ISmartFoxExtension to FirstExtension (within SecondExtension), we get a ClassCastException (although the object is clearly the right FirstExtension).
This strongly suggests that each extension is being loaded by a separate classloader. We did manage to call the desired function entirely through reflection on the ISmartFoxExtension, but this seems rather inelegant, and isn't readily extensible for more complex interactions among our extensions.
Any additional pointers you can give us would be greatly appreciated. Thanks!~
Posted: 05 Nov 2007, 08:30
by Lapo
Hi Zood,
we don't seem to be able to reproduce the problem, additionally it's not entirely clear what you're trying to accomplish.
We setup a simple test scenario:
2 Zones ->
ZoneA and
ZoneB running 2 different extensions:
ExtA and
ExtB
We want to share data between the two by referencing a class called TestSingleton
-> Both Zones can access the singleton object without any problem
-> The object referenced is the same for both Zones (same object hash code)
-> Both Zones can access the same members in the singleton class
-> Both Zones can access the same static members in the singleton class
-> Additionally this mechanism is not affected by reloading any of the 2 extesions
The singleton class used for the test is the following:
Code: Select all
public class TestSingleton
{
public static int A_NUMBER = 100;
public static String A_STRING = "A String";
private static TestSingleton _instance;
public String text;
private TestSingleton()
{
text = "Hello Singleton!";
}
public static TestSingleton getInstance()
{
if (_instance == null)
_instance = new TestSingleton();
return _instance;
}
}
An even better implementation (thread safe) is available here ->
http://en.wikipedia.org/wiki/Singleton_pattern#Java
Posted: 07 Nov 2007, 23:25
by zood
Hi Lapo ~
Our situation is slightly different from the test you conducted. Our two java extensions are in the same zone. They are both referencing a third class, a singleton. The singleton class has some members which are not primitive types (HashMap, HashTable, etc.). For example, the HashTable changes on an ongoing basis and the extensions need to be able to check its values. When the second extension class gets the instance of the third class, the HashTable is empty, indicating to us that the class loading is segregated somehow.
Code: Select all
public class ThirdClass {
private static HashMap<String, ThirdClass> ZoneInstances = new HashMap<String, ThirdClass>(); // zonename->thirdclass instances (we intend to have one instance per zone)
private DbManager dbMan;
private Zone currZone;
private Hashtable<Integer, Integer> testHashTable;
public ThirdClass (Zone z) {
currZone = z;
dbMan = currZone.dbManager;
testHashTable = new Hashtable<Integer,Integer>();
for (Object u : z.getUserList()) {
User user = (User)u;
this.testHashTable.put(user.getUserId(), 0); // or some other test value
}
}
public static ThirdClass instance(Zone zone) {
String zoneName = zone.getName();
ThirdClass tc;
if (!ZoneInstances.keySet().contains(zoneName)) {
tc = new ThirdClass(zone);
ZoneInstances.put(zoneName, tc);
} else {
tc = ZoneInstances.get(zoneName);
}
return tc;
}
}
Our extensions are initialized like this:
Code: Select all
public class OurExtension2 extends AbstractExtension {
private ExtensionHelper xtHelper;
private Zone currZone;
private ThirdClass thirdClass;
public void init() {
xtHelper = ExtensionHelper.instance();
currZone = xtHelper.getZone(this.getOwnerZone());
thirdClass = namespace.ThirdClass.instance(currZone);
}
From here, the contents of thirdClass.testHashTable are not the same as thirdClass.testHashTable referenced the same way from OurExtension1.
I hope this explanation is helpful. Also, we are running patch 1.5.9
~ zood
Posted: 09 Nov 2007, 05:28
by Lapo
I don't know... honestly your code doesn't look very good.

You call a Singleton a class which is far away from the concept of a Singleton... plus I see concurrency problems in you instance() methods: if 2+ threads access that method you're in trouble.
Additionally this multi-Singleton should take care of keeping tracks multiple instances... which defeats the purpose of the Singleton object.
The Singleton pattern is outlined clearly here ->
http://en.wikipedia.org/wiki/Singleton_pattern#Java
One more question: is there a specific reason why you're using two Extensions in the same Zone instead of one? This is not a recommended practice and there's usually a better way of doing the same thing with just 1 extension
Posted: 20 Nov 2007, 13:14
by fluffy
Hi!
I have got the same problem with sharing objects between extensions.
I have one zone extension which is not dynamically loaded. This creates other rooms with dynamcial extensions.
The dynamically created ones can't access the the static attributes of either the other dynamic extensions nor of the not dynamic zone-extension which created it.
So there seems to be no way for me to exchange objects between them.
Any idea if there is a way around that?
Regards,
Fluffy
Posted: 20 Nov 2007, 19:15
by zood
Lapo wrote:I don't know... honestly your code doesn't look very good.

You call a Singleton a class which is far away from the concept of a Singleton... plus I see concurrency problems in you instance() methods: if 2+ threads access that method you're in trouble.
Additionally this multi-Singleton should take care of keeping tracks multiple instances... which defeats the purpose of the Singleton object.
Thanks for the feedback, but that's not why I am writing. The "multi-singleton" is a solution we tried in order to work with your server tying the database manager to the zone. For the purposes of investigating this bug, it is irrelevant however -- reduce the code to a standard singleton and the problem still exists.
Lapo wrote:One more question: is there a specific reason why you're using two Extensions in the same Zone instead of one? This is not a recommended practice and there's usually a better way of doing the same thing with just 1 extension
Actually, your documentation shows example application architecture with multiple zone extensions.
http://www.smartfoxserver.com/docs/inde ... ecture.htm. We followed this example and logically separated some of our functionality into different extensions and some of our own classes. It has become clear that this isn't ideal however, especially when it comes to handling internal events. It's not the end of the world, but I wish the documentation was more clear on this. Since it is not recommended to use multiple extensions in a zone it would be great if you would fix your documentation to be more accurate on this subject.
Now, due to these issues we will need to consolidate our extensions into one master extension which handles all requests and events, passing requests to other handler classes as necessary. I expect the classloader problem won't affect us after we rewrite our classes this way, but I do hope you'll try the test case again with a standard singleton and see what I was originally writing about.
Thanks,
zood
Posted: 21 Nov 2007, 15:22
by Lapo
Hi,
reduce the code to a standard singleton and the problem still exists.
Can you provide a working example that reproduces the problem with a singleton object.
We tested it, as mentioned in this post ->
http://forums.smartfoxserver.com/viewto ... =8092#8092
and it worked flawlessly.
Posted: 22 Nov 2007, 13:24
by fluffy
Is it possible, that dynamically loaded extensions can't access the static attributes of not dynamically loaded extensions?
Posted: 22 Nov 2007, 16:02
by Lapo
can you provide an example?
Posted: 07 Jul 2011, 06:23
by sanoysys
I am posting in such an old thread because I have run into the same problem.
@Lapo: if you want an example please have a look at this thread that I created:
http://forums.smartfoxserver.com/viewto ... 7768#47768