3
votes

I'm trying to create a release of my Phoenix application using Distillery and I've overridden the Poison Encoders for DateTime and NaiveDateTime to match the API requirements.

When I run mix release, my app compiles but I get an error during .boot generation.

Here is the stacktrace:

$> mix release
warning: variable "aliases" does not exist and is being expanded to "aliases()", please use parentheses to remove the ambiguity or change the variable name
  mix.exs:12

warning: variable "deps" does not exist and is being expanded to "deps()", please use parentheses to remove the ambiguity or change the variable name
  mix.exs:13

==> Assembling release..
==> Building release helios:1.0.0 using environment dev
==> One or more direct or transitive dependencies are missing from
    :applications or :included_applications, they will not be included
    in the release:

    :ex_admin
    :floki
    :geo
    :guardian
    :json_web_token
    :mogrify
    :phoenix_pubsub
    :scrivener_ecto
    :timex
    :timex_ecto

    This can cause your application to fail at runtime. If you are sure
    that this is not an issue, you may ignore this warning.

==> Release failed, during .boot generation:
        Duplicated modules:
        'Elixir.Poison.Encoder.NaiveDateTime' specified in poison and helios
        'Elixir.Poison.Encoder.Ecto.DateTime' specified in ecto and helios

Is there any way to override the Poison Encoders without running into this problem?

EDIT: Here are the encoders that I have:

  defimpl Poison.Encoder, for: Ecto.DateTime do
    def encode(datetime, options) do

      dt = datetime |> Ecto.DateTime.to_erl
      |> Timex.Timezone.convert("UTC")
      |> Timex.format("{ISO:Extended}")
      |> elem(1)

      <<?", dt::binary, ?">>
    end
  end

  defimpl Poison.Encoder, for: NaiveDateTime do
    def encode(datetime, options) do

      dt = datetime
      |> Timex.Timezone.convert("UTC")
      |> Timex.format("{ISO:Extended}")
      |> elem(1)

      <<?", dt::binary, ?">>
    end
  end
1

1 Answers

2
votes

You probably want to implement the protocol. The docs give this example:

defimpl Poison.Encoder, for: Person do
  def encode(%{name: name, age: age}, options) do
    Poison.Encoder.BitString.encode("#{name} (#{age})", options)
  end
end

If your unfamiliar with protocols, please post your custom encoders and we can help with the protocol.

EDIT:

So, after a lot of digging, it appears that Poison does not allow override base types. These already have an implementation in the package. So, when you override them in your project, your creating two versions of the beam files.

There is already this issue open against this issue.