I created a simple application in Java and C++ in CORBA, client-server app, take a look:
interface Task
{
string getThingToDo();
};
#include "Task.idl"
interface Employee
{
typedef sequence <Task> tasks;
string getLastname();
Task getTask(in short id);
};
#include "Employee.idl"
interface Work
{
Employee getEmployee(in short id);
};
TaskImpl.h and TaskImpl.cpp:
#include "Task.hh"
class TaskImpl : public POA_Task
{
private:
CORBA::String_var thingToDo;
public:
TaskImpl(const char* thingToDo);
char* getThingToDo();
};
#include "TaskImpl.h"
TaskImpl::TaskImpl(const char* thingToDo)
{
this->thingToDo = CORBA::string_dup(thingToDo);
}
char* TaskImpl::getThingToDo()
{
return CORBA::string_dup(this->thingToDo.in());
}
EmployeeImpl.h and EmployeeImpl.cpp:
#include "Employee.hh"
#include "TaskImpl.h"
class EmployeeImpl : public POA_Employee
{
private:
CORBA::String_var lastname;
int id;
Employee::tasks thingsToDo;
public:
EmployeeImpl(const char* lastname, int id);
char* getLastname();
Task_ptr getTask(::CORBA::Short id);
};
#include "EmployeeImpl.h"
EmployeeImpl::EmployeeImpl(const char* lastname, int id)
{
this->lastname = CORBA::string_dup(lastname);
this->id = id;
this->thingsToDo.length(3);
TaskImpl *t1, *t2, *t3;
t1 = new TaskImpl("Print all the documents");
t2 = new TaskImpl("Write the report");
t3 = new TaskImpl("Make backup");
this->thingsToDo[0] = t1->_this();
this->thingsToDo[1] = t2->_this();
this->thingsToDo[2] = t3->_this();
}
char* EmployeeImpl::getLastname()
{
return CORBA::string_dup(this->lastname.in());
}
Task_ptr EmployeeImpl::getTask(::CORBA::Short id)
{
return Task::_duplicate(this->thingsToDo[id-1]);
}
WorkImpl.h and WorkImpl.cpp:
#include "Work.hh"
#include <vector>
#include "EmployeeImpl.h"
using namespace std;
class WorkImpl : public POA_Work
{
private:
vector<EmployeeImpl> employees;
public:
WorkImpl();
Employee_ptr getEmployee(::CORBA::Short id);
};
#include "WorkImpl.h"
WorkImpl::WorkImpl()
{
EmployeeImpl ei1(CORBA::string_dup("Doe"), 1);
EmployeeImpl ei2(CORBA::string_dup("Smith"), 2);
EmployeeImpl ei3(CORBA::string_dup("Brown"), 3);
employees.push_back(ei1);
employees.push_back(ei2);
employees.push_back(ei3);
}
Employee_ptr WorkImpl::getEmployee(::CORBA::Short id)
{
return employees[id]._this();
}
Server.cpp:
#include "WorkImpl.h"
#include <omniORB4/CORBA.h>
#include <omniORB4/Naming.hh>
#include <iostream>
using std::cout;
using std::cerr;
int main(int argc, char **argv)
{
try
{
CORBA::ORB_ptr serverORB = CORBA::ORB_init(argc, argv);
CORBA::Object_var myPOAObj = serverORB->resolve_initial_references("RootPOA");
PortableServer::POA_var myPOA = PortableServer::POA::_narrow(myPOAObj);
PortableServer::POAManager_var myManager = myPOA->the_POAManager();
myManager->activate();
WorkImpl *work = new WorkImpl();
try
{
CORBA::Object_var nameServiceObj = serverORB->resolve_initial_references("NameService");
if(!CORBA::is_nil(nameServiceObj))
{
CosNaming::NamingContext_ptr namingContext = CosNaming::NamingContext::_narrow(nameServiceObj);
CosNaming::Name serviceName;
serviceName.length(1);
serviceName[0].id = CORBA::string_dup("WorkService");
namingContext->rebind(serviceName, work->_this());
cout << "WorkService is running ...\n";
}
}catch(CosNaming::NamingContext::NotFound&){
cerr << "CosNaming::NamingContext::NotFound\n";
}catch(CosNaming::NamingContext::InvalidName&){
cerr << "CosNaming::NamingContext::InvalidName\n";
}catch(CosNaming::NamingContext::CannotProceed&){
cerr << "CosNaming::NamingContext::CannotProceed\n";
}
serverORB->run();
delete work;
serverORB->destroy();
}catch(CORBA::SystemException&){
cerr << "Caught CORBA::SystemException\n";
}catch(CORBA::Exception&){
cerr << "Caught CORBA::Exception \n";
}catch(omniORB::fatalException &fe){
cerr << "Caught omniORB::fatalException\n";
cerr << "File: " << fe.file() << "\n";
cerr << "Line: " << fe.line() << "\n";
cerr << "Msg: " << fe.errmsg() << "\n";
}catch(...){
cerr << "Caught unknown exception\n";
}
return 0;
}
Client.java:
package OtherPackage;
import java.util.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import java.io.*;
public class Client
{
public static void main(String [] args)
{
try
{
org.omg.CORBA.ORB clientORB = org.omg.CORBA.ORB.init(args, null);
if (clientORB == null)
{
System.out.println("Problem while creating ORB");
System.exit(1);
}
org.omg.CORBA.Object objRef = clientORB.resolve_initial_references("NameService");
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
Work work = WorkHelper.narrow(ncRef.resolve_str("WorkService"));
Employee e = work.getEmployee((short)1);
System.out.println(e.getLastname());
Task t = e.getTask((short)1);
System.out.println(t.getThingToDo());
}catch(Exception e){ System.out.println(e.getMessage());
}
}
}
When I had EmployeeImpl.cpp like this:
#include "EmployeeImpl.h"
EmployeeImpl::EmployeeImpl(const char* lastname, int id)
{
this->lastname = CORBA::string_dup(lastname);
this->id = id;
this->thingsToDo.length(3);
TaskImpl *t1, *t2, *t3;
t1 = new TaskImpl("Print all the documents");
t2 = new TaskImpl("Write the report");
t3 = new TaskImpl("Make backup");
this->thingsToDo[0] = Task::_duplicate(t1->_this());
this->thingsToDo[1] = Task::_duplicate(t2->_this());
this->thingsToDo[2] = Task::_duplicate(t3->_this());
}
char* EmployeeImpl::getLastname()
{
return CORBA::string_dup(this->lastname.in());
}
Task_ptr EmployeeImpl::getTask(::CORBA::Short id)
{
return this->thingsToDo[id-1]._retn();
}
and I ran client fisrt time, I saw:
Smith
Print all the documents
which is correct. But when I ran my client for the second (and third, and so on ...) time, I saw:
Smith
null
where's the problem? I've been thinking about it a lot and wrote EmployeeImpl.cpp again:
#include "EmployeeImpl.h"
EmployeeImpl::EmployeeImpl(const char* lastname, int id)
{
this->lastname = CORBA::string_dup(lastname);
this->id = id;
this->thingsToDo.length(3);
TaskImpl *t1, *t2, *t3;
t1 = new TaskImpl("Print all the documents");
t2 = new TaskImpl("Write the report");
t3 = new TaskImpl("Make backup");
this->thingsToDo[0] = t1->_this();
this->thingsToDo[1] = t2->_this();
this->thingsToDo[2] = t3->_this();
}
char* EmployeeImpl::getLastname()
{
return CORBA::string_dup(this->lastname.in());
}
Task_ptr EmployeeImpl::getTask(::CORBA::Short id)
{
return Task::_duplicate(this->thingsToDo[id-1]);
}
and it all seems good now, every time I run client. But I'm not sure if it's good in CORBA way. Any suggestions?
Use those commands to compile and run server and client files (I use omniORB 4.1.6 and default-jdk package on Kubuntu 12.04):
Compile (and run) server files (just copy and paste):
g++ -c *.cpp -I$OMNIORB_HOME/include -I$OMNIORB_HOME/include/omniORB4
g++ -c *.cc -I$OMNIORB_HOME/include -I$OMNIORB_HOME/include/omniORB4
g++ -o Server Server.o EmployeeSK.o WorkSK.o WorkImpl.o EmployeeImpl.o TaskImpl.o TaskSK.o -L$OMNIORB_HOME/lib -lomnithread -lomniORB4
./Server -ORBInitRef NameService=corbaloc::localhost:2809/NameService
Compile (and run) client files (just copy and paste):
cd EmployeePackage; javac -cp .. *.java
cd OtherPackage; javac -cp .. *.java
cd java; java OtherPackage.Client -ORBInitRef NameService=corbaloc::localhost:2809/NameService
Here's my working code: http://www9.zippyshare.com/v/46287610/file.html
On second thought, I'm not sure my answer was really correct, and stackoverflow won't let me delete my answer once it has been accepted.