Contents
WARNING: This documentation refers to an outdated version of rosjava and is probably incorrect. Use at your own risk.
This page only applies to the pre-gradle rosjava build system. If you are trying to use rosjava after the gradle switch-over (Spring 2012), then please refer to the external rosjava documentation. |
Creating a ROS package that uses rosjava
ant is the main supported build system for rosjava-based projects. The rosjava package requires basic integration with rosmake to bootstrap your build process, but you will be able to use standard ant tasks and workflows once this is configured.
Please follow the instructions below to create and setup a new rosjava-based package.
Summary
Create a Makefile that includes rosjava.mk. This will setup rules when you run rosmake to bootstrap your package. rosmake expects a package to respond to the make command, so a Makefile is always required.
In your build.xml file Include the ros.properties property file and add ${ros.compile.classpath} to your build path
In your ROS manifest.xml file, add <depend/> tags for any messages or services your package needs (e.g. sensor_msgs).
Detail
Run roscreate-pkg to generate your new package and give it rosjava as a dependency, e.g.:
roscreate-pkg my_package rosjava
Replace the Makefile with the following snippet that includes rosjava.mk:
include $(shell rospack find rosjava_bootstrap)/rosjava.mk
Create a build.xml file that includes the ros.properties property file and also adds ros.compile.classpath to your build path. The ROS tools require you to declare a 'test' target, so we add an empty one below.
Here is a minimal example:
<?xml version="1.0" encoding="UTF-8"?> <project name="." default="default"> <property file="ros.properties" /> <path id="classpath"> <pathelement path="${ros.compile.classpath}" /> </path> <!-- required entry point --> <target name="test" /> </project>
Here is a more complete skeleton:
<?xml version="1.0" encoding="UTF-8"?> <project name="." default="default"> <property file="ros.properties" /> <property name="dist" location="dist" /> <property name="build" location="build" /> <property name="src" location="src" /> <path id="classpath"> <pathelement path="${ros.compile.classpath}" /> </path> <echo message="${toString:classpath}" /> <target name="default" depends="init, compile" /> <target name="init"> <fail unless="ros.compile.classpath" message="ros.properties is missing. Please type 'rosmake' first "/> <mkdir dir="${build}" /> <mkdir dir="${dist}" /> </target> <target name="compile" depends="init"> <javac destdir="${build}"> <classpath refid="classpath" /> <src path="${src}" /> </javac> </target> <target name="clean"> <delete dir="${build}" /> <delete dir="${dist}" /> </target> <!-- required entry point --> <target name="test" /> </project>
Generating msg/srv files in Java
The rosmake integration can automatically generate your message and service files that you need to use as long as your package correctly declares it dependencies.
Edit your manifest.xml in your package to add <depend /> tags for the message and service packages you use, e.g.
<package> ... <depend package="rosjava" /> <depend package="std_msgs" /> <depend package="sensor_msgs" /> ... </package>
The jar files will be built into $ROS_HOME/rosjava/lib. Continue reading to see how you can automatically get a classpath generated for these jar files.
NOTE: you currently cannot place .msg/.srv files in a rosjava-based package as the rosjava packages use ant instead of CMake and thus cannot invocate standard rosbuild macros.
See also rosjava/Overview/Messages#Using_Messages.
Building your ROS package
You must first use
rosmake my_pkg
in order to bootstrap and build your ROS package for the first time. This will:
- generate jar files for messages and services your package uses
generate the ros.properties file with ros.compile.classpath and other useful ant properties
After you have run rosmake my_pkg, you can use ant to do subsequent builds that are much quicker.
NOTE: Message/service jar files are generated into ~/.ros/rosjava/lib and are shared by all rosjava-based libraries (i.e. there is only one sensor_msgs.jar).
Exporting a jar file from your ROS package
If you have a jar file that want other ROS packages to be able to use, you can export them from your manifest.xml. In these exports, you should distinguish between jar files your project builds versus ones that it includes. Tools, such as the Eclipse integration, depend on this distinction.
Edit your manifest.xml to add a rule, like so:
<export> <rosjava-pathelement location="dist/my_package.jar" built="true" /> <rosjava-pathelement location="lib/dnsjava-2.1.1.jar" /> </export>
Although not required, you should also edit your manifest.xml to specify the source folder locations in your package for better integration with Eclipse and other tools:
<export> <rosjava-src location="src" /> ... </export>
NOTE: the built="true" for the my_package.jar, which indicates the build file for this package creates this jar file.
All locations are relative to the root of your package. Any package that depends on your package will get these jar files added to their classpath.
Behind the scenes
Behind the scenes, most of the magic happens in rosjava.mk:
- make ant-properties target: generates the ros.properties file, which currently contains ros.compile.classpath and ros.home. I will probably throw a couple of other common properties in there like ros.test_results_dir, ros.root, ros.log_dir, etc...
- make msg-deps target: first generates the .java files into ~/.ros/rosjava/gen, then compiles them into ~/.ros/rosjava/build, then creates jar files. This is all done in Python. Probably would be cleaner if I just generated a parameterized ant file instead.
make eclipse-project, make eclipse-classpath: auto-generates .project and .classpath files for Eclipse.
Other tidbits:
- make wipe-msgs deletes *all* auto-generated messages that your package uses.
- in the future, I will probably start including a version number where possible for the message jar files, e.g. sensor_msgs-1.4.2.jar. The version number will be pulled from the containing stack.
In order to build a package, you should first type 'rosmake' or 'make', but after that, you are free to just run bare 'ant'.