Application Name: Platform
Version Number: 2.0.1
We have modified the legacyui to tailor our health center’s workflow, and we have followed the OpenMRS Documentation for creating the modules to be run with the modified legacyui.
We’ve made quite a few modules already and each runs fine on the modified legacyui. However, we’ve noticed that the more modules we add, the more OpenMRS slows down at startup. It seems to get stuck often on the “Refreshing Context” process.
For example, adding about three modules together with the modified legacyui takes about 3-8 minutes. Adding three more would take about 30 minutes or more. We’ve already tried increasing java’s memory allocation and heap space, to no avail.
Side note: We’re running OpenMRS on Ubuntu 16.04 LTS 64bit, on a laptop with 16GB ram and intel i5 core.
The total system startup time depends a lot on modules you install and their startup procedures. 30 minutes is very long.
It may be the case that it is only one module, which is adding to the startup time e.g. scanning through resources in all modules. You can experiment by disabling a module one at a time and testing the startup time.
It is also known that using annotations for services slows down the startup and declaring them in moduleApplicationContext.xml is preferred.
It’s best to run a profiler like YourKit to determine where the time is spent.
Thanks! I’ll give it a shot.
There are two things that I’m not clear about yet though:
You mentioned that the startup time depends on the modules’ startup procedures. Is there a way to modify a module’s startup procedure?
Also, in your example, you mentioned that scanning through resources in a module can slow down startup time. Is this about spring’s component scanning?
Module’s startup procedure includes what a module does in its Activator class, but also any code executed when instantiating and initializing spring beans, static code fragments, etc.
Regarding scanning through resources I didn’t mean springs’ component scanning. Some modules like Metadata Sharing do a search through the classpath to find classes implementing certain interfaces, see e.g. here. It is slow and can sometimes be deferred to be executed when its actually needed and not at startup. Just examine what’s get executed when starting up your modules to identify such cases.
Definitely look out for services that are configured via annotations rather than via the moduleApplicationContext as @raff suggests. This is an issue we’ve run into at times as well, and usually is caused by an annotated service method or some other inefficient wiring that can be quite difficult to debug, unfortunately. The suggestion of disabling each module separately to find the culprit is also a good one. Good luck!
Thanks for your suggestions! I’ll post an update as soon as we fix the problem.
You guys are right! Doing your suggestion, the startup time improved significantly.
What we did was, we removed all @Repository annotations and declared the beans in the moduleApplicationContext.xml. Also, instead of annotating classes with @Entity, we used hibernate mapping files instead.
The main culprit was the @Autowired annotation. “Wiring” through the moduleApplicationContext instead took quite a load off from the module startup.
Once again, thanks!