I made a hex package (Channels) that optionally depends on another one (AMQP). My implementation is based on Ecto's optional dependency on Mariaex.
In Channels' mix.exs:
defp deps do
[{:amqp, "0.1.4", optional: true}]
end
In the Channels' file that depends on AMQP:
if Code.ensure_loaded?(AMQP) do
defmodule Channels.Adapter.AMQP do
...
end
end
The application is starting properly on dev and test are also passing (including those that depend on AMQP mix test --include amqp_server
).
But when I try to use the package from another project some problems arise:
In my project I'm adding the following to my mix.exs file:
def application do
[applications: [:amqp, :channels, ...],
...]
end
defp deps do
[{:amqp, "0.1.4"},
{:channels, "~> 0.1.1"},
...]
end
When I try to start the application or run the tests I'm getting the following error:
=INFO REPORT==== 27-May-2016::10:28:35 ===
application: logger
exited: stopped
type: temporary
** (Mix) Could not start application channels: Channels.start(:normal, []) returned an error: shutdown: failed to start child: Channels.Monitor.Supervisor
** (EXIT) shutdown: failed to start child: :main
** (EXIT) an exception was raised:
** (UndefinedFunctionError) undefined function Channels.Adapter .AMQP.connect/1 (module Channels.Adapter.AMQP is not available)
Channels.Adapter.AMQP.connect([])
(channels) lib/channels/monitor.ex:42: Channels.Monitor.init/1
(stdlib) gen_server.erl:328: :gen_server.init_it/6
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
I'm adding AMQP as a dependency but it seems that Code.ensure_loaded?(AMQP)
is returning false and therefore Channels.Adapter.AMQP
is not being defined.
I've noticed that in the compilation process Channels is being compiled before AMQP:
...
==> channels
...
Generated channels app
==> rabbit_common (compile)
==> amqp_client (compile)
==> amqp
...
Generated amqp app
...
May this be the cause of my problem? If so, is there a way to decide the compilation order of my dependencies?
channels
are you using? I only see0.0.1
published on hex.pm and that doesn't includeamqp
as an optional dependency. See how optional dependencies are showing up for e.g. ecto. – Dogbert