Application isn't started

I am doing the code gnome course (which the application is a Hangman) and I tried to start a module with Application which uses an Agent and is complainig this:

iex(1)> Dictionary.random_word
** (exit) exited in: GenServer.call(Dictionary.Runtime.Server, {:get, &Dictionary.Impl.WordList.random_word/1}, 5000)
    ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
    (elixir 1.13.0) lib/gen_server.ex:1019: GenServer.call/3

I tried to start with the atom mod: and start_module: on the file mix.exs

def application do
    [
      # mod: { Dictionary.Runtime.Application, [] },
      start_module: { Dictionary.Runtime.Application, [] },
      extra_applications: [:logger]
    ]
  end

application.ex:

defmodule Dictionary.Runtime.Application do

  use Application

  def start(_type, _args) do
    Dictionary.Runtime.Server.start_link()
  end
end

server.ex :

defmodule Dictionary.Runtime.Server do

  @type t :: pid()

  @me __MODULE__

  alias Dictionary.Impl.WordList

  def start_link do
    Agent.start_link(&WordList.word_list/0, name: @me)
  end

  def random_word() do
    Agent.get(@me, &WordList.random_word/1)
  end
end

Hi,
try to put

iex(1)> Application.ensure_started(:dictionary_runtime) #or :dictionary, the name of your application
iex(2)> Dictionary.random_word

I think you are not starting the application before calling it.
If you call

iex -S mix

Mix starts the application that you are developing for you:)

Hello @SirWerto,
this is not what I want to do.
If I try to run:

iex(1)> Dictionary.Runtime.Server.start_link
{:ok, #PID<0.154.0>}
iex(2)> Dictionary.random_word
"academics"

it work’s for me. But I want to start like Application.

I tried your code:

iex(1)> Application.ensure_started(:dictionary_runtime)
{:error, {'no such file or directory', 'dictionary_runtime.app'}}
iex(2)> Application.ensure_started(:dictionary)
:ok
iex(3)> Dictionary.random_word
** (exit) exited in: GenServer.call(Dictionary.Runtime.Server, {:get, &Dictionary.Impl.WordList.random_word/1}, 5000)
    ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
    (elixir 1.13.0) lib/gen_server.ex:1019: GenServer.call/3

but complains the same.
Thank you for reply!

Okey, you need to start a supervisor in you application start callback, here is the elixir tutorial about that. And start your server from the supervisor.

I am not totally sure if is possible to use an application without spawning a top level supervisor, but the normal behaviour is to spawn a top level supervisor an then start the other processs of your application from there.

You can either use mix, as @SirWerto have suggested, or use a OTP release, as documented here

You need to tell us what exactly do you want.

Hi! Here is a list of changes that would make it work, with a few references to documentation. Hope it helps to have this running at least.

Please use mod: which is the option documented here: Application — Elixir v1.13.4


Here you’re missing the use Agent line, so this module actually behaves like an Agent module. See: Agent — Elixir v1.12.3

Also, the start_link function should accept one argument. You may change it to:

  def start_link(_initial_value) do
    Agent.start_link(&WordList.word_list/0, name: @me)
  end

Finally, you need to adjust here to pass an initial value to Dictionary.Runtime.Server.start_link(...).


With these changes the app should start when doing mix -S iex. The Dictionary.random_word invocation should just work, without manually start the app from the iex session.

Good luck!

Hello this is not a release.

Hello @jmbejar.
I put the use Agent but the same error complains and this don’t need an initial value on the Server.start_link because this is reading a file, so the initial value is a list of words.

You will also need to start a Supervisor on the start/2 callback instead of directly starting your Agent server, as per documentation:

The start/2 callback has to spawn and link a supervisor and return {:ok, pid} or {:ok, pid, state} , where pid is the PID of the supervisor, and state is an optional application state. args is the second element of the tuple given to the :mod option.

eg:

defmodule Dictionary.Runtime.Application do

  use Application

  def start(_type, _args) do
    children = [{Dictionary.Runtime.Server, []}]
    Supervisor.start_link(children, strategy: :one_for_one)
  end
end

And I think you will need to provide a start_link/1

or you could implement your own child_spec instead of relying on the convention of {mod, args} tuple as presented on the variable children

I understand that you may not need to use the initial value argument, but it is a requirement to implement start_link/1 in your Agent module, otherwise, it won’t work. You can simply ignore that argument but it has to be in the function definition.

I solved the problem.
I was putting the mod: on a different app.
Rather than to put on the :dictionary app hahaha.
Thank you all guys for the help.

2 Likes