Orber(Erlang ORB)在被TAO ORB抛出时无法捕获用户定义的异常



我有一个C++CORBA服务器,它实现了一个抛出用户定义异常的接口。

当客户端和服务器都在C++中实现时(使用TAO-orb和omniORB进行测试),我很容易捕捉到特定的异常。

但是,当我从Erlang(使用orber)调用相同的方法时,异常显示为一般异常,而不是特定的用户定义异常。

为了测试这一点,我只使用了一个简单的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);
};

如果服务器和客户端都在C++中,那么我得到的异常是(为了测试,我将其编码为总是抛出用户异常)

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

但是当通过Erlang调用时-我得到-

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

在陈述Orber应用程序时,我是否需要做一些特别的事情来实现正确的行为?

编辑-这是我如何从erlang调用服务器-

在Erlang提示下,这就是我所做的-

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 

在调用方法之前,您需要将IDL定义注册到orber接口存储库(IFR)中。例如,如果IDL文件名为messenger.idl,则编译它将创建oe_messenger.erl,后者提供oe_register/0函数。调用它会将有关用户定义异常的信息注册到IFR中,orber的CDR解码使用IFR来正确解码包含该异常的任何响应:

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)

更新:orber中需要这个额外的IFR注册步骤,而在C++ORB中很少需要,这是由于CORBA规范中的一些灵活性,以及C++ORB的开发传统。最初的CORBA规范在一定程度上是静态和动态语言阵营之间的折衷。动态阵营坚持IFR在规范中,因为他们需要它来在运行时检索类型信息(很明显,他们如愿以偿,因为它一直是CORBA的一部分),但静态阵营认为IFR是不必要的,因为所有必要的类型信息都可以编码在由IDL定义生成的C/C++代码中。C++ORB开发社区传统上遵循代码生成方法,并将IFR视为可选的运行时组件,本问题中使用的C++ORB从生成的存根和骨架中检索有关用户定义的cirrus_error异常的信息。但是,用其他语言编写的ORB,如Smalltalk和Erlang,已经选择将IFR用作ORB运行时的正常组件,因此它们需要将类型信息注册到IFR中,以便ORB运行库可以使用它。不过,在Erlang中,将有关用户定义异常的信息生成到存根/骨架中,并让运行时从中检索这些信息肯定是可能的。

相关内容

  • 没有找到相关文章

最新更新