How to meld libraries together in a clever way?

Hi,

I’ve made a library that requires all game objects to implement SSObject (an interface which lets the objects be serialized/turned into bytes), but I want to use another library in my code: JBox2D (http://www.box2d.org/forum/viewtopic.php?f=5&t=36&start=30). Obviously JBox2D objects don’t implement SSObject, so I have to either

  1. Change their source code so that everything extends SSObject
  2. Extend every one of their classes with my own class and make that class implement SSObject.

I’ve done option 1 before because it’s very direct and easy to do. But obviously it sucks when a new release of jBox2D comes out because then I have to do it all over again :frowning: :’(

With extending every one of their classes, it will be a lot of work since I’ll probably have to over-ride many methods. JBox2D would create its own objects internally which would not be my extended objects that implement SSObject. For example the JBox2D World might create lots of Body’s in its constructor, but my SSWorld which extends World but implements SSObject would have to over-ride the World contructor and make SSBody’s, which extends Body but implements SSObject.

So both options are a pain in the neck. What do you guys do with such problems?? The SSObject class has just a few methods, basically writeObject(outStream) and readObject(inStream).

Thanks,
Keith

You may have reinvented the wheel :wink:
http://java.sun.com/j2se/1.3/docs/api/java/io/Externalizable.html

If you just want to store random objects, you can use XStream:
http://xstream.codehaus.org/

If you want to use your problem by implementation, you can use byte code manipulation and aspects:
http://asm.objectweb.org/

If you want to use your problem by design, just refacture out a model from your code, which merely holds the data and has means for reading and writing itself.

or JAXB it ships with JDK

Thanks for the pointers guys.

It doesn’t sound like there is a very elegant way to do it then. That byte code manipulation stuff sounds a bit messy.

But wouldn’t I still have to turn all of JBox2D’s objects into a model? This would probably harder than just extending all of the JBox2D classes.

About serialization, my implementation is much more specific - it doesn’t touch XML or regular serialization (and it’s super-fast). The main feature of my streams is that they allow objects to be deserialized and instead of producing a new object, they just replace the fields of an existing object. So when the server sends objects to the client, if the objects don’t exist on the client then they’re constructed, but if they’re already there (which is mostly the case) then the client objects are just over-written - so no garbage collection and all of the game object references remain.

Thanks for the replies cylab and bienator :slight_smile:

I dont know how your serialization framework is designed, but I guess it should be possible to just have your serializer monitor these “external” objects through reflection instead. You could pass your serializer an arbitrary object (and a optional list of variables it should monitor in there).

It surely would be less of a pain to maintain the object monitor list (and possibly a restricted list of vars for each object) than to modify or extend a whole framework…

[quote=“CommanderKeith,post:1,topic:31004”]
Hi! This quite a typical issue for serialization in Java2. Modifying source code does imply that further updates of the base package from the developer’s team will be hard to re-impl. By the way, why don’t you impl. thoroughly the whole stuff on your own ? Well, if you’re interested in one third-party class because of its specific features, one of the usual way to extend it, is to study HOW OBJECTS OF THIS CLASS GET INSTANCIED (args, context, etc.) and WHAT DO YOU NEED FROM THIS CLASS.
Hence, to make a class Serializable when it wasn’t used to be alike, state which contructor you use from this class and keep a notepad-copy of it. Right after, declare a new class extending the targeted class, and impl. the Serializable interface. within the writeObject() make a DEEP COPY of the member variables (which can be ONLY ACCESSED IN THE SAME PACKAGE, that is e.g. :


package java.geom; //!!!! this line must fit the exact path to the package you're extending !!!
import java.geom.Rectangle; class myNewRect extends Rectangle implements Serializable {}

) and write the objects to the objectoutputstream.
The readObject() method will then instanciate the super.class with default members, those are the members you have just serialized on output you can now recover throughout the in.readObject() and other objectinputstream methods. :smiley:

Actually, a more correct and smarter procedure is to implement the writeExternal() and readExternal() methods that dedicate their capabilities to external store/recover processes. I’m not used to those latter methods, but they’re known to be the ones to get what you want exactly AS YOU WANT. So, you may have a look to writeExternal() and readExternal() javadoc. :wink:

What about using revision control tools (CVS or SVN) to manage merging the changes made to JBox2D to the copy that you have added serialization too?

Also I believe byte-code manipulation is the cleanest approach, its what used in other persistence frameworks I have used in the past. However I have never used byte-code manipulation directly so take it with a grain of salt.

I think the simple answer is: never design an OOP app to “require” that all objects implement a particular interface. This is dooming yourself to failure from the start. Not because you are wrong to do so, but just because it’s anathema to OOP itself, which means that all the OOP libraries you ever try to join with will have problems like this. And even your own other OOP code (e.g. from other projects of yours) will have a hard time integrating.

  1. If I’m stuck with this problem already thanks to legacy code, I might try one of:
    a. externalize your need for the root object, as suggested by earlier responses, using reflection
    b. edit the foreign libs source code so that instead of instantiating objects, they use factories extensively. Gradually refactor and test until you find all the cases you missed
    c. wrap, at runtime, every object returned by the foreign library in a facade of your own that adheres to the contract you need (i.e. implementing your class)

This is what the adapter pattern is for (http://en.wikipedia.org/wiki/Adapter_pattern)

This is the same as blah’s point c.

Thanks for the input everyone! 8) Many of those techniques never even crossed my mind.

Adam and Don, I like the wwrapper class idea the best and it seems the most doable. The only thing is that just blindly using reflection to write every object’s fields won’t work because it’ll try and write everything like Swing components and other objects that you don’t want. So I’ll have to make an individual wrapper-class for most objects, which is basically the same as extending the class anyway.

What OOP method would you have used then Adam?

The JDK’s Serialization approach is the same as mine - all objects must implements a certain interface (JDK’s Serializable or my SSObject). But you still have to extend or wrap every class in the external project in a class that implements SSObject (and maybe over-ride some methods if some of the object’ refs shouldn’t be serialized). I would have thought that if there was a neat OOP approach to automatic serialization then the JDK would have used it.

Kieth,

In general I would not write my own serialization library because it is reinventing the wheel.

It’s difficult to give more than that as it is not obvious what all the requirements are.

You could have a look though at XStream, which serializes objects to XML. You can provide bespoke serialization via converters. It is very good.

thanks, D.

Well I can see the use; When writing networked games it can be cumbersome to write hundreds of message types and manually creating these to synchronize events & objects. (Java’s) serialization offers an elegant way of doing this automatically but isnt really suited for the purpose of games. I remember Keith made a custom version tailored at many updates per second, that offers more customizability and minimizes the object creation overhead. I think using XML for game network updates would be overkill (having to parse the XML structure for each network update)

[quote]The only thing is that just blindly using reflection to write every object’s fields won’t work because it’ll try and write everything like Swing components and other objects that you don’t want. So I’ll have to make an individual wrapper-class for most objects, which is basically the same as extending the class anyway.
[/quote]
You don’t have to do this serialization blindly on all fields. Like I mentioned earlier you could use blacklists (per class) to leave out certain fields for serialization. You could also make a preprocess tool that parses the libraries classes once and stores a list of fields per class. You could edit these lists to your likings (what fields should be included, excluded, their datatype etc)… So generating this list could be done fully automated, and updating & maintaining these lists for a new release of the lib should be pretty straightforward…

Thanks for the comments thijs. Interestingly, ewjordan, one of the two devs on JBox2D, has posted something on the same track as my little project. Maybe something cool could come of it?!

http://www.box2d.org/forum/viewtopic.php?f=3&t=143&p=774#p774