[QFJ-255] Remove dependencies between different FIX version jarfiles Created: 02/Oct/07  Updated: 01/Apr/14  Resolved: 01/Apr/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.0
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Francis Lalonde Assignee: Unassigned
Resolution: Fixed Votes: 2
Labels: None
Environment:

windows / eclipse using FIX 4.3 initiator


Attachments: File DefaultMessageFactory.java     File DefaultMessageFactory.java     File DefaultMessageFactory.java     File MessageCracker.java     XML File MessageCracker.xsl    

 Description   

Since QFJ v1.2, the QFJ lib consists of 5 jarfile. Programs depending on QFJ need to import all five files for it to work because of internal circular dependencies.

The submitted improvement breaks these dependencies and allows client application to import only the jarfiles of the FIX version that they use. For example, a client application conversing only with FIX 4.3 servers, could import only quickfixj-core.jarfile and quickfixj-msg-fix43.jar. The space savings could be useful in constrained remote deployment situations, and generally helps to reduce bloat.

The first code transforms tries to to keep the original MessageCracker pattern intact, without breaking existing code. MessageCrackers no longer extend each other from one version to the next; instead they all derive from the core MessageCracker, which uses introspection used to load the appropriate MessageCracker classes for each FIX version that needs to be cracked. The version-specific MessageCracker instances are stored in a cache.

crack() calls to the core (generic) MessageCracker method are routed to a modified crack() method in the appropriate version-specific MessageCracker, which takes the orignal instance as parameter in order to be able to callback the appropriate overloaded onMessage() method once the message class is determined. The core MessageCracker defines utility methods to enable introspection based onMessage() calls and handling of MessageType default cases.

Exisiting code using classes extending the versionned MessageCracker classes should see no impact, since the call pattern did not change at all in that case.

Existing classes deriving from the core (generic) MessageCracker will break on compilation if they were calling super() in their onMessage() methods, since the generic MessageCracker no longer derives from the fix44 MessageCracker, it no longer defines these methods. However, their onMessage methods will still be called correctly, although through Introspection rather than overloading.

Although not tested, it is quite probable that using introspection will somewhat reduce performance when using the generic MessageCracker, although not enough to show any impact in low to moderate message volumes. A second level per-instance method-cache could be added to reduce onMessage() method lookup time. If performance is an absolute concern, using version-specific MessageCrackers should be considered.

The second code transform is of a more benign nature and only affects the DefaultMessageFactory class. Like the message cracker, it uses dynamic classloading to identify which version-specific MessageFactories are available. Once loaded, create() methods are called directly, without Introspection.

Errors in dynamic classloading and introspection mechanisms result in RuntimeExceptions. An application expecting version specific behavior should break if the appropriate jarfile is not on the classpath. Generic handling of message without an onMessage() method will throw UnsupportedMessageType. Where needed, InvocationTargetExceptions are unwrapped and rethrown bare to preserve the application's ability to handle special cases (UnsupportedMessageType, FieldNotFound, IncorrectTagValue).



 Comments   
Comment by Francis Lalonde [ 02/Oct/07 ]

replaces quickfixj-1.3.0-src\quickfixj\core\src\main\java\quickfix\MessageCracker.java

Comment by Francis Lalonde [ 02/Oct/07 ]

replaces quickfixj-1.3.0-src\quickfixj\core\src\main\java\quickfix\codegen\MessageCracker.xsl

Comment by Francis Lalonde [ 02/Oct/07 ]

replaces quickfixj-1.3.0-src\quickfixj\core\src\main\java\quickfix\DefaultMessageFactory.java

Comment by Francis Lalonde [ 02/Oct/07 ]

This replaces the first uploaded version. Better loading performance, better error reporting.

Comment by Scott Harrington [ 28/Mar/08 ]

Francis: I found your contribution very useful.

There is a typo at DefaultMessageFactory.java:124, in that line you need to change BEGINSTRING_FIX43 to BEGINSTRING_FIX42.

Comment by Francis Lalonde [ 09/Apr/08 ]

Fixed the BEGINSTRING_FIX43- > 42 at line 124 issue reported by Scott (thanks).

Also, note that the proposed modifications do not pass the unit tests, as the harness expects some classes to be derived from others, which is the thing this fix specifically intends to break, while preserving full compatibility with existing client code. So either the test cases should be loosened (can we do that?), or this change be confined to an experimental branch.

Comment by Christoph John [ 22/Aug/12 ]

I'm not 100% sure, but wasn't this addressed in QFJ 1.5.1 and the cracker uses introspection since then?

Comment by Christoph John [ 01/Apr/14 ]

I think this has been solved in http://sourceforge.net/p/quickfixj/code/1005

Generated at Sat Nov 23 10:34:47 UTC 2024 using JIRA 7.5.2#75007-sha1:9f5725bb824792b3230a5d8716f0c13e296a3cae.