sharing runtime objects between java server extensions

Post here your questions about Actionscript and Java server side extensions development.

Moderators: Lapo, Bax

Post Reply
zood
Posts: 21
Joined: 02 Jul 2007, 17:29
Location: San Francisco
Contact:

sharing runtime objects between java server extensions

Post 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
User avatar
Lapo
Site Admin
Posts: 23438
Joined: 21 Mar 2005, 09:50
Location: Italy

Post 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.
Lapo
--
gotoAndPlay()
...addicted to flash games
zood
Posts: 21
Joined: 02 Jul 2007, 17:29
Location: San Francisco
Contact:

Post 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!~
User avatar
Lapo
Site Admin
Posts: 23438
Joined: 21 Mar 2005, 09:50
Location: Italy

Post 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
Lapo
--
gotoAndPlay()
...addicted to flash games
zood
Posts: 21
Joined: 02 Jul 2007, 17:29
Location: San Francisco
Contact:

Post 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
User avatar
Lapo
Site Admin
Posts: 23438
Joined: 21 Mar 2005, 09:50
Location: Italy

Post 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
Lapo
--
gotoAndPlay()
...addicted to flash games
fluffy
Posts: 20
Joined: 26 Jun 2007, 18:26

Post 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
zood
Posts: 21
Joined: 02 Jul 2007, 17:29
Location: San Francisco
Contact:

Post 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
User avatar
Lapo
Site Admin
Posts: 23438
Joined: 21 Mar 2005, 09:50
Location: Italy

Post 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.
Lapo
--
gotoAndPlay()
...addicted to flash games
fluffy
Posts: 20
Joined: 26 Jun 2007, 18:26

Post by fluffy »

Is it possible, that dynamically loaded extensions can't access the static attributes of not dynamically loaded extensions?
User avatar
Lapo
Site Admin
Posts: 23438
Joined: 21 Mar 2005, 09:50
Location: Italy

Post by Lapo »

can you provide an example?
Lapo
--
gotoAndPlay()
...addicted to flash games
sanoysys
Posts: 10
Joined: 24 Mar 2009, 08:38
Location: Bengaluru, India
Contact:

Post 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
Post Reply