Mix modules not loaded in release

I’m building/deploying an application using mix release. As part of my build, I have custom mix compiler modules that compile new modules. This works find when running the project locally.

When I run mix release, the modules are compiled but are not automatically loaded when running ./bin/my_app start from the releases folder. The beam files exists, and I can manually load them. Is there something I need to do to ensure these modules are automatically loaded?

It’s hard to tell from the problem description what the real cause is, but you always can do Code.ensure_loaded?/1 from your application start/2 or from any other appropriate place.

Interestingly, Code.ensure_loaded? only works if I first call l/1 on the module:

Code.ensure_loaded?(CustomModule)
false
l(CustomModule)
{:module, CustomModule}
Code.ensure_loaded?(CustomModule)
true

FWIW, this is running on FreeBSD 12.2 running Elixir 1.10.4. I don’t observe this problem from my development machine running macOS and Elixir 1.11.3.

Try Code.ensure_compiled/1 instead, it enforces a compilation if possible.

Releases start in embedded mode, which means only the modules listed in your .app files are loaded upfront and no more modules are loaded. So based on your description of custom compiler modules, I would check if that this may be the root cause. Run Application.spec(:your_app, :modules) and see if those modules are listed there. If they are not, then you need to make sure you generate said modules as a custom compiler (before the compile.app) or you generate them while Elixir is being compiled.

If they are there, then we would need more information on how to reproduce it.

1 Like

That was it! Learned something today about the default compilers.

Thank you so much @josevalim !