0

I have two Bundles

1. I18n Service (Internationalization)
2. Persistence Service (Database)

The thing is that the Bundle I18n uses the Database Services to store Texts and Messages in different languages. And the Persistence Service, also use I18m to store some Error Messages in different languages, so each Service depend on each other, but they should not work together, because they both offer dofferent types of Services.

My question, does any bosy knows a Pattern or Strictire that can help me solve this problem? I need to registers these Services and allow them to use each other.

In the Persistence Service Activator, I have the following dependency delcared:

    dependencyManager.add(createComponent()
            .setImplementation(PersistenceImpl.class)
            .add(createServiceDependency()
                    .setService(I18nService.class)
                    .setRequired(true))
    );

But the same cannot be done with the I18n, in that case none of them would start:

    dependencyManager.add(createComponent()
            .setImplementation(I18nImpl.class)
            .add(createServiceDependency()
                    .setService(PersistenceService.class)
                    .setRequired(true))
    );

Thank you.

Progman
  • 16,827
  • 6
  • 33
  • 48
Joe Almore
  • 4,036
  • 9
  • 52
  • 77
  • Does this answer your question? [Intra- and inter-bundle mutual dependencies in OSGi component models](https://stackoverflow.com/questions/10568236/intra-and-inter-bundle-mutual-dependencies-in-osgi-component-models) – Progman Dec 21 '21 at 18:33
  • Please [edit] your question to include a more detailed description on how your services are interactive to each other. It sounds weird that an "Internationalization", which does translations(?) wants to store data somewhere. Having it a dependency for a database service might not be correct in this case. Add some kind of diagram which services you have (or want to create), what they should do, how they interact between each other and why you design them in a way that you have cyclic dependencies. – Progman Dec 21 '21 at 19:17
  • @Progman Why do you say an "Internationalization" Bundle cannot do transactions to a database? Is there a better practice you know about? Please, feel free to share your thoughts. – Joe Almore Dec 21 '21 at 20:11
  • That's why I asked for clarifications of the services you have and the services you want to build. Also describe how the services should interact between each other. – Progman Dec 21 '21 at 20:15
  • @Progman It is simple, the `I18n` offers 2 basic Services: 1. Registration of String Resources and 2. Dispatch of String Resources. This all is stored in DB and loaded into memory at run-time. And there is the `Persistence Service` which offers DB Services for any other module that needs it (including the `I18n`) and also it registers its own Resource Strings (i.e. "Field ABC is expected to be a String", etc.). So, as you can see, both make use of each other. – Joe Almore Dec 21 '21 at 20:55
  • Please [edit] your question to include this information to your question, not as a comment. – Progman Dec 21 '21 at 20:57
  • Is it an option to remove the I18N dependency from the PersistanceService implementation, that it does not register any resource strings? A separate bundle, which only has a dependency on the I18N service, register the resource strings related to the PersistanceService. – Progman Dec 21 '21 at 21:19

1 Answers1

2

When you run into cycles almost invariably you're making things too complicated. In this case, it seems your low level components that should be used by higher level application code do too much 'application' level stuff. This makes them really hard to reuse and tends to create very complicated systems.

My solution would be to remove the translation from the database, the database should report its errors with an error code and maybe some parameters but the translation of the messages should be done on a much higher level, closer to the user. This would remove the need to even be aware of I18n.

This sounds better anyway since quite often on the level of database operations you're not really aware of the locale of the caller, trying to get it here universally requires ugly solutions like thread locals or polluting the call chain. The design where all your code needs to do translation would imho create quite a tangled web of unnecessary couplings.

My golden rule is to create reusable low level simple components that have very few dependencies each, and then wire them together in an application component. This makes the application component depend on everything but not of the other components have a large dependency fan out imho. Whenever I have a component that depends on a service that does not feel like its part of its essential function I feel it as a failure.

Peter Kriens
  • 15,196
  • 1
  • 37
  • 55