Announcement Announcement Module
No announcement yet.
Adding Client Bundle Packages to Service Bundles Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Adding Client Bundle Packages to Service Bundles

    I have structured my project so that there are services with no dependencies on which everything else depends. One such bundle is the resource_manager which contains a service that exposes a SessionFactory. The idea is that different client bundles need a datasource/transaction manager, and each client bundle has its own schema and Hibernate annotated POJO's.

    Problem is that the resource_manager doesn't import the client bundles, as this would be a dependency on a client. I would prefer that bundles that use the resource manager somehow inject their POJO package into the ClassLoader of the service it uses.

    Another case of the same issue is a XML parser service, which will be used to marshall and unmarshall various documents, but once again the POJO's for these documents are kept in another bundle. Basically this is the same use case.

    I see that there is a DynamicImport-Package option in the manifest file, but this imports all public packages. Is there any way to be more selective about which packages are added to a classloader? Or am I simply architecting this the wrong way?

  • #2
    The architecture you are considering does seem a bit broken. ;-)

    In general, a service needs a bundle which exports the service interface package and a bundle which publishes the service instance to the service registry. These bundles may be the same bundle or distinct bundles, but, if they are distinct, then the bundle that publishes the service must import the service interface package.

    Bundles which are clients of the service must import the service interface package and obtain the service instance from the service registry.

    Does this help? (If not, perhaps you could explain what you were hoping to achieve by loading a client class from within the service providing bundle's class loader.)


    • #3
      Solution is Eclipse-BuddyPolicy and Eclipse-RegisterBuddy

      Originally posted by Glyn Normington View Post
      Does this help? (If not, perhaps you could explain what you were hoping to achieve by loading a client class from within the service providing bundle's class loader.)
      Consider an XML parser - if you look at something like XStream it creates POJO instances based on alias definitions as it parses the XML. You can have a service which exposes an XStream instance, and you can have it reconfigured when a new bundle registers to handle new POJOs.

      Say you have two "domains" - invoices and stock control. The invoice bundle has invoice POJO objects, while the stock control has packing slip POJOs. Both bundles use the XStream Service to convert a XML representation of their objects into real POJO's. But in order for XStream to be able to create a instance of the POJO it must be able to see its class. The Parser doesn't know which XML it will get ahead of time - aka could be invoice or packing slip, so you can't have the parsers instantaited inside the client bundles.

      There must be no compile time dependency on the clients bundles. The XStream Bundle can parse any XML into any supplied POJO, but there has to be a way to supply the POJO classes. Anyhoo - I found the solution, although it is Equinox specific.

      I have found out that the Eclipse-BuddyPolicy and Eclipse-RegisterBuddy elements inside a Manifest really achieve what I'm looking for. Have not tried it yet though.


      • #4
        It sounds like one option here would be to make the bundle that contains your POJO classes a fragment of the XStream bundle. This will make them available to XStream's class loader.

        Another option might be to set the thread context class loader to the classloader for your POJO bundle before making the call the XStream. This option relies on XStream using the thread context class loader when it's attempting to instantiate types. I'm not too familiar with XStream so I don't know if this is the case but it may well be worth a try.

        In general I'd recommend trying both of these options, before resorting to using an Equinox-specific solution.


        • #5
          I agree with Andy. Equinox buddy class loading is acknowledged to be a hack and will only get you round certain problems, so finding a more general solution would be better if you can.