2015-12-24 2 views
2

J'ai un serveur CORBA C++ qui implémente une interface lançant une exception définie par l'utilisateur.Orber (ORB Erlang) ne peut pas intercepter les exceptions définies par l'utilisateur lorsqu'il est lancé par TAO orb

Je peux facilement attraper l'exception spécifique lorsque le client et le serveur sont tous deux implémentés en C++ (testés en utilisant à la fois TAO orb et omniORB).

Mais lorsque j'appelle la même méthode d'Erlang (en utilisant orber), l'exception apparaît comme une exception générique et non comme une exception spécifique définie par l'utilisateur.

Pour tester cela, je viens d'utiliser simple IDL -

interface Messenger { 

    exception cirrus_error{ 
      short error_code; 
      string error_desc; 
    }; 

    boolean send_message(in string user_name, 
         in string subject, 
         inout string message) raises (cirrus_error); 
}; 

Si le serveur et le client sont en C++ - l'exception que je reçois est (pour le test je codé pour toujours jeter l'exception de l'utilisateur)

CORBA exception: cirrus_error (IDL:Messenger/cirrus_error:1.0) 

Mais lorsqu'il est invoqué par Erlang - je reçois -

** exception throw: {'EXCEPTION',{'UNKNOWN',[],1330446337,'COMPLETED_MAYBE'}} 
in function corba:raise/1 

Est-ce que je dois faire avec quelque chose de spécial Hile indiquant l'application Orber pour activer le bon comportement?

Edit - Voici comment j'appelle serveur de Erlang -

On invite Erlang, voici ce que je fais -

1> orber:jump_start(). 

2> O = corba:string_to_object(IORStr). 

3> 'Messenger':send_message(O, "s", "t", "f"). 
** exception throw: {'EXCEPTION',{'UNKNOWN',[],1330446337,'COMPLETED_MAYBE'}} 
    in function corba:raise/1 
+0

Comment appelez-vous le serveur depuis orber? –

+0

Mise à jour de cette question – spkhaira

Répondre

5

Vous devez vous enregistrer vos définitions IDL dans le référentiel d'interface Orber (IFR) avant d'appeler la méthode. Si votre fichier IDL est nommé messenger.idl, par exemple, la compilation crée oe_messenger.erl, qui fournit la fonction oe_register/0. L'appelant enregistre des informations sur votre exception définie par l'utilisateur dans l'IFR, qui décode CDR de Orber utilise pour être en mesure de décoder correctement les réponses contenant cette exception:

1> orber:jump_start(). 
... 
2> ic:gen(messenger). 
Erlang IDL compiler version 4.4 
ok 
3> make:all(). 
Recompile: Messenger 
Recompile: Messenger_cirrus_error 
Recompile: oe_messenger 
oe_messenger.erl:65: Warning: function oe_get_top_module/4 is unused 
oe_messenger.erl:91: Warning: function oe_destroy_if_empty/2 is unused 
up_to_date 
4> oe_messenger:oe_register(). 
ok 
5> M = corba:string_to_object(IORStr). 
... 
6> 'Messenger':send_message(M, "a", "b", "c"). 
** exception throw: {'EXCEPTION',{'Messenger_cirrus_error',"IDL:Messenger/cirrus_error:1.0", 
                  1234,"yep, an error"}} 
    in function corba:raise/1 (corba.erl, line 646) 

Mise à jour: La raison pour laquelle cette étape d'inscription IFR supplémentaire est nécessaire orber, bien que rarement nécessaire dans les ORB C++, est dû à une certaine flexibilité dans la spécification CORBA et aussi aux traditions de développement C++ ORB. Le original CORBA specification était en partie un compromis entre des camps linguistiques statiques et dynamiques. Le camp dynamique a insisté sur le fait que les IFR étaient dans la spécification comme ils en avaient besoin pour récupérer des informations de type à l'exécution (et clairement ils ont eu leur souhait, puisque ça faisait toujours partie de CORBA), mais le camp statique a supposé que l'IFR était inutile. les informations de type nécessaires pourraient être codées dans du code C/C++ généré à partir de définitions IDL. La communauté de développement ORB C++ suivait traditionnellement l'approche de génération de code et traitait l'IFR comme composant d'exécution facultatif, et les ORB C++ utilisés dans cette question récupéraient des informations sur l'exception cirrus_error définie par l'utilisateur des stubs et des squelettes générés. Mais les ORB écrits dans d'autres langages, tels que Smalltalk et Erlang, ont choisi d'utiliser l'IFR comme un composant normal du runtime ORB, et nécessitent donc l'enregistrement des informations de type dans l'IFR afin qu'il soit disponible pour l'exécution ORB. . Cependant, il serait certainement possible dans Erlang de générer des informations sur les exceptions définies par l'utilisateur dans des stubs/squelettes et de le récupérer à partir de là.

+0

Parfait, ça marche. Merci beaucoup, Steve. Pour ma compréhension, pourquoi n'ai-je pas besoin d'une telle étape lors de l'invocation d'un serveur C++ via un client C++? – spkhaira

+0

J'ai mis à jour ma réponse avec quelques détails à ce sujet. –