[ 
https://issues.apache.org/jira/browse/THRIFT-3473?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

YU Chang updated THRIFT-3473:
-----------------------------
    Description: 
When a struct/object contains list, the thrift C++ server always return 
null/undef.

Here is my thrift file:
{code:title=WordAligner.thrift|borderStyle=solid}
namespace cpp WordAligner
namespace perl WordAligner

struct AlignParamter { 
    1: string srcLang,
    2: string tarLang,
    3: optional i32 nBestSize = 1,
}

struct SentenPair {
    1: string srcSenten,
    2: string tarSenten,
}

struct AlignPair {
    1: optional string srcWord,
    2: optional string tarWord,
}

struct AlignResult {
    1: i32 resultCode,
    2: string resultMessage,
    3: optional list<list<AlignPair>> nBestAlignPairList,
}

service WordAlignService {
    AlignResult alignOnePair(1: AlignParamter alignParamter, 2: SentenPair 
sentenPair),
    list<AlignResult> alignPairList(1: AlignParamter alignParamter, 2: 
list<SentenPair> sentenPairList)
}
{code}

Here is my C++ code (server):
{code:title=WordAlignerServer.cpp|borderStyle=solid}
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>

#include "thrift/WordAlignService.h"

#include <iostream>
#include <cstdlib>

using namespace std;
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;

using boost::shared_ptr;

using namespace  ::WordAligner;

class WordAlignServiceHandler : virtual public WordAlignServiceIf {
    public:
        WordAlignServiceHandler() {
        }

        void alignOnePair(AlignResult& _return, const AlignParamter& 
alignParamter, const SentenPair& sentenPair) {
            _return.resultCode = 0;
            _return.resultMessage = "Success";
            AlignPair alignPair;
            alignPair.srcWord = "中国";
            alignPair.tarWord = "china";
            vector<AlignPair> alignPairVec;
            alignPairVec.push_back(alignPair);
            _return.nBestAlignPairList.push_back(alignPairVec);
            cout << "nBestAlignPairList size: " << 
_return.nBestAlignPairList.size() << endl;
            cout << "src word: " << _return.nBestAlignPairList[0][0].srcWord << 
endl;
            cout << "tar word: " << _return.nBestAlignPairList[0][0].tarWord << 
endl;
        }

        void alignPairList(std::vector<AlignResult> & _return, const 
AlignParamter& alignParamter, const std::vector<SentenPair> & sentenPairList) {
            // Your implementation goes here
            printf("alignPairList\n");
        }

};

int main(int argc, char **argv) {
    int port = 9595;
    shared_ptr<WordAlignServiceHandler> handler(new WordAlignServiceHandler());
    shared_ptr<TProcessor> processor(new WordAlignServiceProcessor(handler));
    shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
    shared_ptr<TTransportFactory> transportFactory(new 
TBufferedTransportFactory());
    shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

    TSimpleServer server(processor, serverTransport, transportFactory, 
protocolFactory);
    server.serve();
    return 0;
}
{code}


Here is my perl code (client):
{code:title=WordAlignerClient.pl|borderStyle=solid}
#!/usr/bin/perl

use v5.12;
use warnings;
use autodie;

use utf8;
use Data::Dumper;

use lib 'gen-perl-wordalign';

use WordAligner::WordAlignService;
use WordAligner::Constants;
use WordAligner::Types;

use Thrift;
use Thrift::BinaryProtocol;
use Thrift::Socket;
use Thrift::BufferedTransport;


my $socket    = new Thrift::Socket('localhost', 9595);
my $transport = new Thrift::BufferedTransport($socket, 1024, 1024);
my $protocol  = new Thrift::BinaryProtocol($transport);
my $client    = new WordAligner::WordAlignServiceClient($protocol);

my $align_param = new WordAligner::AlignParamter;
$align_param->srcLang('zh-CN');
$align_param->tarLang('en');

my $src_senten = "中国 政府 高度 重视 经济 发展 。";
my $tar_senten = "china 's government attached great importance to economic 
development .";

my $senten_pair = new WordAligner::SentenPair;
$senten_pair->srcSenten($src_senten);
$senten_pair->tarSenten($tar_senten);

eval {
    $transport->open();
    my $result = $client->alignOnePair($align_param, $senten_pair);
    say Dumper($result);
    $transport->close();
};
say $@ if $@;
{code}

{code:title=C++ server output|borderStyle=solid}
nBestAlignPairList size: 1
src word: 中国
tar word: china
{code}

{code:title=perl client output|borderStyle=solid}
$VAR1 = bless( {
                 'resultMessage' => 'Success',
                 'resultCode' => 0,
                 'nBestAlignPairList' => undef
               }, 'WordAligner::AlignResult' );
{code}
For solving this problem, I have already tried to:

1) return just one level list, not list of list;
2) using C++ client to test;
3) upgrade thrift version from 0.9.1 to 0.9.3;

But nothing help, the return list is still empty.

  was:
When a struct/object contains list, the thrift C++ server always return 
null/undef.

Here is my thrift file:
{code:title=WordAligner.thrift|borderStyle=solid}
namespace cpp WordAligner
namespace perl WordAligner

struct AlignParamter { 
    1: string srcLang,
    2: string tarLang,
    3: optional i32 nBestSize = 1,
}

struct SentenPair {
    1: string srcSenten,
    2: string tarSenten,
}

struct AlignPair {
    1: optional string srcWord,
    2: optional string tarWord,
}

struct AlignResult {
    1: i32 resultCode,
    2: string resultMessage,
    3: optional list<list<AlignPair>> nBestAlignPairList,
}

service WordAlignService {
    AlignResult alignOnePair(1: AlignParamter alignParamter, 2: SentenPair 
sentenPair),
    list<AlignResult> alignPairList(1: AlignParamter alignParamter, 2: 
list<SentenPair> sentenPairList)
}
{code}

Here is my C++ code (server):
{code:title=WordAlignerServer.cpp|borderStyle=solid}
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>

#include "thrift/WordAlignService.h"

#include <iostream>
#include <cstdlib>

using namespace std;
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;

using boost::shared_ptr;

using namespace  ::WordAligner;

class WordAlignServiceHandler : virtual public WordAlignServiceIf {
    public:
        WordAlignServiceHandler() {
        }

        void alignOnePair(AlignResult& _return, const AlignParamter& 
alignParamter, const SentenPair& sentenPair) {
            _return.resultCode = 0;
            _return.resultMessage = "Success";
            AlignPair alignPair;
            alignPair.srcWord = "中国";
            alignPair.tarWord = "china";
            vector<AlignPair> alignPairVec;
            alignPairVec.push_back(alignPair);
            _return.nBestAlignPairList.push_back(alignPairVec);
            cout << "nBestAlignPairList size: " << 
_return.nBestAlignPairList.size() << endl;
            cout << "src word: " << _return.nBestAlignPairList[0][0].srcWord << 
endl;
            cout << "tar word: " << _return.nBestAlignPairList[0][0].tarWord << 
endl;
        }

        void alignPairList(std::vector<AlignResult> & _return, const 
AlignParamter& alignParamter, const std::vector<SentenPair> & sentenPairList) {
            // Your implementation goes here
            printf("alignPairList\n");
        }

};

int main(int argc, char **argv) {
    int port = 9595;
    shared_ptr<WordAlignServiceHandler> handler(new WordAlignServiceHandler());
    shared_ptr<TProcessor> processor(new WordAlignServiceProcessor(handler));
    shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
    shared_ptr<TTransportFactory> transportFactory(new 
TBufferedTransportFactory());
    shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

    TSimpleServer server(processor, serverTransport, transportFactory, 
protocolFactory);
    server.serve();
    return 0;
}
{code}


Here is my perl code (client):
{code:title=WordAlignerClient.pl|borderStyle=solid}
#!/usr/bin/perl

use v5.12;
use warnings;
use autodie;

use utf8;
use Data::Dumper;

use lib 'gen-perl-wordalign';

use WordAligner::WordAlignService;
use WordAligner::Constants;
use WordAligner::Types;

use Thrift;
use Thrift::BinaryProtocol;
use Thrift::Socket;
use Thrift::BufferedTransport;


my $socket    = new Thrift::Socket('localhost', 9595);
my $transport = new Thrift::BufferedTransport($socket, 1024, 1024);
my $protocol  = new Thrift::BinaryProtocol($transport);
my $client    = new WordAligner::WordAlignServiceClient($protocol);

my $align_param = new WordAligner::AlignParamter;
$align_param->srcLang('zh-CN');
$align_param->tarLang('en');

my $src_senten = "中国 政府 高度 重视 经济 发展 。";
my $tar_senten = "china 's government attached great importance to economic 
development .";

my $senten_pair = new WordAligner::SentenPair;
$senten_pair->srcSenten($src_senten);
$senten_pair->tarSenten($tar_senten);

eval {
    $transport->open();
    my $result = $client->alignOnePair($align_param, $senten_pair);
    say Dumper($result);
    $transport->close();
};
say $@ if $@;
{code}

C++ server output:
{code:title=C++ server output|borderStyle=solid}
nBestAlignPairList size: 1
src word: 中国
tar word: china
{code}
perl client output:
{code:title=perl client output|borderStyle=solid}
$VAR1 = bless( {
                 'resultMessage' => 'Success',
                 'resultCode' => 0,
                 'nBestAlignPairList' => undef
               }, 'WordAligner::AlignResult' );
{code}
For solving this problem, I have already tried to:

1) return just one level list, not list of list;
2) using C++ client to test;
3) upgrade thrift version from 0.9.1 to 0.9.3;

But nothing help, the return list is still empty.


> C++ server cannot correctly return a struct/object contains list
> ----------------------------------------------------------------
>
>                 Key: THRIFT-3473
>                 URL: https://issues.apache.org/jira/browse/THRIFT-3473
>             Project: Thrift
>          Issue Type: Bug
>          Components: C++ - Library
>    Affects Versions: 0.9.3
>         Environment: CentOS 7, GCC 4.8.3, Perl 5.16
>            Reporter: YU Chang
>
> When a struct/object contains list, the thrift C++ server always return 
> null/undef.
> Here is my thrift file:
> {code:title=WordAligner.thrift|borderStyle=solid}
> namespace cpp WordAligner
> namespace perl WordAligner
> struct AlignParamter { 
>     1: string srcLang,
>     2: string tarLang,
>     3: optional i32 nBestSize = 1,
> }
> struct SentenPair {
>     1: string srcSenten,
>     2: string tarSenten,
> }
> struct AlignPair {
>     1: optional string srcWord,
>     2: optional string tarWord,
> }
> struct AlignResult {
>     1: i32 resultCode,
>     2: string resultMessage,
>     3: optional list<list<AlignPair>> nBestAlignPairList,
> }
> service WordAlignService {
>     AlignResult alignOnePair(1: AlignParamter alignParamter, 2: SentenPair 
> sentenPair),
>     list<AlignResult> alignPairList(1: AlignParamter alignParamter, 2: 
> list<SentenPair> sentenPairList)
> }
> {code}
> Here is my C++ code (server):
> {code:title=WordAlignerServer.cpp|borderStyle=solid}
> #include <thrift/protocol/TBinaryProtocol.h>
> #include <thrift/server/TSimpleServer.h>
> #include <thrift/transport/TServerSocket.h>
> #include <thrift/transport/TBufferTransports.h>
> #include "thrift/WordAlignService.h"
> #include <iostream>
> #include <cstdlib>
> using namespace std;
> using namespace ::apache::thrift;
> using namespace ::apache::thrift::protocol;
> using namespace ::apache::thrift::transport;
> using namespace ::apache::thrift::server;
> using boost::shared_ptr;
> using namespace  ::WordAligner;
> class WordAlignServiceHandler : virtual public WordAlignServiceIf {
>     public:
>         WordAlignServiceHandler() {
>         }
>         void alignOnePair(AlignResult& _return, const AlignParamter& 
> alignParamter, const SentenPair& sentenPair) {
>             _return.resultCode = 0;
>             _return.resultMessage = "Success";
>             AlignPair alignPair;
>             alignPair.srcWord = "中国";
>             alignPair.tarWord = "china";
>             vector<AlignPair> alignPairVec;
>             alignPairVec.push_back(alignPair);
>             _return.nBestAlignPairList.push_back(alignPairVec);
>             cout << "nBestAlignPairList size: " << 
> _return.nBestAlignPairList.size() << endl;
>             cout << "src word: " << _return.nBestAlignPairList[0][0].srcWord 
> << endl;
>             cout << "tar word: " << _return.nBestAlignPairList[0][0].tarWord 
> << endl;
>         }
>         void alignPairList(std::vector<AlignResult> & _return, const 
> AlignParamter& alignParamter, const std::vector<SentenPair> & sentenPairList) 
> {
>             // Your implementation goes here
>             printf("alignPairList\n");
>         }
> };
> int main(int argc, char **argv) {
>     int port = 9595;
>     shared_ptr<WordAlignServiceHandler> handler(new 
> WordAlignServiceHandler());
>     shared_ptr<TProcessor> processor(new WordAlignServiceProcessor(handler));
>     shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
>     shared_ptr<TTransportFactory> transportFactory(new 
> TBufferedTransportFactory());
>     shared_ptr<TProtocolFactory> protocolFactory(new 
> TBinaryProtocolFactory());
>     TSimpleServer server(processor, serverTransport, transportFactory, 
> protocolFactory);
>     server.serve();
>     return 0;
> }
> {code}
> Here is my perl code (client):
> {code:title=WordAlignerClient.pl|borderStyle=solid}
> #!/usr/bin/perl
> use v5.12;
> use warnings;
> use autodie;
> use utf8;
> use Data::Dumper;
> use lib 'gen-perl-wordalign';
> use WordAligner::WordAlignService;
> use WordAligner::Constants;
> use WordAligner::Types;
> use Thrift;
> use Thrift::BinaryProtocol;
> use Thrift::Socket;
> use Thrift::BufferedTransport;
> my $socket    = new Thrift::Socket('localhost', 9595);
> my $transport = new Thrift::BufferedTransport($socket, 1024, 1024);
> my $protocol  = new Thrift::BinaryProtocol($transport);
> my $client    = new WordAligner::WordAlignServiceClient($protocol);
> my $align_param = new WordAligner::AlignParamter;
> $align_param->srcLang('zh-CN');
> $align_param->tarLang('en');
> my $src_senten = "中国 政府 高度 重视 经济 发展 。";
> my $tar_senten = "china 's government attached great importance to economic 
> development .";
> my $senten_pair = new WordAligner::SentenPair;
> $senten_pair->srcSenten($src_senten);
> $senten_pair->tarSenten($tar_senten);
> eval {
>     $transport->open();
>     my $result = $client->alignOnePair($align_param, $senten_pair);
>     say Dumper($result);
>     $transport->close();
> };
> say $@ if $@;
> {code}
> {code:title=C++ server output|borderStyle=solid}
> nBestAlignPairList size: 1
> src word: 中国
> tar word: china
> {code}
> {code:title=perl client output|borderStyle=solid}
> $VAR1 = bless( {
>                  'resultMessage' => 'Success',
>                  'resultCode' => 0,
>                  'nBestAlignPairList' => undef
>                }, 'WordAligner::AlignResult' );
> {code}
> For solving this problem, I have already tried to:
> 1) return just one level list, not list of list;
> 2) using C++ client to test;
> 3) upgrade thrift version from 0.9.1 to 0.9.3;
> But nothing help, the return list is still empty.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to