Way for module to call another module's API?

I am implementing an OpenMRS module which depends on another module. Is there a way to maybe call a service class method on the other module? (This is without using rest - i.e. directly using api calls).

Thanks.

There is some information and a link to an example here: https://wiki.openmrs.org/display/docs/Requiring+another+module+in+your+module

@pascal thanks for the effort. I have seen that turorial, and already done something like that. But usually, when you want to call a service class within your module, you do this:

MyServiceClass mServiceClass = Context.getService(MyServiceClass.class);

But when I want to call service class from my dependency module this way, I usually get an error. Attached is a log file of the error I get:

log.txt (12.0 KB)

From the logs it looks like it can’t find the service, which probably means there is a config problem. The way you are calling the service seems correct (based on this example in the idgenws module).

All I can recommend is to double check your pom.xml files and your config.xml file and make sure the required module is installed and started in your instance.

1 Like

@osagie_ehigiato make it a required module in the config.xml.

1 Like

You could vote for this ticket:

https://issues.openmrs.org/browse/TRUNK-3766

:burke:

2 Likes

@pascal, @ningosi, thanks for your suggestions. It actually worked after properly taking a look at my config file.

But another issue however arouse: the dependent module (module A) which has an admin link (where you can add/remove from item list) does not however work when another module gets the context. From the other module, you could access module A’s context, but from the admin page, which is inside module A itself, it then throws an service not found exception.

This behaviour reverses once you’re able to get it from module A - you won’t be able to get it from the other module where it is declared as a dependency. Can anyone suggest please? Thanks.

You could work around this by implementing an Observer Pattern in Module A. Instead of Module A needing to know anything about Module B, it can define an interface for injecting dependencies.

For example, in Module A:

interface AdminFunction {
  String getName();
  String getLink();
}

class AdminLister {
  public List<AdminFunction> adminFunctions;

  public Map<String, String> getLinks {
    Map<String, String> map = new HashMap<String, String>();
    for (af : adminFunctionList) {
      map.put(af.getLink(), af.getName());
    }
    return map;
  }
}

Module B depends on Module A, creates a list of admin functions and injects them into Module A’s AdminLister. Module A doesn’t need to know about Module B, it just needs it’s admin list populated.

2 Likes

I thought aware_of_module tag in config.xml makes it possible for modules to have weak dependencies, why would we introduce another tag to achieve more less the same thing?