[Documentation] [TitleIndex] [WordIndex

Pure Java implementation

For a pure Java implementation, please see rosjava_core.

Package Details

Rosjava has been moved to a different repository and got released. Get the current version with the following command:

git clone https://github.com/gheorghelisca/rosjava_jni.git client_rosjava_jni

Client library API

As much as possible, each method provided by the rosjava client library simply wraps a call to a method by the same name in the roscpp C++ client library.

Thus, the best place to look for detailed documentation on individual rosjava methods is probably the roscpp documentation. Specifically, you can find information there about initialization and NodeHandle creation, NodeHandles, Publishers and Subscribers, and ServiceClients and ServiceServers.

Right now, the rosjava code is broken up into three packages.

Messages and Services

When a package (with a Java target) is compiled, a Java source files for each Message and Service of all dependencies is automatically generated and placed in the msg_gen/java and srv_gen/java folders respectively. Currently, a package's messages and services live in the ros.pkg.<package-name>.msg and ros.pkg.<package-name>.srv Java packages, and extend the java.communication.Message and java.communication.Service classes.

In addition to the interface defined in the java.communication.Message and java.communication.Service classes, each message will have one public member for each data element, with the name defined in the message declaration, and each Service will have inner class Message types named "Request" and "Response".

ROS Message data types are mapped to Java data types as follows:

Message type

Java type







byte, char, int8


uint8, int16


uint16, int32


uint32, int64, uint64









type[] for primitive types


ArrayList<type> for complex types



In particular, because Java lacks unsigned types, note that unsigned message types are currently mapped to Java's next bigger signed types. Since there is no next bigger type for long, uing64 and int64 are both mapped to long. Fixed size arrays are mapped to Java arrays. Variable size arrays over primitive types are also mapped to Java arrays to ensure that processing can be done efficiently. All other arrays are mapped to ArrayLists.

Message constants are mapped to final static members of a message class.

Finally, when a new Message subtype instance is created, all the fields are initialized to legal default values. In particular, primitives will be 0 (or 0.0), strings will be "", times and durations will have 0 secs and nsecs, variable arrays will be created with size 0 and fixed-length arrays will be created with the given size, and submessages will be recursively initialized by these same rules.

Building and running rosjava packages

Because rosjava currently wraps roscpp via JNI, it requires header files and shared libraries only provided with the Java Development Kit (JDK). You will need a copy of the JDK (version >= 5) installed to compile or run rosjava and any nodes that depend on it. client_rosjava contains a rosdep.yaml file so that rosdep should work as expected.

Moreover, in order to build, rosjava needs to know where to find your JDK installation. Per default, it uses the cmake FindJNI module. If this causes problems, you can set your JAVA_HOME environmental variable, e.g.,:

export JAVA_HOME=/usr/lib/jvm/java-6-sun/

Once you've installed the JDK and maybe set your JAVA_HOME, you should be ready to build and use existing rosjava nodes. To test this out, assuming you have already downloaded and build ROS, you should be able to:

roscd test_rosjava
make test

and see a bunch of printouts, followed by a successful test result. If things don't build or run properly, you probably have a bad version of Java installed or haven't set your JAVA_HOME correctly.

When running rosjava nodes, you should always use the provided scripts (which can be autogenerated, see the next section) rather than directly launching them via the "java" command. This is because two environmental variables need to be set for rosjava nodes to run correctly. First, rosjava nodes need to be able to dynamically link to the rosjava JNI library: LD_LIBRARY_PATH= <rosjava>/bin. Second, roscpp installs signal handlers that can interfere with the Java virtual machine's handlers, causing unexpected and hard-to-diagnose problems. To avoid this, you need to set LD_PRELOAD="path to libjsig.so", which is part of the JDK distribution.

Creating new rosjava packages

To create a new rosjava node, you need to take the following steps:


rospack_add_java_executable(<exec-name> <class-name>)

Currently, there is no support for more advanced features, such as setting JVM arguments. Patches are always welcome!


   1   import ros.*;
   2   import ros.communication.*;

   1   Ros ros = Ros.getInstance();
   2   ros.init("testNode");

   1   ros.logDebug("DEBUG");
   2   ros.logInfo("INFO");
   3   ros.logWarn("WARN");
   4   ros.logError("ERROR");
   5   ros.logFatal("FATAL");

   1   NodeHandle n = ros.createNodeHandle();

   1   n.setParam("test", 2);
   2   n.setParam("test2", 2.2);
   3   n.setParam("test3", "2.5");
   5   System.out.println(n.getIntParam("test"));
   6   System.out.println(n.getDoubleParam("test2"));
   7   System.out.println(n.getStringParam("test3"));

   1   Publisher<ros.pkg.std_msgs.msg.String> pub =
   2        n.advertise("/pub", new ros.pkg.std_msgs.msg.String(), 100);
   4   ros.pkg.std_msgs.msg.String m = new ros.pkg.rosjava_test.msg.String();
   5   m.data = "Hello, ROS";
   6   pub.publish(m);
   8   pub.shutdown();

   1   Subscriber.QueueingCallback<ros.pkg.std_msgs.msg.String> callback =
   2        new Subscriber.QueueingCallback<ros.pkg.std_msgs.msg.String>();
   3   Subscriber<ros.pkg.std_msgs.msg.String> sub =
   4        n.subscribe("/sub", new ros.pkg.std_msgs.msg.String(), callback, 10);
   6   n.spinOnce();
   8   while (!callback.isEmpty()) {
   9     System.out.println(callback.pop().data);
  10   }
  11   sub.shutdown();

(this could be made less ugly by importing the String message class, except that in this case it clashes with Java's built-in String type.)

   1   import ros.pkg.roscpp_tutorials.srv.TwoInts;
   3   ServiceClient<TwoInts.Request, TwoInts.Response, TwoInts> sc =
   4        n.serviceClient("add_two_ints" , new TwoInts(), false);
   6   TwoInts.Request rq = new TwoInts.Request();
   7   rq.a = 12;
   8   rq.b = 17;
  10   System.out.println("12 + 17 = " + sc.call(rq).sum);
  11   sc.shutdown();

   1   import ros.pkg.roscpp_tutorials.srv.TwoInts;
   3   ServiceServer.Callback<TwoInts.Request,TwoInts.Response> scb =
   4        new ServiceServer.Callback<TwoInts.Request,TwoInts.Response>() {
   5             public TwoInts.Response call(TwoInts.Request request) {
   6                  TwoInts.Response res = new TwoInts.Response();
   7                  res.sum = request.a + request.b;
   8                  return res;
   9             }
  10        };
  12   ServiceServer<TwoInts.Request,TwoInts.Response,TwoInts> srv =
  13        n.advertiseService("add_two_ints", new TwoInts(), scb);
  15   ros.spin();

   1   n.shutdown();

Known Issues

2024-07-13 14:37