[
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 thrifttest
namespace perl thrifttest
struct Pair {
1: optional string a,
2: optional string b
}
struct Result {
1: optional list<string> strList,
2: optional list<Pair> pairList
}
service Test {
Result listTest()
}
{code}
Here is my C++ code (server):
{code:title=Test_server.cpp|borderStyle=solid}
#include "gen-cpp/Test.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <iostream>
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 ::thrifttest;
class TestHandler : virtual public TestIf {
public:
TestHandler() {
// Your initialization goes here
}
void listTest(Result& _return) {
_return.strList.push_back("Test");
_return.strList.push_back("one level list");
cout << "strList size: " << _return.strList.size() << endl;
Pair pair;
pair.a = "Test";
pair.b = "two level list";
_return.pairList.push_back(pair);
cout << "pairList size: " << _return.pairList.size() << endl;
printf("call listTest\n");
}
};
int main(int argc, char **argv) {
int port = 9595;
shared_ptr<TestHandler> handler(new TestHandler());
shared_ptr<TProcessor> processor(new TestProcessor(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=Test_client.pl|borderStyle=solid}
#!/usr/bin/perl
use v5.12;
use warnings;
use autodie;
use utf8;
use Data::Dumper;
use lib 'gen-perl';
use thrifttest::Test;
use thrifttest::Constants;
use thrifttest::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 thrifttest::TestClient($protocol);
eval {
$transport->open();
my $result = $client->listTest;
say Dumper($result);
$transport->close();
};
say $@ if $@;
{code}
{code:title=C++ server output|borderStyle=solid}
strList size: 2
pairList size: 1
call listTest
{code}
{code:title=perl client output|borderStyle=solid}
$VAR1 = bless( {
'pairList' => undef,
'strList' => undef
}, 'thrifttest::Result' );
{code}
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}
{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.
> When use "optional' before a list, C++ server cannot return it correctly
> -------------------------------------------------------------------------
>
> 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 thrifttest
> namespace perl thrifttest
> struct Pair {
> 1: optional string a,
> 2: optional string b
> }
> struct Result {
> 1: optional list<string> strList,
> 2: optional list<Pair> pairList
> }
> service Test {
> Result listTest()
> }
> {code}
> Here is my C++ code (server):
> {code:title=Test_server.cpp|borderStyle=solid}
> #include "gen-cpp/Test.h"
> #include <thrift/protocol/TBinaryProtocol.h>
> #include <thrift/server/TSimpleServer.h>
> #include <thrift/transport/TServerSocket.h>
> #include <thrift/transport/TBufferTransports.h>
> #include <iostream>
> 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 ::thrifttest;
> class TestHandler : virtual public TestIf {
> public:
> TestHandler() {
> // Your initialization goes here
> }
> void listTest(Result& _return) {
> _return.strList.push_back("Test");
> _return.strList.push_back("one level list");
> cout << "strList size: " << _return.strList.size() << endl;
> Pair pair;
> pair.a = "Test";
> pair.b = "two level list";
> _return.pairList.push_back(pair);
> cout << "pairList size: " << _return.pairList.size() << endl;
> printf("call listTest\n");
> }
> };
> int main(int argc, char **argv) {
> int port = 9595;
> shared_ptr<TestHandler> handler(new TestHandler());
> shared_ptr<TProcessor> processor(new TestProcessor(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=Test_client.pl|borderStyle=solid}
> #!/usr/bin/perl
> use v5.12;
> use warnings;
> use autodie;
> use utf8;
> use Data::Dumper;
> use lib 'gen-perl';
> use thrifttest::Test;
> use thrifttest::Constants;
> use thrifttest::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 thrifttest::TestClient($protocol);
> eval {
> $transport->open();
> my $result = $client->listTest;
> say Dumper($result);
> $transport->close();
> };
> say $@ if $@;
> {code}
> {code:title=C++ server output|borderStyle=solid}
> strList size: 2
> pairList size: 1
> call listTest
> {code}
> {code:title=perl client output|borderStyle=solid}
> $VAR1 = bless( {
> 'pairList' => undef,
> 'strList' => undef
> }, 'thrifttest::Result' );
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)