Loading...

Friday, June 25, 2010

Sample Thrift Program for Server in Java and Client in C++

Objective: To create a Java Server which prints ping on the console output each time a C++ Client connects to it and calls the function ping().


I use Facebook's Thrift for implementing this IPC.


First of all install Thrift:

To get a thrift tarball file go here and extract it. Before installing it, we need to resolve some dependencies which can be resolved by running the following command on an Ubuntu machine:


sudo apt-get install libboost-dev automake libtool flex bison pkg-config g++


To get a list of dependencies for other platforms, consult this:

Now to install thrift simply run the following commands from the thrift folder you just extracted:

./configure

make

sudo make install


This should be sufficient to install thrift on your machine. Later though I still got the following error while running the executables for which I had to copy my thrift library files from /usr/local/lib to /lib:

error while loading shared libraries: libthrift.so.0: cannot open shared object file: No such file or directory


If you still face some problems, try consulting this or leave a comment.


Now with Thrift setup on your machine, lets begin the real work!


First of all we write a sample.thrift file:

namespace cpp Test

namespace java Test

service Something {

i32 ping()

}


And then a C++ client:

Run: thrift --gen cpp sample.thrift and I get a couple of autogenerated files in gen-cpp folder. You can build them to get the Server.cpp file, but you have to write a C++ Client yourself. Ways to build your C++ Server and to write a sample C++ Client are clearly explained here.

My C++ Client thus looks like this:

#include "Something.h" // One of the autogenerated files

#include[<]transport/TSocket.h[>]

#include[<]transport.TBufferTransports.h[>]

#include[<]protocol.TBinaryProtocol.h[>]


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

using namespace Test;

int main(int argc, char **argv) {
boost::shared_ptr socket(new TSocket("localhost", 9090));
boost::shared_ptr transport(new TBufferedTransport(socket));
boost::shared_ptr protocol(new TBinaryProtocol(transport));

SomethingClient client(protocol);
transport->open();
client.ping();
transport->close();

return 0;
}


Your C++ Client is thus easily ready. You can check that its working fine by running the C++ Server and pinging it through the C++ Client. If this works, your C++ Client is ready.


Java Server

Now this for me was the most difficult part. When I run: thrift --gen java sample.thrift

I get a Something.java file in a gen-java folder.

Then I wrote a Server.java file myself by taking help from the Java Server given in thrift/tutorial/java/src. The exact Server.java is as follows:


import org.apache.thrift.TException;

import org.apache.thrift.protocol.TBinaryProtocol;

import org.apache.thrift.protocol.TProtocol;

import org.apache.thrift.server.TServer;

import org.apache.thrift.server.TSimpleServer;

import org.apache.thrift.transport.TServerSocket;

import org.apache.thrift.transport.TServerTransport;

import Test.*;

public class Server {

public static class SomethingHandler implements Something.Iface {

public SomethingHandler() {

}

public int ping() {

System.out.println("ping\n");

return 0;

}

}

public static void main(String [] args) {

try {

SomethingHandler handler = new SomethingHandler();

Something.Processor processor = new Something.Processor(handler);

TServerTransport serverTransport = new TServerSocket(9090);

TServer server = new TSimpleServer(processor, serverTransport);

// Use this for a multithreaded server

// server = new TThreadPoolServer(processor, serverTransport);


System.out.println("Starting the server...");

server.serve();


} catch (Exception x) {

x.printStackTrace();

}

System.out.println("done.");

}

}


I am using Eclipse IDE for developing my java project.

Now here are a lot of dependencies which need to be resolved.

First of all in the new Java Project, I had created, I added my Server.java to the default package and added the Something.java to a Test package.

Hence my package hierarchy now looked as:

ThriftServer(Project Name, You can give any)

-src

--default package

---Server.java

--Test package

---Something.java


Now you need to go to thrift/lib/java and have a look at the README file present to install the java libraries required.

just run the ant cmd from thrift/lib/java in your terminal and you will get a libthrift.jar file in the same folder.

Now to resolve the org.apache.* imports in your project, add this jar file to your project. You can have a look here to see how this is done.

After doing this, you will still be unable to resolve import errors for org.slf4j.Logger and LoggerFactory.

To resolve them, download slf4j-1.6.0.tar.gz from here.

Extract it and add the following two jar files to your project:

  • slf4j-api-1.6.0.jar
  • slf4j-simple-1.6.0.jar


Now your project should be completely-error free and ready to run.

Just right-click on Server.java and goto Run As-> Java Application

You should see "Starting the Server...." in the console indicating the server is running fine.

Now run your C++ client from a terminal and you should see ping on the console in Eclipse each time you run your client.

This indicates your Server-Client architecture is ready and fully functional.
Now you can use it to create some great stuff or atleast try and solve some good puzzles on the Facebook Thrift Puzzle Server!!

Enjoy!!


2 comments:

  1. Thank you dude!
    Helped a lot :-)

    ReplyDelete
  2. Thank you So much man.

    Will the above code be useful for Thrift server pool.

    ReplyDelete