From 36e0426b7ada49d1a9fff8438b4636bd96366a29 Mon Sep 17 00:00:00 2001
From: Mickael Gaillard
Date: Sun, 28 Aug 2016 19:59:23 +0200
Subject: [PATCH 1/6] Add Javadoc
---
rcljava/CMakeLists.txt | 6 +
.../main/java/org/ros2/rcljava/Consumer.java | 19 ++
.../src/main/java/org/ros2/rcljava/Log.java | 36 +++
.../src/main/java/org/ros2/rcljava/Node.java | 90 +++++--
.../main/java/org/ros2/rcljava/Publisher.java | 90 ++++++-
.../java/org/ros2/rcljava/QoSProfile.java | 30 +++
.../main/java/org/ros2/rcljava/RCLJava.java | 233 ++++++++++++------
.../java/org/ros2/rcljava/Subscription.java | 74 +++++-
...mplementationAlreadyImportedException.java | 34 +++
.../InvalidRCLJAVAImplementation.java | 34 +++
.../NoImplementationAvailableException.java | 36 +++
.../exception/NotInitializedException.java | 33 +++
12 files changed, 606 insertions(+), 109 deletions(-)
create mode 100644 rcljava/src/main/java/org/ros2/rcljava/Log.java
create mode 100644 rcljava/src/main/java/org/ros2/rcljava/QoSProfile.java
create mode 100644 rcljava/src/main/java/org/ros2/rcljava/exception/ImplementationAlreadyImportedException.java
create mode 100644 rcljava/src/main/java/org/ros2/rcljava/exception/InvalidRCLJAVAImplementation.java
create mode 100644 rcljava/src/main/java/org/ros2/rcljava/exception/NoImplementationAvailableException.java
create mode 100644 rcljava/src/main/java/org/ros2/rcljava/exception/NotInitializedException.java
diff --git a/rcljava/CMakeLists.txt b/rcljava/CMakeLists.txt
index 991af41a..a9920e1d 100644
--- a/rcljava/CMakeLists.txt
+++ b/rcljava/CMakeLists.txt
@@ -87,6 +87,12 @@ set(${PROJECT_NAME}_sources
"src/main/java/org/ros2/rcljava/Publisher.java"
"src/main/java/org/ros2/rcljava/Subscription.java"
"src/main/java/org/ros2/rcljava/Consumer.java"
+ "src/main/java/org/ros2/rcljava/Log.java"
+ "src/main/java/org/ros2/rcljava/QoSProfile.java"
+ "src/main/java/org/ros2/rcljava/exception/ImplementationAlreadyImportedException.java"
+ "src/main/java/org/ros2/rcljava/exception/InvalidRCLJAVAImplementation.java"
+ "src/main/java/org/ros2/rcljava/exception/NoImplementationAvailableException.java"
+ "src/main/java/org/ros2/rcljava/exception/NotInitializedException.java"
)
add_jar("${PROJECT_NAME}_jar"
diff --git a/rcljava/src/main/java/org/ros2/rcljava/Consumer.java b/rcljava/src/main/java/org/ros2/rcljava/Consumer.java
index 74abbca4..3b2dd690 100644
--- a/rcljava/src/main/java/org/ros2/rcljava/Consumer.java
+++ b/rcljava/src/main/java/org/ros2/rcljava/Consumer.java
@@ -1,5 +1,24 @@
+/* Copyright 2016 Open Source Robotics Foundation, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.ros2.rcljava;
+/**
+ *
+ *
+ * @author Esteve Fernandez
+ */
public interface Consumer {
void accept(T t);
}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/Log.java b/rcljava/src/main/java/org/ros2/rcljava/Log.java
new file mode 100644
index 00000000..42c3f079
--- /dev/null
+++ b/rcljava/src/main/java/org/ros2/rcljava/Log.java
@@ -0,0 +1,36 @@
+/* Copyright 2016 Open Source Robotics Foundation, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.ros2.rcljava;
+
+import org.ros2.rcljava.exception.NoImplementationAvailableException;
+
+/**
+ * Not define in ROS2.
+ *
+ * @author Mickael Gaillard
+ */
+public class Log {
+
+ public Log() { }
+
+ public void fatal(Exception e) {
+ throw new NoImplementationAvailableException(e);
+ }
+
+ public void info(String string) {
+ throw new NoImplementationAvailableException(new Exception(string));
+ }
+
+}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/Node.java b/rcljava/src/main/java/org/ros2/rcljava/Node.java
index 56e1bac4..e9560c38 100644
--- a/rcljava/src/main/java/org/ros2/rcljava/Node.java
+++ b/rcljava/src/main/java/org/ros2/rcljava/Node.java
@@ -1,12 +1,32 @@
+/* Copyright 2016 Open Source Robotics Foundation, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.ros2.rcljava;
import java.lang.ref.WeakReference;
-
import java.util.ArrayList;
import java.util.List;
+/**
+ * Node ROS2.
+ *
+ * @author Esteve Fernandez
+ * @author Mickael Gaillard
+ */
public class Node {
- static {
+
+ static {
try {
System.loadLibrary("rcljavaNode__" + RCLJava.getRMWIdentifier());
} catch (UnsatisfiedLinkError e) {
@@ -15,35 +35,73 @@ public class Node {
}
}
- private long nodeHandle;
- private List subscriptions = new ArrayList();
+ /** Node handler */
+ private final long nodeHandle;
- public Node(long nodeHandle) {
- this.nodeHandle = nodeHandle;
- }
+ /** List of subscriptions */
+ private final List> subscriptions;
+ // Native call.
private static native long nativeCreatePublisherHandle(
- long nodeHandle, Class cls, String topic);
+ long nodeHandle, Class cls, String topic);
private static native long nativeCreateSubscriptionHandle(
long nodeHandle, Class cls, String topic);
- public Publisher createPublisher(Class cls, String topic) {
- long publisherHandle = nativeCreatePublisherHandle(this.nodeHandle, cls, topic);
- Publisher publisher = new Publisher(this.nodeHandle, publisherHandle);
- RCLJava.publisherReferences.add(new WeakReference(publisher));
+ /**
+ * Constructor of Node.
+ * @param nodeHandle Handler to the node.
+ */
+ public Node(long nodeHandle) {
+ this.nodeHandle = nodeHandle;
+ this.subscriptions = new ArrayList>();
+ }
+
+ /**
+ * Create a new publisher.
+ *
+ * @param Message definition.
+ * @param message Message class.
+ * @param topic Topic to publish.
+ * @param qos QOS profile.
+ * @return Publisher instance.
+ */
+ public Publisher createPublisher(Class message, String topic, QoSProfile qos) {
+ long publisherHandle = Node.nativeCreatePublisherHandle(this.nodeHandle, message, topic);
+
+ Publisher publisher = new Publisher(this.nodeHandle, publisherHandle, message, topic, qos);
+ RCLJava.publisherReferences.add(new WeakReference>(publisher));
+
return publisher;
}
- public Subscription createSubscription(Class cls, String topic, Consumer callback) {
- long subscriptionHandle = nativeCreateSubscriptionHandle(this.nodeHandle, cls, topic);
+ /**
+ * Create a new Subscriber with callback.
+ *
+ * @param Message definition.
+ * @param message Message Class
+ * @param topic Topic to subscribe.
+ * @param callback Function to call on recieve.
+ * @param qos QOS profile.
+ * @return
+ */
+ public Subscription createSubscription(Class message, String topic, Consumer callback, QoSProfile qos) {
+ long subscriptionHandle = Node.nativeCreateSubscriptionHandle(this.nodeHandle, message, topic);
- Subscription subscription = new Subscription(this.nodeHandle, subscriptionHandle, cls, topic, callback);
+ Subscription subscription = new Subscription(this.nodeHandle, subscriptionHandle, message, topic, callback, qos);
this.subscriptions.add(subscription);
return subscription;
}
- public List getSubscriptions() {
+ /**
+ * Get list of Subscriptions.
+ * @return ArrayList of Subscriptions
+ */
+ public List> getSubscriptions() {
return this.subscriptions;
}
+
+ public Log getLog() {
+ return new Log();
+ }
}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/Publisher.java b/rcljava/src/main/java/org/ros2/rcljava/Publisher.java
index 12696128..ac642ec0 100644
--- a/rcljava/src/main/java/org/ros2/rcljava/Publisher.java
+++ b/rcljava/src/main/java/org/ros2/rcljava/Publisher.java
@@ -1,7 +1,48 @@
+/* Copyright 2016 Open Source Robotics Foundation, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.ros2.rcljava;
+/**
+ * Publisher of node.
+ *
+ * @param Message Type.
+ * @author Esteve Fernandez
+ * @author Mickael Gaillard
+ */
public class Publisher {
- static {
+
+ /** Node Handler. */
+ private final long nodeHandle;
+
+ /** Publisher Hander. */
+ private final long publisherHandle;
+
+ /** Message Type. */
+ private final Class messageType;
+
+ /** Topic to publish. */
+ private final String topic;
+
+ /** Quality of Service profil. */
+ private final QoSProfile qosProfile;
+
+ // Native call.
+ private static native void nativePublish(long publisherHandle, T msg);
+ private static native void nativeDispose(long nodeHandle, long publisherHandle);
+
+ static {
try {
System.loadLibrary("rcljavaPublisher__" + RCLJava.getRMWIdentifier());
} catch (UnsatisfiedLinkError e) {
@@ -10,24 +51,51 @@ public class Publisher {
}
}
- private long nodeHandle;
- private long publisherHandle;
-
- public Publisher(long nodeHandle, long publisherHandle) {
+ /**
+ * Constructor of Publisher.
+ *
+ * @param nodeHandle Node handler initialize.
+ * @param publisherHandle Publisher handler.
+ * @param messageType Message type.
+ * @param topic Topic to publish.
+ * @param qos Quality of Service profile.
+ */
+ public Publisher(long nodeHandle, long publisherHandle, Class messageType, String topic, QoSProfile qosProfile) {
this.nodeHandle = nodeHandle;
this.publisherHandle = publisherHandle;
+ this.messageType = messageType;
+ this.topic = topic;
+ this.qosProfile = qosProfile;
}
- private static native void nativePublish(long publisherHandle, T msg);
-
+ /**
+ * Publish a message.
+ * @param msg Message to publish.
+ */
public void publish(T msg) {
- nativePublish(this.publisherHandle, msg);
+ Publisher.nativePublish(this.publisherHandle, msg); //TODO(theos) add qosProfile
}
- private static native void nativeDispose(
- long nodeHandle, long publisherHandle);
+ /**
+ * Get message type.
+ * @return
+ */
+ public Class getMsgType() {
+ return this.messageType;
+ }
+
+ /**
+ * Get topic name.
+ * @return
+ */
+ public String getTopic() {
+ return this.topic;
+ }
+ /**
+ * Release all Publisher ressource.
+ */
public void dispose() {
- nativeDispose(this.nodeHandle, this.publisherHandle);
+ Publisher.nativeDispose(this.nodeHandle, this.publisherHandle);
}
}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/QoSProfile.java b/rcljava/src/main/java/org/ros2/rcljava/QoSProfile.java
new file mode 100644
index 00000000..e894ad75
--- /dev/null
+++ b/rcljava/src/main/java/org/ros2/rcljava/QoSProfile.java
@@ -0,0 +1,30 @@
+/* Copyright 2016 Open Source Robotics Foundation, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.ros2.rcljava;
+
+/**
+ * Quality of Service
+ * TODO Not full implemented !!
+ * @author Mickael Gaillard
+ */
+public class QoSProfile {
+
+ public static final QoSProfile DEFAULT = new QoSProfile();
+
+ public QoSProfile() {
+
+ }
+
+}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/RCLJava.java b/rcljava/src/main/java/org/ros2/rcljava/RCLJava.java
index cd8fd36c..28d01fd4 100644
--- a/rcljava/src/main/java/org/ros2/rcljava/RCLJava.java
+++ b/rcljava/src/main/java/org/ros2/rcljava/RCLJava.java
@@ -1,21 +1,76 @@
+/* Copyright 2016 Open Source Robotics Foundation, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.ros2.rcljava;
import java.lang.ref.WeakReference;
-
import java.util.Queue;
-import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
+import org.ros2.rcljava.exception.NoImplementationAvailableException;
+
import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;
+/**
+ * ROS2 java client wrapper.
+ * JNI call of ROS2 c client.
+ *
+ * @author Esteve Fernandez
+ */
public class RCLJava {
+
+ /** Global List/Queue of publishers. */
public static Queue publisherReferences = new LinkedBlockingQueue();
+ /** Current ROS2 middleware implementation use. */
+ private static String rmwImplementation = null;
+
+ /** ROS2 client is initialized. */
+ private static boolean initialized = false;
+
+ /** List of ROS2 middleware supported. */
+ private static final Map rmwToTypesupport = new ConcurrentSkipListMap() {
+ /** Serial Id */
+ private static final long serialVersionUID = 1L;
+
+ {
+ put("rmw_fastrtps_cpp", "rosidl_typesupport_introspection_c");
+ put("rmw_opensplice_cpp", "rosidl_typesupport_opensplice_c");
+ put("rmw_connext_cpp", "rosidl_typesupport_connext_c");
+ put("rmw_connext_dynamic_cpp", "rosidl_typesupport_introspection_c");
+ }
+ };
+
+ // Natives definitions
+ private static native void nativeRCLJavaInit();
+ private static native long nativeCreateNodeHandle(String nodeName);
+ private static native boolean nativeOk();
+ private static native String nativeGetRMWIdentifier();
+ private static native void nativeShutdown();
+ private static native long nativeGetZeroInitializedWaitSet();
+ private static native void nativeWaitSetInit(long waitSetHandle, int numberOfSubscriptions, int numberOfGuardConditions, int numberOfTimers);
+ private static native void nativeWaitSetClearSubscriptions(long waitSetHandle);
+ private static native void nativeWaitSetAddSubscription(long waitSetHandle, long subscriptionHandle);
+ private static native void nativeWait(long waitSetHandle);
+ private static native Object nativeTake(long SubscriptionHandle, Class> msgType);
+
+ /** Release all ressources at shutdown. */
static {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
- for(WeakReference publisherReference : publisherReferences) {
+ for(WeakReference> publisherReference : RCLJava.publisherReferences) {
if(publisherReference.get() != null) {
publisherReference.get().dispose();
}
@@ -24,112 +79,140 @@ public void run() {
});
}
- private static String rmwImplementation = null;
- private static boolean initialized = false;
-
- private static final Map rmwToTypesupport = new ConcurrentSkipListMap() {{
- put("rmw_fastrtps_cpp", "rosidl_typesupport_introspection_c");
- put("rmw_opensplice_cpp", "rosidl_typesupport_opensplice_c");
- put("rmw_connext_cpp", "rosidl_typesupport_connext_c");
- put("rmw_connext_dynamic_cpp", "rosidl_typesupport_introspection_c");
- }};
-
+ /**
+ * Global initialization of rcl.
+ *
+ * Unless otherwise noted, this must be called
+ * before using any rcl functions.
+ *
+ * This function can only be run once after starting the program, and once
+ * after each call to rcl_shutdown. Repeated calls will fail with
+ * RCL_RET_ALREADY_INIT. This function is not thread safe.
+ *
+ */
public static void rclJavaInit() {
- synchronized(RCLJava.class) {
- if (!initialized) {
+ synchronized (RCLJava.class) {
+ if (!RCLJava.initialized) {
if (RCLJava.rmwImplementation == null) {
- for(Map.Entry entry : rmwToTypesupport.entrySet()) {
+ for (Map.Entry entry : rmwToTypesupport.entrySet()) {
try {
- setRMWImplementation(entry.getKey());
+ RCLJava.setRMWImplementation(entry.getKey());
break;
- } catch(UnsatisfiedLinkError ule) {
- // TODO(esteve): handle exception
- } catch(Exception e) {
+ } catch (NoImplementationAvailableException e) {
// TODO(esteve): handle exception
}
}
}
+
if (RCLJava.rmwImplementation == null) {
System.err.println("No RMW implementation found");
System.exit(1);
} else {
- nativeRCLJavaInit();
- initialized = true;
+ RCLJava.nativeRCLJavaInit();
+ RCLJava.initialized = true;
}
}
}
}
- private static native void nativeRCLJavaInit();
-
- private static native long nativeCreateNodeHandle(String nodeName);
+ /**
+ * Node Reference of native node.
+ *
+ * @param nodeName Name of the node.
+ * @return Instance of Node Reference.
+ */
+ public static Node createNode(String nodeName) {
+ long nodeHandle = RCLJava.nativeCreateNodeHandle(nodeName);
- public static String getTypesupportIdentifier() {
- String typesupportIdentifier = rmwToTypesupport.get(nativeGetRMWIdentifier());
- return typesupportIdentifier;
+ return new Node(nodeHandle);
}
- public static void setRMWImplementation(String rmwImplementation) throws Exception {
- synchronized(RCLJava.class) {
- System.loadLibrary("rcljavaRCLJava__" + rmwImplementation);
- RCLJava.rmwImplementation = rmwImplementation;
+ /**
+ * Wait for once loop.
+ * @param node
+ */
+ public static void spinOnce(Node node) {
+ long waitSetHandle = RCLJava.nativeGetZeroInitializedWaitSet();
+
+ RCLJava.nativeWaitSetInit(waitSetHandle, node.getSubscriptions().size(), 0, 0);
+ RCLJava.nativeWaitSetClearSubscriptions(waitSetHandle);
+
+ for(Subscription> subscription : node.getSubscriptions()) {
+ RCLJava.nativeWaitSetAddSubscription(waitSetHandle, subscription.getSubscriptionHandle());
}
- }
- private static native String nativeGetRMWIdentifier();
+ RCLJava.nativeWait(waitSetHandle);
- public static String getRMWIdentifier() {
- return nativeGetRMWIdentifier();
+ for(Subscription subscription : node.getSubscriptions()) {
+ Object msg = RCLJava.nativeTake(subscription.getSubscriptionHandle(), subscription.getMsgType());
+ if (msg != null) {
+ subscription.getCallback().accept(msg);
+ }
+ }
}
- private static native boolean nativeOk();
-
+ /**
+ * Check if native is ready.
+ *
+ * @see rcl_node_is_valid(const rcl_node_t * node);
+ * @return true if the node is valid, else false.
+ */
public static boolean ok() {
- return nativeOk();
+ return RCLJava.nativeOk();
}
- public static Node createNode(String nodeName) {
- long nodeHandle = nativeCreateNodeHandle(nodeName);
- Node node = new Node(nodeHandle);
- return node;
+ /**
+ * Signal global shutdown of RCLJava.
+ *
+ * This function does not have to be
+ * called on exit, but does have to be called making a repeat call to
+ * RCLJava.rclJavaInit.
+ *
+ * This function can only be called once after each call to RCLJava.rclJavaInit.
+ *
+ */
+ public static void shutdown() {
+ RCLJava.nativeShutdown();
}
- public static void spinOnce(Node node) {
- long waitSetHandle = nativeGetZeroInitializedWaitSet();
-
- nativeWaitSetInit(waitSetHandle, node.getSubscriptions().size(), 0, 0);
-
- nativeWaitSetClearSubscriptions(waitSetHandle);
-
- for(Subscription subscription : node.getSubscriptions()) {
- nativeWaitSetAddSubscription(waitSetHandle, subscription.getSubscriptionHandle());
- }
-
- nativeWait(waitSetHandle);
-
- for(Subscription subscription : node.getSubscriptions()) {
- Object msg = nativeTake(subscription.getSubscriptionHandle(), subscription.getMsgType());
- if (msg != null) {
- subscription.getCallback().accept(msg);
- }
- }
+ /**
+ * Get ROS Midleware indentifier.
+ *
+ * @return indentifier.
+ */
+ public static String getRMWIdentifier() {
+ return RCLJava.nativeGetRMWIdentifier();
}
- private static native void nativeShutdown();
+ /**
+ * Get identifier of the ROS2 middleware use.
+ * TODO rename to list of RMW available.
+ * @return Identifier string of ROS2 middleware.
+ */
+ public static String getTypesupportIdentifier() {
+ String typesupportIdentifier = rmwToTypesupport.get(RCLJava.getRMWIdentifier());
- public static void shutdown() {
- nativeShutdown();
+ return typesupportIdentifier;
}
- private static native long nativeGetZeroInitializedWaitSet();
-
- private static native void nativeWaitSetInit(long waitSetHandle, int numberOfSubscriptions, int numberOfGuardConditions, int numberOfTimers);
-
- private static native void nativeWaitSetClearSubscriptions(long waitSetHandle);
+ /**
+ * Switch of ROS2 middleware implementation
+ * TODO need to check implementation available.
+ * @param rmwImplementation
+ * @throws NoImplementationAvailableException
+ */
+ public static void setRMWImplementation(String rmwImplementation)
+ throws NoImplementationAvailableException {
- private static native void nativeWaitSetAddSubscription(long waitSetHandle, long subscriptionHandle);
-
- private static native void nativeWait(long waitSetHandle);
-
- private static native Object nativeTake(long SubscriptionHandle, Class msgType);
+ synchronized(RCLJava.class) {
+ try {
+ System.loadLibrary("rcljavaRCLJava__" + rmwImplementation);
+ RCLJava.rmwImplementation = rmwImplementation;
+ } catch (UnsatisfiedLinkError ule) {
+ throw new NoImplementationAvailableException(ule);
+ } catch (Exception e) {
+ throw new NoImplementationAvailableException(e);
+ }
+ }
+ }
}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/Subscription.java b/rcljava/src/main/java/org/ros2/rcljava/Subscription.java
index 035e14c8..5843c24d 100644
--- a/rcljava/src/main/java/org/ros2/rcljava/Subscription.java
+++ b/rcljava/src/main/java/org/ros2/rcljava/Subscription.java
@@ -1,30 +1,90 @@
+/* Copyright 2016 Open Source Robotics Foundation, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package org.ros2.rcljava;
+/**
+ * Subscrition of node.
+ *
+ * @param Message Type.
+ * @author Esteve Fernandez
+ * @author Mickael Gaillard
+ */
public class Subscription {
+ /** Node Handler. */
private long nodeHandle;
+
+ /** Subsciption Hander. */
private long subscriptionHandle;
- private Class msgType;
+
+ /** Message Type. */
+ private Class messageType;
+
+ /** Topic subscribed. */
private String topic;
+
+ /** Callback. */
private Consumer callback;
- public Subscription(long nodeHandle, long subscriptionHandle, Class msgType, String topic, Consumer callback) {
+ /** Quality of Service profil. */
+ private QoSProfile qosProfile;
+
+ // Native call.
+ private static native void nativeDispose(long nodeHandle, long publisherHandle);
+
+ public Subscription(long nodeHandle, long subscriptionHandle, Class messageType, String topic, Consumer callback, QoSProfile qosProfile) {
this.nodeHandle = nodeHandle;
this.subscriptionHandle = subscriptionHandle;
- this.msgType = msgType;
+ this.messageType = messageType;
this.topic = topic;
this.callback = callback;
+ this.qosProfile = qosProfile;
}
+ /**
+ * Get Callback.
+ * @return
+ */
public Consumer getCallback() {
- return callback;
+ return this.callback;
}
+ public long getSubscriptionHandle() {
+ return this.subscriptionHandle;
+ }
+
+ /**
+ * Get message type.
+ * @return
+ */
public Class getMsgType() {
- return msgType;
+ return this.messageType;
}
- public long getSubscriptionHandle() {
- return subscriptionHandle;
+ /**
+ * Get topic name.
+ * @return
+ */
+ public String getTopic() {
+ return this.topic;
+ }
+
+ /**
+ * Release all Publisher ressource.
+ */
+ public void dispose() {
+ Subscription.nativeDispose(this.nodeHandle, this.subscriptionHandle);
}
}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/exception/ImplementationAlreadyImportedException.java b/rcljava/src/main/java/org/ros2/rcljava/exception/ImplementationAlreadyImportedException.java
new file mode 100644
index 00000000..d225a55f
--- /dev/null
+++ b/rcljava/src/main/java/org/ros2/rcljava/exception/ImplementationAlreadyImportedException.java
@@ -0,0 +1,34 @@
+/* Copyright 2016 Open Source Robotics Foundation, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.ros2.rcljava.exception;
+
+/**
+ * Raised on select_rmw_implemenation() after import_rmw_implementation() has
+ * been called.
+ *
+ * @author Mickael Gaillard
+ */
+public class ImplementationAlreadyImportedException extends Exception {
+
+ /**
+ * Constructor.
+ *
+ * @param cause
+ */
+ public ImplementationAlreadyImportedException(Throwable cause) {
+ super("rmw implementation already imported", cause);
+ }
+
+}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/exception/InvalidRCLJAVAImplementation.java b/rcljava/src/main/java/org/ros2/rcljava/exception/InvalidRCLJAVAImplementation.java
new file mode 100644
index 00000000..e97e8ee8
--- /dev/null
+++ b/rcljava/src/main/java/org/ros2/rcljava/exception/InvalidRCLJAVAImplementation.java
@@ -0,0 +1,34 @@
+/* Copyright 2016 Open Source Robotics Foundation, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.ros2.rcljava.exception;
+
+/**
+ * Raised when an invalid RCLPYImplementation is requested.
+ *
+ * @author Mickael Gaillard
+ *
+ */
+public class InvalidRCLJAVAImplementation extends Exception {
+
+ /**
+ * Constructor.
+ *
+ * @param cause
+ */
+ public InvalidRCLJAVAImplementation(Throwable cause) {
+ super("requested invalid rmw implementation", cause);
+ }
+
+}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/exception/NoImplementationAvailableException.java b/rcljava/src/main/java/org/ros2/rcljava/exception/NoImplementationAvailableException.java
new file mode 100644
index 00000000..49305510
--- /dev/null
+++ b/rcljava/src/main/java/org/ros2/rcljava/exception/NoImplementationAvailableException.java
@@ -0,0 +1,36 @@
+/* Copyright 2016 Open Source Robotics Foundation, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.ros2.rcljava.exception;
+
+/**
+ * Raised when there is no rmw implementation with a Java extension available.
+ *
+ * @author Mickael Gaillard
+ *
+ */
+public class NoImplementationAvailableException extends RuntimeException {
+
+ /** Serial ID */
+ private static final long serialVersionUID = -2351440132432398102L;
+
+ /**
+ * Constructor.
+ *
+ * @param cause
+ */
+ public NoImplementationAvailableException(Throwable cause) {
+ super("no rmw implementation with a Java extension available", cause);
+ }
+}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/exception/NotInitializedException.java b/rcljava/src/main/java/org/ros2/rcljava/exception/NotInitializedException.java
new file mode 100644
index 00000000..d6c1ffa9
--- /dev/null
+++ b/rcljava/src/main/java/org/ros2/rcljava/exception/NotInitializedException.java
@@ -0,0 +1,33 @@
+/* Copyright 2016 Open Source Robotics Foundation, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.ros2.rcljava.exception;
+
+/**
+ * Raised when the rcljava implementation is accessed before RclJava().
+ *
+ * @author Mickael Gaillard
+ *
+ */
+public class NotInitializedException extends Exception {
+
+ /**
+ * Constructor.
+ *
+ * @param cause
+ */
+ public NotInitializedException(Throwable cause) {
+ super("RclJava() has not been called", cause);
+ }
+}
From bbe8d3a4a7930888f0fe199da1370c92f0e49cfa Mon Sep 17 00:00:00 2001
From: Mickael Gaillard
Date: Mon, 29 Aug 2016 02:28:14 +0200
Subject: [PATCH 2/6] Add QOS profile
---
.../java/org/ros2/rcljava/QoSProfile.java | 103 +++++++++++++++++-
1 file changed, 100 insertions(+), 3 deletions(-)
diff --git a/rcljava/src/main/java/org/ros2/rcljava/QoSProfile.java b/rcljava/src/main/java/org/ros2/rcljava/QoSProfile.java
index e894ad75..c10b0693 100644
--- a/rcljava/src/main/java/org/ros2/rcljava/QoSProfile.java
+++ b/rcljava/src/main/java/org/ros2/rcljava/QoSProfile.java
@@ -15,16 +15,113 @@
package org.ros2.rcljava;
/**
- * Quality of Service
+ * Quality of Service Profile
* TODO Not full implemented !!
* @author Mickael Gaillard
*/
public class QoSProfile {
- public static final QoSProfile DEFAULT = new QoSProfile();
+ /** Default Depth level */
+ public static final int DEPTH_SYSTEM_DEFAULT = 0;
- public QoSProfile() {
+ /** Reliability Policy enum. */
+ public enum ReliabilityPolicy {
+ SYSTEM_DEFAULT,
+ RELIABLE,
+ BEST_EFFORT
+ }
+
+ /** History Policy enum. */
+ public enum HistoryPolicy {
+ SYSTEM_DEFAULT,
+ KEEP_LAST,
+ KEEP_ALL
+ }
+ /** Durability Policy enum. */
+ public enum DurabilityPolicy {
+ SYSTEM_DEFAULT,
+ TRANSIENT_LOCAL,
+ VOLATILE
}
+ /** Sensor QOS Profile */
+ public static final QoSProfile PROFILE_SENSOR_DATA = new QoSProfile(
+ HistoryPolicy.KEEP_LAST,
+ 5,
+ ReliabilityPolicy.BEST_EFFORT,
+ DurabilityPolicy.SYSTEM_DEFAULT
+ );
+
+ /** Parameter QOS Profile */
+ public static final QoSProfile PROFILE_PARAMETER = new QoSProfile(
+ HistoryPolicy.KEEP_LAST,
+ 1000,
+ ReliabilityPolicy.RELIABLE,
+ DurabilityPolicy.SYSTEM_DEFAULT
+ );
+
+ /** Default QOS Profile */
+ public static final QoSProfile PROFILE_DEFAULT = new QoSProfile(
+ HistoryPolicy.KEEP_ALL,
+ 10,
+ ReliabilityPolicy.RELIABLE,
+ DurabilityPolicy.SYSTEM_DEFAULT
+ );
+
+ /** Services default QOS Profile */
+ public static final QoSProfile PROFILE_SERVICES_DEFAULT = new QoSProfile(
+ HistoryPolicy.KEEP_LAST,
+ 10,
+ ReliabilityPolicy.RELIABLE,
+ DurabilityPolicy.TRANSIENT_LOCAL
+ );
+
+ /** Parameter events QOS Profile */
+ public static final QoSProfile PROFILE_PARAMETER_EVENTS = new QoSProfile(
+ HistoryPolicy.KEEP_ALL,
+ 1000,
+ ReliabilityPolicy.RELIABLE,
+ DurabilityPolicy.SYSTEM_DEFAULT
+ );
+
+ /** System default QOS Profile */
+ public static final QoSProfile PROFILE_SYSTEM_DEFAULT = new QoSProfile(
+ HistoryPolicy.SYSTEM_DEFAULT,
+ DEPTH_SYSTEM_DEFAULT,
+ ReliabilityPolicy.SYSTEM_DEFAULT,
+ DurabilityPolicy.SYSTEM_DEFAULT
+ );
+
+ /** History Policy */
+ protected final HistoryPolicy history;
+
+ /** Depth */
+ protected final int depth;
+
+ /** Reliability Policy */
+ protected final ReliabilityPolicy reliability;
+
+ /** Durability Policy */
+ protected final DurabilityPolicy durability;
+
+ /**
+ * Constuctor.
+ *
+ * @param history
+ * @param depth
+ * @param reliability
+ * @param durability
+ */
+ public QoSProfile(
+ HistoryPolicy history,
+ int depth,
+ ReliabilityPolicy reliability,
+ DurabilityPolicy durability) {
+
+ this.history = history;
+ this.depth = depth;
+ this.reliability = reliability;
+ this.durability = durability;
+ }
}
From 3d92ae0e0efce04954bf994c7295616df4773407 Mon Sep 17 00:00:00 2001
From: Mickael Gaillard
Date: Mon, 29 Aug 2016 02:28:47 +0200
Subject: [PATCH 3/6] Refactor code
---
rcljava/src/main/java/org/ros2/rcljava/Node.java | 9 ++++++---
.../src/main/java/org/ros2/rcljava/Subscription.java | 12 ++++++------
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/rcljava/src/main/java/org/ros2/rcljava/Node.java b/rcljava/src/main/java/org/ros2/rcljava/Node.java
index e9560c38..274f1c9c 100644
--- a/rcljava/src/main/java/org/ros2/rcljava/Node.java
+++ b/rcljava/src/main/java/org/ros2/rcljava/Node.java
@@ -46,7 +46,7 @@ private static native long nativeCreatePublisherHandle(
long nodeHandle, Class cls, String topic);
private static native long nativeCreateSubscriptionHandle(
- long nodeHandle, Class cls, String topic);
+ long nodeHandle, Class cls, String topic);
/**
* Constructor of Node.
@@ -101,7 +101,10 @@ public List> getSubscriptions() {
return this.subscriptions;
}
- public Log getLog() {
- return new Log();
+ /**
+ * Release all Publisher ressource.
+ */
+ public void dispose() {
+ //TODO
}
}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/Subscription.java b/rcljava/src/main/java/org/ros2/rcljava/Subscription.java
index 5843c24d..5aa32cff 100644
--- a/rcljava/src/main/java/org/ros2/rcljava/Subscription.java
+++ b/rcljava/src/main/java/org/ros2/rcljava/Subscription.java
@@ -24,22 +24,22 @@
public class Subscription {
/** Node Handler. */
- private long nodeHandle;
+ private final long nodeHandle;
/** Subsciption Hander. */
- private long subscriptionHandle;
+ private final long subscriptionHandle;
/** Message Type. */
- private Class messageType;
+ private final Class messageType;
/** Topic subscribed. */
- private String topic;
+ private final String topic;
/** Callback. */
- private Consumer callback;
+ private final Consumer callback;
/** Quality of Service profil. */
- private QoSProfile qosProfile;
+ private final QoSProfile qosProfile;
// Native call.
private static native void nativeDispose(long nodeHandle, long publisherHandle);
From 4ce5c2c76b22033ea831d6c7cb9ccdc280b31ecd Mon Sep 17 00:00:00 2001
From: Mickael Gaillard
Date: Sun, 4 Sep 2016 16:25:37 +0200
Subject: [PATCH 4/6] Move/refactor loadLibrary and added logger.
---
rcljava/CMakeLists.txt | 1 +
.../java/org/ros2/rcljava/NativeUtils.java | 34 +++++++++++++
.../src/main/java/org/ros2/rcljava/Node.java | 27 ++++++----
.../main/java/org/ros2/rcljava/Publisher.java | 10 ++--
.../main/java/org/ros2/rcljava/RCLJava.java | 51 +++++++++++++++++--
.../resource/msg.java.template | 7 +--
.../rosidl_generator_java/RCLJavaProxy.java | 9 ++++
7 files changed, 113 insertions(+), 26 deletions(-)
create mode 100644 rcljava/src/main/java/org/ros2/rcljava/NativeUtils.java
diff --git a/rcljava/CMakeLists.txt b/rcljava/CMakeLists.txt
index a9920e1d..6015398c 100644
--- a/rcljava/CMakeLists.txt
+++ b/rcljava/CMakeLists.txt
@@ -89,6 +89,7 @@ set(${PROJECT_NAME}_sources
"src/main/java/org/ros2/rcljava/Consumer.java"
"src/main/java/org/ros2/rcljava/Log.java"
"src/main/java/org/ros2/rcljava/QoSProfile.java"
+ "src/main/java/org/ros2/rcljava/NativeUtils.java"
"src/main/java/org/ros2/rcljava/exception/ImplementationAlreadyImportedException.java"
"src/main/java/org/ros2/rcljava/exception/InvalidRCLJAVAImplementation.java"
"src/main/java/org/ros2/rcljava/exception/NoImplementationAvailableException.java"
diff --git a/rcljava/src/main/java/org/ros2/rcljava/NativeUtils.java b/rcljava/src/main/java/org/ros2/rcljava/NativeUtils.java
new file mode 100644
index 00000000..8f84ee19
--- /dev/null
+++ b/rcljava/src/main/java/org/ros2/rcljava/NativeUtils.java
@@ -0,0 +1,34 @@
+package org.ros2.rcljava;
+
+import java.util.Vector;
+
+public abstract class NativeUtils {
+
+ private static java.lang.reflect.Field LIBRARIES;
+
+ static {
+ try {
+ LIBRARIES = ClassLoader.class.getDeclaredField("loadedLibraryNames");
+ LIBRARIES.setAccessible(true);
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static String[] getLoadedLibraries(final ClassLoader loader) {
+ Vector libraries = new Vector();
+
+ try {
+ libraries = (Vector) LIBRARIES.get(loader);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+
+ return libraries.toArray(new String[] {});
+ }
+}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/Node.java b/rcljava/src/main/java/org/ros2/rcljava/Node.java
index 274f1c9c..71bcf1a9 100644
--- a/rcljava/src/main/java/org/ros2/rcljava/Node.java
+++ b/rcljava/src/main/java/org/ros2/rcljava/Node.java
@@ -17,6 +17,7 @@
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
+import java.util.logging.Logger;
/**
* Node ROS2.
@@ -25,14 +26,10 @@
* @author Mickael Gaillard
*/
public class Node {
+ private static Logger logger = Logger.getLogger(RCLJava.LOG_NAME);
static {
- try {
- System.loadLibrary("rcljavaNode__" + RCLJava.getRMWIdentifier());
- } catch (UnsatisfiedLinkError e) {
- System.err.println("Native code library failed to load.\n" + e);
- System.exit(1);
- }
+ RCLJava.loadLibrary("rcljavaNode__" + RCLJava.getRMWIdentifier());
}
/** Node handler */
@@ -67,6 +64,7 @@ public Node(long nodeHandle) {
* @return Publisher instance.
*/
public Publisher createPublisher(Class message, String topic, QoSProfile qos) {
+ logger.fine("Create Publisher : " + topic);
long publisherHandle = Node.nativeCreatePublisherHandle(this.nodeHandle, message, topic);
Publisher publisher = new Publisher(this.nodeHandle, publisherHandle, message, topic, qos);
@@ -85,10 +83,21 @@ public Publisher createPublisher(Class message, String topic, QoSProf
* @param qos QOS profile.
* @return
*/
- public Subscription createSubscription(Class message, String topic, Consumer callback, QoSProfile qos) {
+ public Subscription createSubscription(
+ Class message,
+ String topic,
+ Consumer callback,
+ QoSProfile qos) {
+ logger.fine("Create Subscription : " + topic);
long subscriptionHandle = Node.nativeCreateSubscriptionHandle(this.nodeHandle, message, topic);
- Subscription subscription = new Subscription(this.nodeHandle, subscriptionHandle, message, topic, callback, qos);
+ Subscription subscription = new Subscription(
+ this.nodeHandle,
+ subscriptionHandle,
+ message,
+ topic,
+ callback,
+ qos);
this.subscriptions.add(subscription);
return subscription;
}
@@ -105,6 +114,6 @@ public List> getSubscriptions() {
* Release all Publisher ressource.
*/
public void dispose() {
- //TODO
+ //TODO Implement on JNI
}
}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/Publisher.java b/rcljava/src/main/java/org/ros2/rcljava/Publisher.java
index ac642ec0..c8f8b27d 100644
--- a/rcljava/src/main/java/org/ros2/rcljava/Publisher.java
+++ b/rcljava/src/main/java/org/ros2/rcljava/Publisher.java
@@ -43,12 +43,7 @@ public class Publisher {
private static native void nativeDispose(long nodeHandle, long publisherHandle);
static {
- try {
- System.loadLibrary("rcljavaPublisher__" + RCLJava.getRMWIdentifier());
- } catch (UnsatisfiedLinkError e) {
- System.err.println("Native code library failed to load.\n" + e);
- System.exit(1);
- }
+ RCLJava.loadLibrary("rcljavaPublisher__" + RCLJava.getRMWIdentifier());
}
/**
@@ -96,6 +91,7 @@ public String getTopic() {
* Release all Publisher ressource.
*/
public void dispose() {
- Publisher.nativeDispose(this.nodeHandle, this.publisherHandle);
+ //TODO implement to JNI
+ //Publisher.nativeDispose(this.nodeHandle, this.publisherHandle);
}
}
diff --git a/rcljava/src/main/java/org/ros2/rcljava/RCLJava.java b/rcljava/src/main/java/org/ros2/rcljava/RCLJava.java
index 28d01fd4..13341844 100644
--- a/rcljava/src/main/java/org/ros2/rcljava/RCLJava.java
+++ b/rcljava/src/main/java/org/ros2/rcljava/RCLJava.java
@@ -17,6 +17,10 @@
import java.lang.ref.WeakReference;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.logging.SimpleFormatter;
import org.ros2.rcljava.exception.NoImplementationAvailableException;
@@ -31,6 +35,10 @@
*/
public class RCLJava {
+ public static final String LOG_NAME = RCLJava.class.getName();
+
+ private static Logger logger = Logger.getLogger(LOG_NAME);
+
/** Global List/Queue of publishers. */
public static Queue publisherReferences = new LinkedBlockingQueue();
@@ -68,8 +76,16 @@ public class RCLJava {
/** Release all ressources at shutdown. */
static {
+ logger.setLevel(Level.ALL);
+ ConsoleHandler handler = new ConsoleHandler();
+ handler.setFormatter(new SimpleFormatter());
+ logger.addHandler(handler);
+ handler.setLevel(Level.INFO);
+
+
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
+ logger.fine("Shutdown...");
for(WeakReference> publisherReference : RCLJava.publisherReferences) {
if(publisherReference.get() != null) {
publisherReference.get().dispose();
@@ -93,19 +109,24 @@ public void run() {
public static void rclJavaInit() {
synchronized (RCLJava.class) {
if (!RCLJava.initialized) {
+ String libpath = System.getProperty("java.library.path");
+ logger.fine("Native Library path : \n" + libpath.replace(':', '\n'));
+
if (RCLJava.rmwImplementation == null) {
for (Map.Entry entry : rmwToTypesupport.entrySet()) {
try {
+ logger.config("Try to load native " + entry.getKey() + "...");
RCLJava.setRMWImplementation(entry.getKey());
+ logger.config(entry.getKey() + " loaded !");
break;
} catch (NoImplementationAvailableException e) {
- // TODO(esteve): handle exception
+ logger.config(entry.getKey() + " not available ! (" + e.getMessage() + ")");
}
}
}
if (RCLJava.rmwImplementation == null) {
- System.err.println("No RMW implementation found");
+ logger.severe("No RMW implementation found...");
System.exit(1);
} else {
RCLJava.nativeRCLJavaInit();
@@ -122,6 +143,7 @@ public static void rclJavaInit() {
* @return Instance of Node Reference.
*/
public static Node createNode(String nodeName) {
+ logger.fine("Create Node stack : " + nodeName);
long nodeHandle = RCLJava.nativeCreateNodeHandle(nodeName);
return new Node(nodeHandle);
@@ -172,6 +194,7 @@ public static boolean ok() {
*
*/
public static void shutdown() {
+ logger.fine("Shutdown...");
RCLJava.nativeShutdown();
}
@@ -205,13 +228,33 @@ public static void setRMWImplementation(String rmwImplementation)
throws NoImplementationAvailableException {
synchronized(RCLJava.class) {
+ String file = "rcljavaRCLJava__" + rmwImplementation;
+ logger.fine("Load native file : lib" + file + ".so");
+
try {
- System.loadLibrary("rcljavaRCLJava__" + rmwImplementation);
+ System.loadLibrary(file);
RCLJava.rmwImplementation = rmwImplementation;
} catch (UnsatisfiedLinkError ule) {
throw new NoImplementationAvailableException(ule);
} catch (Exception e) {
- throw new NoImplementationAvailableException(e);
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Load Native ROS library
+ * load from java.library.path .
+ * @param name Name of the library.
+ */
+ public static void loadLibrary(String name) {
+ synchronized(RCLJava.class) {
+ logger.fine("Load native file : lib" + name + ".so");
+ try {
+ System.loadLibrary(name);
+ } catch (UnsatisfiedLinkError e) {
+ System.err.println("Native code library failed to load.\n" + e);
+ System.exit(1);
}
}
}
diff --git a/rosidl_generator_java/resource/msg.java.template b/rosidl_generator_java/resource/msg.java.template
index 57b72dfd..4c18f309 100644
--- a/rosidl_generator_java/resource/msg.java.template
+++ b/rosidl_generator_java/resource/msg.java.template
@@ -12,12 +12,7 @@ import @(field.type.pkg_name).msg.@(field.type.type);
public class @(type_name) {
static {
- try {
- System.loadLibrary("@(spec.base_type.pkg_name)_@(type_name)_s__" + RCLJavaProxy.getTypesupportIdentifier());
- } catch (UnsatisfiedLinkError e) {
- System.err.println("Native code library failed to load.\n" + e);
- System.exit(1);
- }
+ RCLJavaProxy.loadLibrary("@(spec.base_type.pkg_name)_@(type_name)_s__" + RCLJavaProxy.getTypesupportIdentifier());
}
public static native long getFromJavaConverter();
diff --git a/rosidl_generator_java/src/main/java/org/ros2/rosidl_generator_java/RCLJavaProxy.java b/rosidl_generator_java/src/main/java/org/ros2/rosidl_generator_java/RCLJavaProxy.java
index 9f7d7bf3..f5d46731 100644
--- a/rosidl_generator_java/src/main/java/org/ros2/rosidl_generator_java/RCLJavaProxy.java
+++ b/rosidl_generator_java/src/main/java/org/ros2/rosidl_generator_java/RCLJavaProxy.java
@@ -27,4 +27,13 @@ public static synchronized String getRMWIdentifier() {
}
}
+ public static synchronized void loadLibrary(String name) {
+ try {
+ Class c = Class.forName("org.ros2.rcljava.RCLJava");
+ Method m = c.getDeclaredMethod("loadLibrary", String.class);
+ Object o = m.invoke(null, name);
+ } catch(Exception e) {
+ // TODO(esteve): handle exception
+ }
+ }
}
From 8039e0abc617a51aeb31cbfe558db26f50bde89b Mon Sep 17 00:00:00 2001
From: Mickael Gaillard
Date: Sun, 4 Sep 2016 16:37:04 +0200
Subject: [PATCH 5/6] Added log native library and Fix
---
rcljava/src/main/java/org/ros2/rcljava/RCLJava.java | 9 +++++++++
rcljava/src/main/java/org/ros2/rcljava/Subscription.java | 3 ++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/rcljava/src/main/java/org/ros2/rcljava/RCLJava.java b/rcljava/src/main/java/org/ros2/rcljava/RCLJava.java
index 13341844..ee8ce5d1 100644
--- a/rcljava/src/main/java/org/ros2/rcljava/RCLJava.java
+++ b/rcljava/src/main/java/org/ros2/rcljava/RCLJava.java
@@ -86,6 +86,15 @@ public class RCLJava {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
logger.fine("Shutdown...");
+
+ String[] list = NativeUtils.getLoadedLibraries(RCLJava.class.getClassLoader());
+ StringBuilder msgLog = new StringBuilder();
+ for (String key : list) {
+ msgLog.append(key);
+ msgLog.append("\n");
+ }
+ logger.fine("Native libraries Loaded: \n" + msgLog.toString());
+
for(WeakReference> publisherReference : RCLJava.publisherReferences) {
if(publisherReference.get() != null) {
publisherReference.get().dispose();
diff --git a/rcljava/src/main/java/org/ros2/rcljava/Subscription.java b/rcljava/src/main/java/org/ros2/rcljava/Subscription.java
index 5aa32cff..4f2a7c5b 100644
--- a/rcljava/src/main/java/org/ros2/rcljava/Subscription.java
+++ b/rcljava/src/main/java/org/ros2/rcljava/Subscription.java
@@ -85,6 +85,7 @@ public String getTopic() {
* Release all Publisher ressource.
*/
public void dispose() {
- Subscription.nativeDispose(this.nodeHandle, this.subscriptionHandle);
+ //TODO implement to JNI
+ // Subscription.nativeDispose(this.nodeHandle, this.subscriptionHandle);
}
}
From 87456710eec6783f992e59dc38ea6ccacc6d7887 Mon Sep 17 00:00:00 2001
From: Mickael Gaillard
Date: Mon, 12 Sep 2016 17:37:56 +0200
Subject: [PATCH 6/6] Fixed bad type object
---
rosidl_generator_java/rosidl_generator_java/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rosidl_generator_java/rosidl_generator_java/__init__.py b/rosidl_generator_java/rosidl_generator_java/__init__.py
index 8b114e22..4e0ebd4f 100644
--- a/rosidl_generator_java/rosidl_generator_java/__init__.py
+++ b/rosidl_generator_java/rosidl_generator_java/__init__.py
@@ -135,7 +135,7 @@ def get_builtin_java_type(type_, use_primitives=True):
return 'byte' if use_primitives else 'Byte'
if type_ == 'char':
- return 'char' if use_primitives else 'Char'
+ return 'char' if use_primitives else 'Character'
if type_ == 'float32':
return 'float' if use_primitives else 'Float'