From 927a23b245e9f86a599f7205aa4860ca12655437 Mon Sep 17 00:00:00 2001 From: Ivan Santiago Paunovic Date: Thu, 3 Sep 2020 10:52:55 -0300 Subject: [PATCH 1/4] * Add NodeNameInfo class * Implement getNodeNames Signed-off-by: Ivan Santiago Paunovic --- rcljava/CMakeLists.txt | 8 +- .../org_ros2_rcljava_graph_NodeNameInfo.h | 35 ++++++++ .../include/org_ros2_rcljava_node_NodeImpl.h | 9 ++ .../org_ros2_rcljava_graph_NodeNameInfo.cpp | 51 ++++++++++++ .../cpp/org_ros2_rcljava_node_NodeImpl.cpp | 76 +++++++++++++++++ .../org/ros2/rcljava/graph/NodeNameInfo.java | 82 +++++++++++++++++++ .../main/java/org/ros2/rcljava/node/Node.java | 7 ++ .../java/org/ros2/rcljava/node/NodeImpl.java | 9 ++ .../java/org/ros2/rcljava/node/NodeTest.java | 59 +++++++++++++ 9 files changed, 333 insertions(+), 3 deletions(-) create mode 100644 rcljava/include/org_ros2_rcljava_graph_NodeNameInfo.h create mode 100644 rcljava/src/main/cpp/org_ros2_rcljava_graph_NodeNameInfo.cpp create mode 100644 rcljava/src/main/java/org/ros2/rcljava/graph/NodeNameInfo.java diff --git a/rcljava/CMakeLists.txt b/rcljava/CMakeLists.txt index 8f10aeb4..c4e06cc1 100644 --- a/rcljava/CMakeLists.txt +++ b/rcljava/CMakeLists.txt @@ -62,6 +62,7 @@ set(${PROJECT_NAME}_jni_sources "src/main/cpp/org_ros2_rcljava_executors_BaseExecutor.cpp" "src/main/cpp/org_ros2_rcljava_events_EventHandlerImpl.cpp" "src/main/cpp/org_ros2_rcljava_graph_EndpointInfo" + "src/main/cpp/org_ros2_rcljava_graph_NodeNameInfo.cpp" "src/main/cpp/org_ros2_rcljava_publisher_statuses_LivelinessLost.cpp" "src/main/cpp/org_ros2_rcljava_publisher_statuses_OfferedDeadlineMissed.cpp" "src/main/cpp/org_ros2_rcljava_publisher_statuses_OfferedQosIncompatible.cpp" @@ -143,9 +144,7 @@ set(${PROJECT_NAME}_sources "src/main/java/org/ros2/rcljava/events/PublisherEventStatus.java" "src/main/java/org/ros2/rcljava/events/SubscriptionEventStatus.java" "src/main/java/org/ros2/rcljava/graph/NameAndTypes.java" - "src/main/java/org/ros2/rcljava/publisher/statuses/LivelinessLost.java" - "src/main/java/org/ros2/rcljava/publisher/statuses/OfferedDeadlineMissed.java" - "src/main/java/org/ros2/rcljava/publisher/statuses/OfferedQosIncompatible.java" + "src/main/java/org/ros2/rcljava/graph/NodeNameInfo.java" "src/main/java/org/ros2/rcljava/executors/AnyExecutable.java" "src/main/java/org/ros2/rcljava/executors/BaseExecutor.java" "src/main/java/org/ros2/rcljava/executors/Executor.java" @@ -173,6 +172,9 @@ set(${PROJECT_NAME}_sources "src/main/java/org/ros2/rcljava/parameters/service/ParameterServiceImpl.java" "src/main/java/org/ros2/rcljava/publisher/Publisher.java" "src/main/java/org/ros2/rcljava/publisher/PublisherImpl.java" + "src/main/java/org/ros2/rcljava/publisher/statuses/LivelinessLost.java" + "src/main/java/org/ros2/rcljava/publisher/statuses/OfferedDeadlineMissed.java" + "src/main/java/org/ros2/rcljava/publisher/statuses/OfferedQosIncompatible.java" "src/main/java/org/ros2/rcljava/qos/policies/Durability.java" "src/main/java/org/ros2/rcljava/qos/policies/History.java" "src/main/java/org/ros2/rcljava/qos/policies/Liveliness.java" diff --git a/rcljava/include/org_ros2_rcljava_graph_NodeNameInfo.h b/rcljava/include/org_ros2_rcljava_graph_NodeNameInfo.h new file mode 100644 index 00000000..45886b26 --- /dev/null +++ b/rcljava/include/org_ros2_rcljava_graph_NodeNameInfo.h @@ -0,0 +1,35 @@ +// Copyright 2020 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. + +#include +/* Header for class org_ros2_rcljava_graph_NodeName */ + +#ifndef ORG_ROS2_RCLJAVA_GRAPH_NODENAMEINFO_H_ +#define ORG_ROS2_RCLJAVA_GRAPH_NODENAMEINFO_H_ +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_ros2_rcljava_graph_NodeName + * Method: nativeFromRCL + * Signature: (J)V + */ +JNIEXPORT void +JNICALL Java_org_ros2_rcljava_graph_NodeName_nativeFromRCL( + JNIEnv *, jobject, jlong, jlong, jlong); + +#ifdef __cplusplus +} +#endif +#endif // ORG_ROS2_RCLJAVA_GRAPH_NODENAMEINFO_H_ diff --git a/rcljava/include/org_ros2_rcljava_node_NodeImpl.h b/rcljava/include/org_ros2_rcljava_node_NodeImpl.h index 8f25d1f7..46729339 100644 --- a/rcljava/include/org_ros2_rcljava_node_NodeImpl.h +++ b/rcljava/include/org_ros2_rcljava_node_NodeImpl.h @@ -92,6 +92,15 @@ JNIEXPORT jlong JNICALL Java_org_ros2_rcljava_node_NodeImpl_nativeCreateTimerHandle( JNIEnv *, jclass, jlong, jlong, jlong); +/* + * Class: org_ros2_rcljava_node_NodeImpl + * Method: nativeGetNodeNames + * Signature: (JLjava/util/List;)V + */ +JNIEXPORT void +JNICALL Java_org_ros2_rcljava_node_NodeImpl_nativeGetNodeNames( + JNIEnv *, jclass, jlong, jobject); + /* * Class: org_ros2_rcljava_node_NodeImpl * Method: nativeGetTopicNamesAndTypes diff --git a/rcljava/src/main/cpp/org_ros2_rcljava_graph_NodeNameInfo.cpp b/rcljava/src/main/cpp/org_ros2_rcljava_graph_NodeNameInfo.cpp new file mode 100644 index 00000000..11c03f60 --- /dev/null +++ b/rcljava/src/main/cpp/org_ros2_rcljava_graph_NodeNameInfo.cpp @@ -0,0 +1,51 @@ +// Copyright 2020 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. + +#include "org_ros2_rcljava_graph_NodeNameInfo.h" + +#include +#include + +#include "rcl/graph.h" +#include "rcljava_common/exceptions.hpp" + +using rcljava_common::exceptions::rcljava_throw_exception; + +JNIEXPORT void JNICALL +JNICALL Java_org_ros2_rcljava_graph_NodeName_nativeFromRCL( + JNIEnv * env, jobject self, jlong name_handle, jlong namespace_handle, jlong enclave_handle) +{ + const char * name = reinterpret_cast(name_handle); + const char * n_namespace = reinterpret_cast(namespace_handle); + const char * enclave = reinterpret_cast(enclave_handle); + + jclass clazz = env->GetObjectClass(self); + jfieldID name_fid = env->GetFieldID(clazz, "name", "Ljava/langString;"); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); + jfieldID namespace_fid = env->GetFieldID(clazz, "namespace", "Ljava/langString;"); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); + jfieldID enclave_fid = env->GetFieldID(clazz, "enclave", "Ljava/langString;"); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); + + jstring jname = env->NewStringUTF(name); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); + jstring jnamespace = env->NewStringUTF(n_namespace); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); + jstring jenclave = env->NewStringUTF(enclave); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); + + env->SetObjectField(self, name_fid, jname); + env->SetObjectField(self, namespace_fid, jnamespace); + env->SetObjectField(self, enclave_fid, jenclave); +} diff --git a/rcljava/src/main/cpp/org_ros2_rcljava_node_NodeImpl.cpp b/rcljava/src/main/cpp/org_ros2_rcljava_node_NodeImpl.cpp index 726f48a2..937a53e6 100644 --- a/rcljava/src/main/cpp/org_ros2_rcljava_node_NodeImpl.cpp +++ b/rcljava/src/main/cpp/org_ros2_rcljava_node_NodeImpl.cpp @@ -254,6 +254,82 @@ Java_org_ros2_rcljava_node_NodeImpl_nativeCreateTimerHandle( return jtimer; } +JNIEXPORT void JNICALL +Java_org_ros2_rcljava_node_NodeImpl_nativeGetNodeNames( + JNIEnv * env, jclass, jlong handle, jobject jnode_names_info) +{ + rcl_node_t * node = reinterpret_cast(handle); + if (!node) { + rcljava_throw_exception(env, "java/lang/IllegalArgumentException", "node handle is NULL"); + return; + } + + jclass list_clazz = env->GetObjectClass(jnode_names_info); + jmethodID list_add_mid = env->GetMethodID(list_clazz, "add", "(Ljava/lang/Object;)Z"); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); + jclass node_info_clazz = env->FindClass("org/ros2/rcljava/graph/NodeNameInfo"); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); + jmethodID node_info_init_mid = env->GetMethodID(node_info_clazz, "", "()V"); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); + jfieldID name_fid = env->GetFieldID(node_info_clazz, "name", "Ljava/lang/String;"); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); + jfieldID namespace_fid = env->GetFieldID(node_info_clazz, "namespace", "Ljava/lang/String;"); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); + jfieldID enclave_fid = env->GetFieldID(node_info_clazz, "enclave", "Ljava/lang/String;"); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); + + rcl_allocator_t allocator = rcl_get_default_allocator(); + rcutils_string_array_t node_names = rcutils_get_zero_initialized_string_array(); + rcutils_string_array_t node_namespaces = rcutils_get_zero_initialized_string_array(); + rcutils_string_array_t enclaves = rcutils_get_zero_initialized_string_array(); + + rcl_ret_t ret = rcl_get_node_names_with_enclaves( + node, + allocator, + &node_names, + &node_namespaces, + &enclaves); + RCLJAVA_COMMON_THROW_FROM_RCL(env, ret, "rcl_get_node_names_with_enclaves failed"); + + if (node_names.size != node_namespaces.size || node_names.size != enclaves.size) { + rcljava_throw_exception( + env, + "java/lang/IllegalStateException", + "names, namespaces and enclaves array leghts don't match"); + goto cleanup; + } + + for (size_t i = 0; i < node_names.size; i++) { + jstring jnode_name = env->NewStringUTF(node_names.data[i]); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION_WITH_ERROR_STATEMENT(env, goto cleanup); + jstring jnode_namespace = env->NewStringUTF(node_namespaces.data[i]); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION_WITH_ERROR_STATEMENT(env, goto cleanup); + jstring jenclave = env->NewStringUTF(enclaves.data[i]); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION_WITH_ERROR_STATEMENT(env, goto cleanup); + jobject jitem = env->NewObject(node_info_clazz, node_info_init_mid); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION_WITH_ERROR_STATEMENT(env, goto cleanup); + env->SetObjectField(jitem, name_fid, jnode_name); + env->SetObjectField(jitem, namespace_fid, jnode_namespace); + env->SetObjectField(jitem, enclave_fid, jenclave); + env->CallBooleanMethod(jnode_names_info, list_add_mid, jitem); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION_WITH_ERROR_STATEMENT(env, goto cleanup); + } + +cleanup: + ret = rcutils_string_array_fini(&node_names); + if (!env->ExceptionCheck() && RCL_RET_OK != ret) { + rcljava_throw_rclexception(env, ret, "failed to fini node names string array"); + } + ret = rcutils_string_array_fini(&node_namespaces); + if (!env->ExceptionCheck() && RCL_RET_OK != ret) { + rcljava_throw_rclexception(env, ret, "failed to fini node namespaces string array"); + } + ret = rcutils_string_array_fini(&enclaves); + if (!env->ExceptionCheck() && RCL_RET_OK != ret) { + rcljava_throw_rclexception(env, ret, "failed to fini enclaves string array"); + } +} + JNIEXPORT void JNICALL Java_org_ros2_rcljava_node_NodeImpl_nativeGetTopicNamesAndTypes( JNIEnv * env, jclass, jlong handle, jobject jnames_and_types) diff --git a/rcljava/src/main/java/org/ros2/rcljava/graph/NodeNameInfo.java b/rcljava/src/main/java/org/ros2/rcljava/graph/NodeNameInfo.java new file mode 100644 index 00000000..ddd8e2f3 --- /dev/null +++ b/rcljava/src/main/java/org/ros2/rcljava/graph/NodeNameInfo.java @@ -0,0 +1,82 @@ +/* Copyright 2020 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.graph; + +import java.util.Objects; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.ros2.rcljava.common.JNIUtils; + +/** + * Class that represents the queried information of a node in the graph. + */ +public class NodeNameInfo { + /// The node name + public String name; + /// The node namespace + public String namespace; + /// The security enclave of the node. + /** + * For further details, see: + * @{link http://design.ros2.org/articles/ros2_security_enclaves.html} + */ + public String enclave; + + /// Constructor + public NodeNameInfo(final String name, final String namespace, final String enclave) { + this.name = name; + this.namespace = namespace; + this.enclave = enclave; + } + + /// Default constructor, used from jni. + private NodeNameInfo() {} + + /// Used to create a NodeNameInfo object from jni code. + private native final void nativeFromRCL( + long namesHandle, long namespacesHandle, long enclavesHandle); + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof NodeNameInfo)) { + return false; + } + NodeNameInfo other = (NodeNameInfo) o; + return Objects.equals(this.name, other.name) && + Objects.equals(this.namespace, other.namespace) && + Objects.equals(this.enclave, other.enclave); + } + + @Override + public int hashCode() { + return Objects.hash(this.name, this.namespace, this.enclave); + } + + private static final Logger logger = LoggerFactory.getLogger(NodeNameInfo.class); + static { + try { + JNIUtils.loadImplementation(NodeNameInfo.class); + } catch (UnsatisfiedLinkError ule) { + logger.error("Native code library failed to load.\n" + ule); + System.exit(1); + } + } +} diff --git a/rcljava/src/main/java/org/ros2/rcljava/node/Node.java b/rcljava/src/main/java/org/ros2/rcljava/node/Node.java index 42c1281b..e86b3ab5 100644 --- a/rcljava/src/main/java/org/ros2/rcljava/node/Node.java +++ b/rcljava/src/main/java/org/ros2/rcljava/node/Node.java @@ -26,6 +26,7 @@ import org.ros2.rcljava.consumers.TriConsumer; import org.ros2.rcljava.graph.EndpointInfo; import org.ros2.rcljava.graph.NameAndTypes; +import org.ros2.rcljava.graph.NodeNameInfo; import org.ros2.rcljava.interfaces.Disposable; import org.ros2.rcljava.interfaces.MessageDefinition; import org.ros2.rcljava.interfaces.ServiceDefinition; @@ -552,6 +553,12 @@ Client createClient(final Class serviceType, */ rcl_interfaces.msg.ListParametersResult listParameters(List prefixes, long depth); + /** + * Returns a collection of node names that were detected in the ROS graph. + * See @{link NodeNameInfo} for more information about the return value. + */ + Collection getNodeNames(); + /** * Return the topics names and types that were detected in the graph. * See @{link graph#NameAndTypes} for more information about the returned value. diff --git a/rcljava/src/main/java/org/ros2/rcljava/node/NodeImpl.java b/rcljava/src/main/java/org/ros2/rcljava/node/NodeImpl.java index 2736e686..3d5681f0 100644 --- a/rcljava/src/main/java/org/ros2/rcljava/node/NodeImpl.java +++ b/rcljava/src/main/java/org/ros2/rcljava/node/NodeImpl.java @@ -22,6 +22,7 @@ import org.ros2.rcljava.concurrent.Callback; import org.ros2.rcljava.consumers.Consumer; import org.ros2.rcljava.consumers.TriConsumer; +import org.ros2.rcljava.graph.NodeNameInfo; import org.ros2.rcljava.contexts.Context; import org.ros2.rcljava.graph.EndpointInfo; import org.ros2.rcljava.graph.NameAndTypes; @@ -741,6 +742,14 @@ public rcl_interfaces.msg.ListParametersResult listParameters( } } + public final Collection getNodeNames() { + ArrayList nodeNames = new ArrayList(); + nativeGetNodeNames(this.handle, nodeNames); + return nodeNames; + } + + private native static final void nativeGetNodeNames(long handle, ArrayList nodeNames); + public final Collection getTopicNamesAndTypes() { Collection namesAndTypes = new ArrayList(); nativeGetTopicNamesAndTypes(this.handle, namesAndTypes); diff --git a/rcljava/src/test/java/org/ros2/rcljava/node/NodeTest.java b/rcljava/src/test/java/org/ros2/rcljava/node/NodeTest.java index 4ab40171..6ec91f6d 100644 --- a/rcljava/src/test/java/org/ros2/rcljava/node/NodeTest.java +++ b/rcljava/src/test/java/org/ros2/rcljava/node/NodeTest.java @@ -45,6 +45,7 @@ import org.ros2.rcljava.executors.SingleThreadedExecutor; import org.ros2.rcljava.graph.EndpointInfo; import org.ros2.rcljava.graph.NameAndTypes; +import org.ros2.rcljava.graph.NodeNameInfo; import org.ros2.rcljava.node.Node; import org.ros2.rcljava.publisher.Publisher; import org.ros2.rcljava.qos.policies.Reliability; @@ -867,6 +868,64 @@ public Node getNode() { assertEquals(0, subscriptionOne.getHandle()); subscriptionTwo.dispose(); assertEquals(0, subscriptionTwo.getHandle()); + publisherNode.dispose(); + assertEquals(0, publisherNode.getHandle()); + subscriptionNodeOne.dispose(); + assertEquals(0, subscriptionNodeOne.getHandle()); + subscriptionNodeTwo.dispose(); + assertEquals(0, subscriptionNodeTwo.getHandle()); + } + + @Test + public final void testGetNodeNames() throws Exception { + final Node node1 = RCLJava.createNode("test_get_node_names_1"); + final Node node2 = RCLJava.createNode("test_get_node_names_2"); + final Node node3 = RCLJava.createNode("test_get_node_names_3"); + + Consumer> validateNodeNameInfo = + new Consumer>() { + public void accept(final Collection nodeNamesInfo) { + assertEquals(4, nodeNamesInfo.size()); + assertTrue( + "node 'test_node' was not discovered", + nodeNamesInfo.contains(new NodeNameInfo("test_node", "/", "/"))); + assertTrue( + "node 'test_get_node_names_1' was not discovered", + nodeNamesInfo.contains(new NodeNameInfo("test_get_node_names_1", "/", "/"))); + assertTrue( + "node 'test_get_node_names_2' was not discovered", + nodeNamesInfo.contains(new NodeNameInfo("test_get_node_names_1", "/", "/"))); + assertTrue( + "node 'test_get_node_names_3' was not discovered", + nodeNamesInfo.contains(new NodeNameInfo("test_get_node_names_1", "/", "/"))); + } + }; + + long start = System.currentTimeMillis(); + boolean ok = false; + Collection nodeNamesInfo = null; + do { + nodeNamesInfo = this.node.getNodeNames(); + try { + validateNodeNameInfo.accept(nodeNamesInfo); + ok = true; + } catch (AssertionError err) { + // ignore here, it's going to be validated again at the end. + } + // TODO(ivanpauno): We could wait for the graph guard condition to be triggered if that + // would be available. + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException err) { + // ignore + } + } while (!ok && System.currentTimeMillis() < start + 1000); + assertNotNull(nodeNamesInfo); + validateNodeNameInfo.accept(nodeNamesInfo); + + node1.dispose(); + node2.dispose(); + node3.dispose(); } @Test From 8734ea82b61fac64d1656169862cfc0577d6d879 Mon Sep 17 00:00:00 2001 From: Ivan Santiago Paunovic Date: Wed, 16 Sep 2020 10:03:32 -0300 Subject: [PATCH 2/4] Delete unneeded code Signed-off-by: Ivan Santiago Paunovic --- rcljava/CMakeLists.txt | 1 - .../org_ros2_rcljava_graph_NodeNameInfo.cpp | 51 ------------------- .../org/ros2/rcljava/graph/NodeNameInfo.java | 18 +------ 3 files changed, 2 insertions(+), 68 deletions(-) delete mode 100644 rcljava/src/main/cpp/org_ros2_rcljava_graph_NodeNameInfo.cpp diff --git a/rcljava/CMakeLists.txt b/rcljava/CMakeLists.txt index c4e06cc1..afa2836b 100644 --- a/rcljava/CMakeLists.txt +++ b/rcljava/CMakeLists.txt @@ -62,7 +62,6 @@ set(${PROJECT_NAME}_jni_sources "src/main/cpp/org_ros2_rcljava_executors_BaseExecutor.cpp" "src/main/cpp/org_ros2_rcljava_events_EventHandlerImpl.cpp" "src/main/cpp/org_ros2_rcljava_graph_EndpointInfo" - "src/main/cpp/org_ros2_rcljava_graph_NodeNameInfo.cpp" "src/main/cpp/org_ros2_rcljava_publisher_statuses_LivelinessLost.cpp" "src/main/cpp/org_ros2_rcljava_publisher_statuses_OfferedDeadlineMissed.cpp" "src/main/cpp/org_ros2_rcljava_publisher_statuses_OfferedQosIncompatible.cpp" diff --git a/rcljava/src/main/cpp/org_ros2_rcljava_graph_NodeNameInfo.cpp b/rcljava/src/main/cpp/org_ros2_rcljava_graph_NodeNameInfo.cpp deleted file mode 100644 index 11c03f60..00000000 --- a/rcljava/src/main/cpp/org_ros2_rcljava_graph_NodeNameInfo.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2020 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. - -#include "org_ros2_rcljava_graph_NodeNameInfo.h" - -#include -#include - -#include "rcl/graph.h" -#include "rcljava_common/exceptions.hpp" - -using rcljava_common::exceptions::rcljava_throw_exception; - -JNIEXPORT void JNICALL -JNICALL Java_org_ros2_rcljava_graph_NodeName_nativeFromRCL( - JNIEnv * env, jobject self, jlong name_handle, jlong namespace_handle, jlong enclave_handle) -{ - const char * name = reinterpret_cast(name_handle); - const char * n_namespace = reinterpret_cast(namespace_handle); - const char * enclave = reinterpret_cast(enclave_handle); - - jclass clazz = env->GetObjectClass(self); - jfieldID name_fid = env->GetFieldID(clazz, "name", "Ljava/langString;"); - RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); - jfieldID namespace_fid = env->GetFieldID(clazz, "namespace", "Ljava/langString;"); - RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); - jfieldID enclave_fid = env->GetFieldID(clazz, "enclave", "Ljava/langString;"); - RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); - - jstring jname = env->NewStringUTF(name); - RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); - jstring jnamespace = env->NewStringUTF(n_namespace); - RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); - jstring jenclave = env->NewStringUTF(enclave); - RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); - - env->SetObjectField(self, name_fid, jname); - env->SetObjectField(self, namespace_fid, jnamespace); - env->SetObjectField(self, enclave_fid, jenclave); -} diff --git a/rcljava/src/main/java/org/ros2/rcljava/graph/NodeNameInfo.java b/rcljava/src/main/java/org/ros2/rcljava/graph/NodeNameInfo.java index ddd8e2f3..2cd29806 100644 --- a/rcljava/src/main/java/org/ros2/rcljava/graph/NodeNameInfo.java +++ b/rcljava/src/main/java/org/ros2/rcljava/graph/NodeNameInfo.java @@ -47,17 +47,13 @@ public NodeNameInfo(final String name, final String namespace, final String encl /// Default constructor, used from jni. private NodeNameInfo() {} - /// Used to create a NodeNameInfo object from jni code. - private native final void nativeFromRCL( - long namesHandle, long namespacesHandle, long enclavesHandle); - @Override public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof NodeNameInfo)) { - return false; + return false; } NodeNameInfo other = (NodeNameInfo) o; return Objects.equals(this.name, other.name) && @@ -67,16 +63,6 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(this.name, this.namespace, this.enclave); - } - - private static final Logger logger = LoggerFactory.getLogger(NodeNameInfo.class); - static { - try { - JNIUtils.loadImplementation(NodeNameInfo.class); - } catch (UnsatisfiedLinkError ule) { - logger.error("Native code library failed to load.\n" + ule); - System.exit(1); - } + return Objects.hash(this.name, this.namespace, this.enclave); } } From 51de623a8da281d95951795ac0af9be48fc23bf6 Mon Sep 17 00:00:00 2001 From: Ivan Santiago Paunovic Date: Wed, 16 Sep 2020 10:06:26 -0300 Subject: [PATCH 3/4] Delete more code Signed-off-by: Ivan Santiago Paunovic --- .../org_ros2_rcljava_graph_NodeNameInfo.h | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 rcljava/include/org_ros2_rcljava_graph_NodeNameInfo.h diff --git a/rcljava/include/org_ros2_rcljava_graph_NodeNameInfo.h b/rcljava/include/org_ros2_rcljava_graph_NodeNameInfo.h deleted file mode 100644 index 45886b26..00000000 --- a/rcljava/include/org_ros2_rcljava_graph_NodeNameInfo.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 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. - -#include -/* Header for class org_ros2_rcljava_graph_NodeName */ - -#ifndef ORG_ROS2_RCLJAVA_GRAPH_NODENAMEINFO_H_ -#define ORG_ROS2_RCLJAVA_GRAPH_NODENAMEINFO_H_ -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_ros2_rcljava_graph_NodeName - * Method: nativeFromRCL - * Signature: (J)V - */ -JNIEXPORT void -JNICALL Java_org_ros2_rcljava_graph_NodeName_nativeFromRCL( - JNIEnv *, jobject, jlong, jlong, jlong); - -#ifdef __cplusplus -} -#endif -#endif // ORG_ROS2_RCLJAVA_GRAPH_NODENAMEINFO_H_ From 5af448a6c06d3282acaaf24b1fe8b2a38fe924a8 Mon Sep 17 00:00:00 2001 From: Ivan Santiago Paunovic Date: Wed, 16 Sep 2020 10:16:42 -0300 Subject: [PATCH 4/4] Use rcpputils::scope_exit Signed-off-by: Ivan Santiago Paunovic --- .../cpp/org_ros2_rcljava_node_NodeImpl.cpp | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/rcljava/src/main/cpp/org_ros2_rcljava_node_NodeImpl.cpp b/rcljava/src/main/cpp/org_ros2_rcljava_node_NodeImpl.cpp index 937a53e6..e9b8378b 100644 --- a/rcljava/src/main/cpp/org_ros2_rcljava_node_NodeImpl.cpp +++ b/rcljava/src/main/cpp/org_ros2_rcljava_node_NodeImpl.cpp @@ -290,43 +290,45 @@ Java_org_ros2_rcljava_node_NodeImpl_nativeGetNodeNames( &node_namespaces, &enclaves); RCLJAVA_COMMON_THROW_FROM_RCL(env, ret, "rcl_get_node_names_with_enclaves failed"); + auto on_scope_exit = rcpputils::make_scope_exit( + [pnames = &node_names, pnamespaces = &node_namespaces, penclaves = &enclaves, env]() { + rcl_ret_t ret = rcutils_string_array_fini(pnames); + if (!env->ExceptionCheck() && RCL_RET_OK != ret) { + rcljava_throw_rclexception(env, ret, "failed to fini node names string array"); + } + ret = rcutils_string_array_fini(pnamespaces); + if (!env->ExceptionCheck() && RCL_RET_OK != ret) { + rcljava_throw_rclexception(env, ret, "failed to fini node namespaces string array"); + } + ret = rcutils_string_array_fini(penclaves); + if (!env->ExceptionCheck() && RCL_RET_OK != ret) { + rcljava_throw_rclexception(env, ret, "failed to fini enclaves string array"); + } + } + ); if (node_names.size != node_namespaces.size || node_names.size != enclaves.size) { rcljava_throw_exception( env, "java/lang/IllegalStateException", "names, namespaces and enclaves array leghts don't match"); - goto cleanup; + return; } for (size_t i = 0; i < node_names.size; i++) { jstring jnode_name = env->NewStringUTF(node_names.data[i]); - RCLJAVA_COMMON_CHECK_FOR_EXCEPTION_WITH_ERROR_STATEMENT(env, goto cleanup); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); jstring jnode_namespace = env->NewStringUTF(node_namespaces.data[i]); - RCLJAVA_COMMON_CHECK_FOR_EXCEPTION_WITH_ERROR_STATEMENT(env, goto cleanup); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); jstring jenclave = env->NewStringUTF(enclaves.data[i]); - RCLJAVA_COMMON_CHECK_FOR_EXCEPTION_WITH_ERROR_STATEMENT(env, goto cleanup); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); jobject jitem = env->NewObject(node_info_clazz, node_info_init_mid); - RCLJAVA_COMMON_CHECK_FOR_EXCEPTION_WITH_ERROR_STATEMENT(env, goto cleanup); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); env->SetObjectField(jitem, name_fid, jnode_name); env->SetObjectField(jitem, namespace_fid, jnode_namespace); env->SetObjectField(jitem, enclave_fid, jenclave); env->CallBooleanMethod(jnode_names_info, list_add_mid, jitem); - RCLJAVA_COMMON_CHECK_FOR_EXCEPTION_WITH_ERROR_STATEMENT(env, goto cleanup); - } - -cleanup: - ret = rcutils_string_array_fini(&node_names); - if (!env->ExceptionCheck() && RCL_RET_OK != ret) { - rcljava_throw_rclexception(env, ret, "failed to fini node names string array"); - } - ret = rcutils_string_array_fini(&node_namespaces); - if (!env->ExceptionCheck() && RCL_RET_OK != ret) { - rcljava_throw_rclexception(env, ret, "failed to fini node namespaces string array"); - } - ret = rcutils_string_array_fini(&enclaves); - if (!env->ExceptionCheck() && RCL_RET_OK != ret) { - rcljava_throw_rclexception(env, ret, "failed to fini enclaves string array"); + RCLJAVA_COMMON_CHECK_FOR_EXCEPTION(env); } }