title: Check availability of optional dependencies in Elixir
body: <p>I made a hex package (<a href="https://hex.pm/packages/channels" rel="noreferrer">Channels</a>) that optionally depends on another one (<a href="https://hex.pm/packages/amqp" rel="noreferrer">AMQP</a>). My implementation is based on Ecto's optional dependency on Mariaex.</p>
  
  <p>In Channels' mix.exs:</p>
  
  <pre><code>defp deps do
    [{:amqp, "0.1.4", optional: true}]
  end
  </code></pre>
  
  <p>In the Channels' file that depends on AMQP:</p>
  
  <pre><code>if Code.ensure_loaded?(AMQP) do
  
    defmodule Channels.Adapter.AMQP do
      ...
    end
  
  end
  </code></pre>
  
  <p>The application is starting properly on dev and test are also passing (including those that depend on AMQP <code>mix test --include amqp_server</code>).</p>
  
  <p>But when I try to use the package from another project some problems arise:</p>
  
  <p>In my project I'm adding the following to my mix.exs file:</p>
  
  <pre><code>def application do
    [applications: [:amqp, :channels, ...],
     ...]
  end
  
  defp deps do
    [{:amqp, "0.1.4"},
     {:channels, "~&gt; 0.1.1"},
     ...]
  end
  </code></pre>
  
  <p>When I try to start the application or run the tests I'm getting the following error:</p>
  
  <pre><code>=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
  </code></pre>
  
  <p>I'm adding AMQP as a dependency but it seems that <code>Code.ensure_loaded?(AMQP)</code> is returning false and therefore <code>Channels.Adapter.AMQP</code> is not being defined.</p>
  
  <p>I've noticed that in the compilation process Channels is being compiled before AMQP:</p>
  
  <pre><code>...
  ==&gt; channels
  ...
  Generated channels app
  ==&gt; rabbit_common (compile)
  ==&gt; amqp_client (compile)
  ==&gt; amqp
  ...
  Generated amqp app
  ...
  </code></pre>
  
  <p>May this be the cause of my problem? If so, is there a way to decide the compilation order of my dependencies?</p>