Uploaded image for project: 'QuickFIX/J'
  1. QuickFIX/J
  2. QFJ-255

Remove dependencies between different FIX version jarfiles

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Default
    • Resolution: Fixed
    • Affects Version/s: 1.3.0
    • Fix Version/s: None
    • Component/s: Engine
    • Labels:
      None
    • Environment:
      windows / eclipse using FIX 4.3 initiator

      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).

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              francis.lalonde Francis Lalonde
            • Votes:
              2 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: