how to correct the syntax? - erlang

I have configured ejabberd with mysql , but after installation I am not able to start ejabberd server due to a syntax error.
%% Modules enabled in all ejabberd virtual hosts.
%%
{modules,
[
%%{mod_adhoc_odbc, []},
%%{mod_announce_odbc, [{access, announce}]}, % requires mod_adhoc
%%{mod_caps_odbc, []},
%%{mod_configure_odbc,[]}, % requires mod_adhoc
%%{mod_admin_extra_odbc, []},
%%{mod_disco_odbc, []},
%%{mod_echo, [{host, "echo.localhost"}]},
%%{mod_irc_odbc, []},
%% NOTE that mod_http_fileserver must also be enabled in the
%% "request_handlers" clause of the "ejabberd_http" listener
%% configuration (see the "LISTENING PORTS" section above).
%%{mod_http_fileserver, [
%% {docroot, "/var/www"},
%% {accesslog, "/var/log/ejabberd/access.log"}
%% ]},
{mod_last_odbc, []},
%%{mod_muc_odbc, [
%%{host, "conference.#HOST#"},
{access, muc},
{access_create, muc},
{access_persistent, muc},
{access_admin, muc_admin},
{max_users, 500}
]},
{mod_muc_log_odbc,[]},
{mod_offline_odbc, [{access_max_user_messages, max_user_offline_messages}]},
{mod_privacy_odbc, []},
{mod_private_odbc, []},
{mod_offline_post_odbc, [
{auth_token, "offline_post_auth_token"},
{post_url, "http://localhost:5280/offline_post"}
]},
{mod_available_post_odbc, [
{auth_token, "mod_available_post"},
{post_url, "http://localhost:5280/available_post"}
]},
{mod_unavailable_post_odbc, [
{auth_token, "unavailable_post_auth_token"},
{post_url, "http://localhost:5280/unavailable_post"}
]},
{mod_proxy65_odbc, [
{access, local},
{shaper, c2s_shaper}
]},
{mod_pubsub_odbc, [ % requires mod_caps
{access_createnode, pubsub_createnode},
{pep_sendlast_offline, false},
{last_item_cache, false},
%%{plugins, ["default", "pep"]}
{plugins, ["flat", "hometree", "pep"]} % pep requires mod_caps
]},
{mod_register_odbc, [
%%
%% After successful registration, the user receives
%% a message with this subject and body.
%%
{welcome_message, {"Welcome!",
"Welcome to a Jabber service powered by Debian. "
"For information about Jabber visit "
"http://www.jabber.org"}},
%% Replace it with 'none' if you don't want to send such message:
%%{welcome_message, none},
%%
%% When a user registers, send a notification to
%% these Jabber accounts.
%%
%%{registration_watchers, ["admin1#example.org"]},
{access, register}
]},
{mod_roster_odbc, []},
{mod_service_log_odbc,[]},
{mod_shared_roster_odbc,[]},
{mod_stats_odbc, []},
{mod_time_odbc, []},
{mod_vcard_odbc, []},
{mod_version_odbc, []}
]}.
%%
And getting the error is,
=ERROR REPORT==== 2014-01-17 16:45:37 ===
E(<0.37.0>:ejabberd_config:187) : The following lines from your configuration file might be relevant to the error:
626:
627: {access, register}
628: ]},
629: {mod_roster_odbc, []},
630: {mod_service_log_odbc,[]},
631: {mod_shared_roster_odbc,[]},
632: {mod_stats_odbc, []},
633: {mod_time_odbc, []},
634: {mod_vcard_odbc, []},
635: {mod_version_odbc, []}
636: ]}.
637:
638: %%
639: %% Enable modules with custom options in a specific virtual host
=ERROR REPORT==== 2014-01-17 16:45:37 ===
E(<0.37.0>:ejabberd_config:106) : Problem loading ejabberd config file /etc/ejabberd/ejabberd.cfg approximately in the line 636: syntax error before: ']'
Please help me to fix this issue.Thanks in advanced.

Here is the problem:
%%{mod_muc_odbc, [
%%{host, "conference.#HOST#"},
{access, muc},
{access_create, muc},
{access_persistent, muc},
{access_admin, muc_admin},
{max_users, 500}
]},
You have commented the first line, but not the rest of the mod_muc_odbc config, causing unbalanced parentheses. Either uncomment the first line, or comment out the rest of them as well.

Related

Erlang simple release with cowboy 2.0.0 do not work

I'm using Erlang/OTP 20.0 and rebar3. When I start a new release that use cowboy 2.0.0, the release fail to start.
Here are the steps I do to build the project. What's wrong?
create the release project
$ rebar3 new release cowboy2
add cowboy package
{deps, [{cowboy, {git, "https://github.com/ninenines/cowboy.git", {tag, "2.0.0"}}}]}.
add a basic dispatcher
start(_StartType, _StartArgs) ->
Dispatch = cowboy_router:compile([
{'_', [
{"/", toppage_handler, []}
]}
]),
{ok, _} = cowboy:start_clear(http, [{port, 8080}], #{
env => #{dispatch => Dispatch}
}),
cowboy2_sup:start_link().
add handler. for the purpose of this example I use (https://raw.githubusercontent.com/ninenines/cowboy/master/examples/hello_world/src/toppage_handler.erl)
compile and release
$ rebar3 compile && rebar3 release
run the application
$ ./_build/default/rel/cowboy2/bin/cowboy2-0.1.0 console
The output
$ ./_build/default/rel/cowboy2/bin/cowboy2-0.1.0 console
Exec: /home/deimos/.asdf/installs/erlang/20.0/lib/erlang/erts-9.0/bin/erlexec
-boot /home/deimos/Dev/personal/cowboy2/_build/default/rel/cowboy2/releases/0.1.0/cowboy2
-mode embedded -boot_var ERTS_LIB_DIR /home/deimos/.asdf/installs/erlang/20.0/lib/erlang/lib
-config /home/deimos/Dev/personal/cowboy2/_build/default/rel/cowboy2/releases/0.1.0/sys.config
-args_file /home/deimos/Dev/personal/cowboy2/_build/default/rel/cowboy2/releases/0.1.0/vm.args
-pa -- console
Root: /home/deimos/Dev/personal/cowboy2/_build/default/rel/cowboy2
/home/deimos/Dev/personal/cowboy2/_build/default/rel/cowboy2
Erlang/OTP 20 [erts-9.0] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:30] [hipe] [kernel-poll:true]
=INFO REPORT==== 11-Oct-2017::21:00:52 ===
application: cowboy2
exited: {bad_return,
{{cowboy2_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy_router,compile,
[[{'_',[{"/",toppage_handler,[]}]}]],
[]},
{cowboy2_app,start,2,
[{file,
"/home/deimos/Dev/personal/cowboy2/_build/default/lib/cowboy2/src/cowboy2_app.erl"},
{line,18}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,273}]}]}}}}
type: permanent
(...)
Kernel pid terminated (application_controller)
({application_start_failure,cowboy2,{bad_return,{{cowboy2_app,start,[normal,[]]},{'EXIT',{undef,[{cowboy_router,compile,[[{'_',[{"/",toppage_handler,[]}]
Crash dump is being written to: erl_crash.dump...done
As #maze-le points out, the problem was that the cowboy application was not started. The solution is to add cowboy to the file apps/cowboy2/src/cowboy2.app.src also generated by the command $rebar3 new release cowboy2. I add the file for completeness.
apps/cowboy2/src/cowboy2.app.src
{application, cowboy2,
[{description, "An OTP application"},
{vsn, "0.1.0"},
{registered, []},
{mod, { cowboy2_app, []}},
{applications,
[kernel,
stdlib,
cowboy
]},
{env,[]},
{modules, []},
{maintainers, []},
{licenses, ["Apache 2.0"]},
{links, []}
]}.

Reltool copies files I don't want into release

I have the following .config file:
{sys, [
{lib_dirs, ["/Users/dan/learn_you_some_erlang/erlcount"]},
{rel, "erlcount", "1.0.0", [
kernel,
stdlib,
{ppool, permanent},
{erlcount, transient}
]},
{boot_rel, "erlcount"},
{erts, [
{mod_cond, derived},
{app_file, strip}]},
{profile, embedded}
]}.
and when I run reltool, I get a directory erts-9.1/doc containing a 400-page book about Erlang (among other things). How do I get rid of this?
I tried adding {excl_sys_filters, ["^doc"]} to the erts options, but I get an error
Illegal option: {excl_sys_filters,[\"^doc\"]}

Gen Server Error noproc

I get the following error when I try to run my program through shell using erlang.mk.
=INFO REPORT==== 5-May-2016::05:47:57 ===
application: rad
exited: {bad_return,
{{rad_app,start,[normal,[]]},
{'EXIT',
{noproc,{gen_server,call,[rad_config,{lookup,port}]}}}}}
type: permanent
Eshell V6.4 (abort with ^G)
(rad#127.0.0.1)1> {"Kernel pid terminated",application_controller,"{application_start_failure,rad,{bad_return,{{rad_app,start,[normal,[]]},{'EXIT',{noproc,{gen_server,call,[rad_config,{lookup,port}]}}}}}}"}
Kernel pid terminated (application_controller) ({application_start_failure,rad,{bad_return,{{rad_app,start,[normal,[]]},{'EXIT',{noproc,{gen_server,call,[radheart: Thu May 5 05:47:58 2016: _coErlang is crashing .. (waiting for crash dump file)nf
ig,{lookup,porheart: Thu May 5 05:47:58 2016: tWould reboot. Terminating.}
]}}}}}})
make: *** [run] Error 1
rad.app.src
{application, rad,
[
{description, "Awesome server written in Erlang"},
{vsn, "0.0.1"},
{registered, [rad_sup, rad_config]},
{modules, []},
{applications, [
kernel,
stdlib,
cowboy
]},
{mod, {rad_app, []}},
{env, []}
]}.
rad_config.erl
-module(rad_config).
-behaviour(gen_server).
%% API
-export([start_link/0]).
%% Gen Server Callbacks
-export([init/1 , handle_call/3 , handle_cast/2 , handle_info/2 , terminate/2 , code_change/3]).
-export([lookup/1]).
-define(SERVER, ?MODULE).
-record(state, {conf}).
start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
init([]) ->
{ok, Conf} = file:consult("config/rad.cfg"),
{ok, #state{conf = Conf}}.
handle_call({lookup, Tag} , _From , State) ->
Reply = case lists:keyfind(Tag, 1, State#state.conf) of
{Tag, Value} ->
Value;
false ->
{error, noinstance}
end,
{reply, Reply, State};
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
handle_cast(_Msg , State) ->
{noreply, State}.
handle_info(_Info , State) ->
{noreply, State}.
terminate(Reason , _State) ->
io:format("~n Server shutdown. Reason: ~s.~n", [Reason]),
ok.
code_change(_OldVsn , State , _Extra) ->
{ok, State}.
lookup(Tag) ->
gen_server:call(?SERVER, {lookup, Tag}).
rad_app.erl
-module(rad_app).
-behaviour(application).
-export([start/2]).
-export([stop/1]).
%% First we need to define and compile the dispatch list, a list of routes
%% that Cowboy will use to map requests to handler modules. Then we tell
%% Cowboy to listen for connections.
start(_Type, _Args) ->
Port = rad_config:lookup(port),
Dispatch = cowboy_router:compile([
{'_', [{"/", route_handler, []}]}
]),
{ok, _} = cowboy:start_http(rad_http_listener, 100,
[{port, Port}], [{env, [{dispatch, Dispatch}]}]),
%% Start the supervisor
rad_sup:start_link().
stop(_State) ->
ok.
rad_sup.erl
-module(rad_sup).
-behaviour(supervisor).
%% API
-export([start_link/0]).
%% Supervisor callbacks
-export([init/1, shutdown/0]).
-define(SERVER, ?MODULE).
%% Helper macro for declaring children of supervisor
-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}).
%% ===================================================================
%% API functions
%% ===================================================================
start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
%% ===================================================================
%% Supervisor callbacks
%% ===================================================================
init([]) ->
RestartStrategy = simple_one_for_one,
MaxRestarts = 10,
MaxSecondsBwRestarts = 5,
SupFlag = {RestartStrategy, MaxRestarts, MaxSecondsBwRestarts},
Processes = [?CHILD(rad_config, worker)],
{ok, {SupFlag, Processes}}.
%% Supervisor can be shutdown by calling exit(SupPid,shutdown)
%% or, if it's linked to its parent, by parent calling exit/1.
shutdown() ->
exit(whereis(?MODULE), shutdown).
So basically I've two questions related to the error that is thrown here:
Is this error thrown because my gen_server is not able to start?
The line in rad_config corresponding to file:consult/1, I want to ask from where does this function fetches the file as in the parameter that I've passed to it is config/rad.cfg but all the .erl files are stored in src folder. And both these folders src and config are at the same directory level. So, the parameter that I've passed to file:consult/1, is it correct? Although I've tried to pass the parameter as ../config/rad.cfg also. I still get the same error.
Please help me out. I'm new to Erlang and I'm trying to solve this error for quite some time. Btw, I using Erlang 17.5.
First, it seems like when you run rad_app.erl your rad_config server is not yet started. so when your get to this line:
Port = rad_config:lookup(port)
You are actually calling:
lookup(Tag) ->
gen_server:call(?SERVER, {lookup, Tag}).
And the gen_server is not started so you are getting a noproc error.
In addition to this, even if the server was started already, you are not able to make a gen_server:call to your self. The best way to handle a case that you want to send yourself an event is to open a new process using spawn and from inside the spawned process make the call.
Your should read more about gen_server and OTP.

Registering a global process in a startup script

I wrote a supervisor (shown below).
It only has one child process that I get from using locations:start_link/0. I expect it to start up a supervisor and register itself globally. That way, I can get to by using global:whereis_name/1.
When I start the supervisor through the shell it works as expected:
$ erl
1> locator_suo:start_link().
registering global supervisor
starting it....
supervisor <0.34.0>
{ok,<0.34.0>}
Then I can get to it by its global name, locator_sup:
2> global:whereis_name( locator_sup ).
<0.34.0>
But I want to start the system using a startup script, so I tried starting the system like so:
$ erl -s locator_sup start_link
registering global supervisor
starting it....
supervisor <0.32.0>
It seems that the init function for the supervisor is being called, but when I try to find the supervisor by its global name, I get undefined
1> global:whereis_name( locator_sup ).
undefined
So my question is, why does the supervisor process only get registered when I use start_link from the shell?
The supervisor module:
-module(locator_sup).
-behaviour(supervisor).
%% API
-export([start_link/0]).
%% Supervisor callbacks
-export([init/1]).
%% ===================================================================
%% API functions
%% ===================================================================
start_link() ->
io:format( "registering global supervisor\n" ),
{ok, E} = supervisor:start_link({global, ?MODULE}, ?MODULE, []),
io:format("supervisor ~p\n", [E] ),
{ok, E}.
%% ===================================================================
%% Supervisor callbacks
%% ===================================================================
% only going to start the gen_server that keeps track of locations
init(_) ->
io:format( "starting it....\n" ),
{ok, {{one_for_one, 1, 60},
[{locations, {locations, start_link, []},
permanent, brutal_kill, worker, [locations]}]}}.
One reason you may have that it is because you start your node not in distributed mode.
First of all add such params to see what happens during startup: erl -boot start_sasl.
Second add node name (it will automatically enable distributed mode) : ... -sname my_node
So the startup command will look like:
erl -boot start_sasl -sname my_node -s locator_sup start_link

Erlang releases with Rebar: What am I missing?

Thanks to much help here, I'm well on my way toward building my first Erlang release. No real code yet, but I want to understand how it's done. I've consulted and followed several web tutorials as well Martin et. al., but still seem to be missing something.
When I try to start my release I get:
lloyd#Reliance:~/Programming/Erlang/learn$ sh rel/learn/bin/learn start
[: 129: Node 'learn#127.0.0.1' not responding to pings.: unexpected operator
Under the project directory "learn" I have:
apps rebar rebar.config rel
In rebar.config, I have:
{cover_enabled, true}.
{sub_dirs, ["rel","apps/zzz", "apps/zzz_lib"]}.
In ...learn/apps, I have:
zzz zzz_lib
zzz and zzz_lib have all the right stuff in them so far as I can tell. From lean, I can clean, compile, and create docs.
In .../rel,I have:
files learn reltool.config
See reltool.config below.
I'm missing magic sauce, but what?
Many thanks,
LRP
{sys, [
{lib_dirs, []},
{rel, "learn", "1",
[
kernel,
stdlib,
sasl
]},
{rel, "start_clean", "",
[
kernel,
stdlib
]},
{boot_rel, "learn"},
{profile, embedded},
{excl_sys_filters, ["^bin/.*",
"^erts.*/bin/(dialyzer|typer)"]},
{app, sasl, [{incl_cond, include}]}
]}.
{target_dir, "learn"}.
{overlay, [
{mkdir, "log/sasl"},
{copy, "files/erl", "{{erts_vsn}}/bin/erl"},
{copy, "files/nodetool", "{{erts_vsn}}/bin/nodetool"},
{copy, "files/learn", "bin/learn"},
{copy, "files/app.config", "etc/app.config"},
{copy, "files/vm.args", "etc/vm.args"}
]}.
Looks like your retool.config file is missing some entries for the application you have written.
The first part should look something like this.
{sys, [
{lib_dirs, ["../apps"]}, <--- point to where your applications are
{rel, "learn", "1",
[
<your application here> <---- add your application(s) here
kernel,
stdlib,
sasl
]},
{rel, "start_clean", "",
[
kernel,
stdlib
]},
{boot_rel, "learn"},
{profile, embedded},
{excl_sys_filters, ["^bin/.*",
"^erts.*/bin/(dialyzer|typer)"]},
{app, <your application here>, [{incl_cond, include}]}, <-- and here
{app, sasl, [{incl_cond, include}]}
]}.
Here is a sample application from Erlang and OTP in Action that I packaged up using rebar.
https://github.com/tmcgilchrist/simple_cache
The general layout I follow is
simple_cache
|-> apps
| \-> simple_cache
| |-> src
| \-> ebin
|
|-> rebar.config
|-> rel
|-> files
|-> reltool.config
\-> simple_cache
Also rather that doing
sh rel/learn/bin/learn start
use
sh rel/learn/bin/learn console
and enter
application:which_applications().
Which should list a bunch of things plus your application.
eg
[{mysample_app,[],[]},
{sasl,"SASL CXC 138 11","2.1.10"},
{stdlib,"ERTS CXC 138 10","1.17.5"},
{kernel,"ERTS CXC 138 10","2.14.5"}]

Resources