1
votes

I am using ejabberd version v2.1.11 on ubuntu 14.04. Compiled the exmpp modules and copied to /usr/lib/ejabberd/ebin/ location. The following is "my_module" code.

-module(my_module).

-author("John").

-include("/home/jk/src/exmpp/include/exmpp.hrl").
-include("/home/jk/src/exmpp/include/exmpp_client.hrl").

-include("ejabberd.hrl").

-export([start/2, stop/1]).

-export([on_filter_packet/1]).

-record(state, {}).

stop(_Host) -> ok.

start(Host, Opts) ->
    ?INFO_MSG("START MODULE LOADING", []),
    ejabberd_hooks:add(filter_packet, global, ?MODULE, on_filter_packet, 0).
    % gen_server:start_link(?MODULE, [Host], []).

on_filter_packet({From, To, Packet} = Input) ->
    Parser = exmpp_xml:start_parser(), % FAILS HERE
        Schedule = exmpp_xml:parse_final(Parser, "<schedule version='1.0' ></schedule>"),
        exmpp_xml:stop_parser(Parser),
        Input.

When ejabberd started the following error was thrown

running hook: {filter_packet,[]}

=ERROR REPORT==== 2015-10-13 22:12:24 ===
E(<0.9790.0>:ejabberd_hooks:335) : {badarg,
                                    [{ets,member,
                                      [exmpp_xml_engines_registry,expat],
                                      []},
                                     {exmpp_xml,is_engine_available,1,
                                      [{file,"./core/exmpp_xml.erl"},
                                       {line,520}]},
                                     {exmpp_xml,get_engine_from_options,1,
                                      [{file,"./core/exmpp_xml.erl"},
                                       {line,4007}]},
                                     {exmpp_xml,start_parser,1,
                                      [{file,"./core/exmpp_xml.erl"},
                                       {line,625}]},
                                     {my_module,on_filter_packet,1,
                                      [{file,"my_module.erl"},{line,52}]},
                                     {ejabberd_hooks,run_fold1,4,
                                      [{file,"ejabberd_hooks.erl"},
                                       {line,331}]},
                                     {ejabberd_router,do_route,3,
                                      [{file,"ejabberd_router.erl"},
                                       {line,315}]},
                                     {ejabberd_router,route,3,
                                      [{file,"ejabberd_router.erl"},
                                       {line,68}]}]}

How to use the exmpp module in ejabberd module ?

EDIT:

Add exmpp:start() in the start method and copy the c_src to the ejabberd lib and it works.

cp -rf exmpp/c_src/ /usr/lib/ejabberd/

I thought since all the exmpp dependencies are within its own modules copying the exmpp_*.beam files to the /usr/lib/ejabberd/ebin/ location where ejabberd modules have access is sufficent to be used in the ejabberd modules, but that is not the case.

Although the above solution works, what is the right way to install exmpp modules so that it can be used in the ejabberd modules.

1
Learn how erlang/OTP applications are built and releasedLol4t0

1 Answers

0
votes

Some modules need to be initialized before you can use them -- they might start a long-running process or create an ETS table or access some remote resource. Also, the module might depend on some other module and that module needs to be initialized before you can use it, but you wouldn't want to initialize the same module twice! An OTP "application" (see http://www.erlang.org/doc/design_principles/des_princ.html) encapsulates all this.

Typically, you'll have a foo.app file in your ebin directory, and this app file will describe what applications the runtime should initialize before running your application (and each one of those will have their own app file...).

Here's one of mine (this is actually a .app.src template-file which Rebar3 transforms into a proper .app file, but the dependency part is the same):

{application, mdw, [
    {description, "My Doohickey Whatsit"},
    {vsn, "1.0.0"},
    {id, "git"},
    {modules, []},
    {registered, []},
    {applications, [
                  kernel
                 ,stdlib
                 ,mnesia
                 ,ssl
                 ,inets
                 ,lager
                 ,erlcloud
                 ,worker_pool
                 ,wutils
                 ,recon
                 ]},
    {mod, {mdw_app, []}},
    {env, []}
]}.

Everything in applications is going to be initialized before my application. Then, the start/2 method in my mdw_app module will be called. ERTS will handle starting things in the correct order and not starting things twice.