From 74cf880a62d7dc9b17111330c99ef230e58b12f6 Mon Sep 17 00:00:00 2001 From: Fred Hornsey Date: Fri, 10 May 2024 03:42:53 -0500 Subject: [PATCH] Try to Avoid Missing Functions Issue on Windows Also: - Make @hidden_op_in_java smarter so it doesn't require a argument for C++ code (thought it needs on because of IDL). - Explicitly call Perl on Windows in Java build so it doesn't require the file association to be set. - Add news. --- MPC/config/optional_jni_check.mpb | 2 +- dds/DdsDcpsTopic.idl | 6 +- dds/idl/IDLTemplate.txt | 9 +-- dds/idl/be_init.cpp | 2 +- docs/news.d/create-sample.rst | 6 ++ java/idl2jni/codegen/be_init.cpp | 6 +- java/idl2jni/codegen/idl_mapping.cpp | 9 +-- java/idl2jni/codegen/idl_mapping.h | 2 +- java/idl2jni/codegen/im_jni.cpp | 89 ++++++++++++++++------------ 9 files changed, 72 insertions(+), 59 deletions(-) create mode 100644 docs/news.d/create-sample.rst diff --git a/MPC/config/optional_jni_check.mpb b/MPC/config/optional_jni_check.mpb index 8889d5a01d0..c5e6d341425 100644 --- a/MPC/config/optional_jni_check.mpb +++ b/MPC/config/optional_jni_check.mpb @@ -1,6 +1,6 @@ feature(jni_check) { - postbuild += $(DDS_ROOT)<%slash%>java<%slash%>build_scripts<%slash%>jni_check.pl <%libout%><%slash%><%sharedname%> + postbuild += perl $(DDS_ROOT)<%slash%>java<%slash%>build_scripts<%slash%>jni_check.pl <%libout%><%slash%><%sharedname%> } diff --git a/dds/DdsDcpsTopic.idl b/dds/DdsDcpsTopic.idl index 0a6693b1f43..822711b26a2 100644 --- a/dds/DdsDcpsTopic.idl +++ b/dds/DdsDcpsTopic.idl @@ -71,10 +71,8 @@ module DDS { in string type_name); string get_type_name(); #ifndef OPENDDS_SAFETY_PROFILE - // valuetype isn't supported in Java. This will exclude this operation - // from the generated Java code and return null in get_type method of - // the TAOPeer generated C++ class so it isn't a pure virtual function. - @OpenDDS::internal::hidden_op_in_java("return 0;") + // TODO: valuetype isn't supported in Java + @OpenDDS::internal::hidden_op_in_java(0) DynamicType get_type(); #endif }; diff --git a/dds/idl/IDLTemplate.txt b/dds/idl/IDLTemplate.txt index 6f1f26b68e8..2e94f4742e0 100644 --- a/dds/idl/IDLTemplate.txt +++ b/dds/idl/IDLTemplate.txt @@ -10,13 +10,10 @@ typedef sequence<<%SCOPED%>> <%TYPE%><%SEQ%>; */ local interface <%TYPE%>TypeSupport : OpenDDS::DCPS::TypeSupport { #ifndef OPENDDS_SAFETY_PROFILE - // valuetype isn't supported in Java, so we can't use DynamicData. This - // will exclude this operation from the generated Java code and return null - // in get_type method of the TAOPeer generated C++ class so it isn't a pure - // virtual function. - @OpenDDS::internal::hidden_op_in_java("(void)(src); return 0;") + // TODO: valuetype isn't supported in Java. + @OpenDDS::internal::hidden_op_in_java(0) <%SCOPED%> create_sample(in ::DDS::DynamicData src); - @OpenDDS::internal::hidden_op_in_java("(void)(src); return 0;") + @OpenDDS::internal::hidden_op_in_java(0) ::DDS::DynamicData create_dynamic_sample(in <%SCOPED%> src); #endif diff --git a/dds/idl/be_init.cpp b/dds/idl/be_init.cpp index dc2b9a95bb2..f9c8b324635 100644 --- a/dds/idl/be_init.cpp +++ b/dds/idl/be_init.cpp @@ -65,5 +65,5 @@ BE_post_init(char*[], long) // This annotation isn't used, but must match the one in idl2jni to avoid // warnings or errors. idl_global->eval( - "module OpenDDS {module internal {@annotation hidden_op_in_java {string impl;};};};\n"); + "module OpenDDS {module internal {@annotation hidden_op_in_java {int8 dummy;};};};\n"); } diff --git a/docs/news.d/create-sample.rst b/docs/news.d/create-sample.rst new file mode 100644 index 00000000000..9cb0dd8ecb3 --- /dev/null +++ b/docs/news.d/create-sample.rst @@ -0,0 +1,6 @@ +.. news-prs: 4373 + +.. news-start-section: Additions +- Implemented the ``create_dynamic_sample`` and ``create_sample`` methods on ``TypeSupport`` to convert samples to and from ``DynamicData``. + Also documented the existing ``DynamicDataAdaptor`` class for wrapping IDL-generated types in a ``DynamicData``. +.. news-end-section diff --git a/java/idl2jni/codegen/be_init.cpp b/java/idl2jni/codegen/be_init.cpp index 171d1f1e54a..a7ccfa6ce61 100644 --- a/java/idl2jni/codegen/be_init.cpp +++ b/java/idl2jni/codegen/be_init.cpp @@ -41,7 +41,9 @@ BE_post_init(char *[], long) DRV_cpp_putarg("-D__OPENDDS_IDL_HAS_ANNOTATIONS"); DRV_cpp_putarg("-DOPENDDS_HIDE_DYNAMIC_DATA"); - // If adding or changing annotations here, they should also be copied into opendds_idl + // If adding or changing annotations here, they should also be copied into + // opendds_idl. dummy is there because IDL annotations can't be used before a + // scoped name starting with :: unless they have annotation parameters. idl_global->eval( - "module OpenDDS {module internal {@annotation hidden_op_in_java {string impl;};};};\n"); + "module OpenDDS {module internal {@annotation hidden_op_in_java {int8 dummy;};};};\n"); } diff --git a/java/idl2jni/codegen/idl_mapping.cpp b/java/idl2jni/codegen/idl_mapping.cpp index e753aff75a6..37eb3ebcc20 100644 --- a/java/idl2jni/codegen/idl_mapping.cpp +++ b/java/idl2jni/codegen/idl_mapping.cpp @@ -137,12 +137,7 @@ bool composite_mapping::gen_union(UTL_ScopedName *name, return true; } -bool is_hidden_op_in_java(AST_Operation* op, std::string* impl) +bool is_hidden_op_in_java(AST_Operation* op) { - AST_Annotation_Appl* a = op->annotations().find("::OpenDDS::internal::@hidden_op_in_java"); - if (a && impl) { - *impl = dynamic_cast((*a)["impl"])-> - value()->ev()->u.strval->get_string(); - } - return a; + return op->annotations().find("::OpenDDS::internal::@hidden_op_in_java"); } diff --git a/java/idl2jni/codegen/idl_mapping.h b/java/idl2jni/codegen/idl_mapping.h index 80e1a7ac2d5..60eee06f2ac 100644 --- a/java/idl2jni/codegen/idl_mapping.h +++ b/java/idl2jni/codegen/idl_mapping.h @@ -164,6 +164,6 @@ class idl_mapping_jni : public idl_mapping { bool sequence, const std::string &length, bool elementIsObjref = false); }; -bool is_hidden_op_in_java(AST_Operation* op, std::string* impl = 0); +bool is_hidden_op_in_java(AST_Operation* op); #endif diff --git a/java/idl2jni/codegen/im_jni.cpp b/java/idl2jni/codegen/im_jni.cpp index 464c5a690fd..415bb0f973e 100644 --- a/java/idl2jni/codegen/im_jni.cpp +++ b/java/idl2jni/codegen/im_jni.cpp @@ -1300,12 +1300,12 @@ void write_native_operation(UTL_ScopedName *name, const char *javaStub, { const char *opname = op->local_name()->get_string(); string ret = "void", - cxx = idl_mapping_jni::scoped(name), - fnName = jni_function_name(javaStub, opname), - retval, retconv, ret_exception; - //for the JavaPeer (local interfaces only) + cxx = idl_mapping_jni::scoped(name), + fnName = jni_function_name(javaStub, opname), + retval, retconv, ret_exception; + // for the JavaPeer (local interfaces only) string ret_jsig = "V", jniFn = "Void", tao_ret = "void", - tao_retval, tao_retconv, array_cast; + tao_retval, tao_retconv, array_cast; if (!op->void_return_type()) { ret = idl_mapping_jni::type(op->return_type()); @@ -1356,6 +1356,8 @@ void write_native_operation(UTL_ScopedName *name, const char *javaStub, } } + const bool hidden = is_hidden_op_in_java(op); + //for the JavaPeer (local interfaces only) string tao_args, java_args, args_jsig, tao_argconv_in, tao_argconv_out; @@ -1367,17 +1369,23 @@ void write_native_operation(UTL_ScopedName *name, const char *javaStub, AST_Decl *item = it.item(); if (item->node_type() == AST_Decl::NT_argument) { - AST_Argument *arg = dynamic_cast(item); - const char *argname = arg->local_name()->get_string(); - bool in = arg->direction() == AST_Argument::dir_IN; - args += ", " + (in ? idl_mapping_jni::type(arg->field_type()) - : "jobject") - + ' ' + argname; + AST_Argument* const arg = dynamic_cast(item); + const char* const argname = arg->local_name()->get_string(); + const bool in = arg->direction() == AST_Argument::dir_IN; + + args += ", " + (in ? idl_mapping_jni::type(arg->field_type()) : "jobject"); + if (!hidden) { + args += std::string(" ") + argname; + } - if (tao_args != "") tao_args += ", "; + if (!tao_args.empty()) { + tao_args.append(", "); + } + tao_args += idl_mapping_jni::taoParam(arg->field_type(), arg->direction()); + if (!hidden) { + tao_args += std::string(" ") + argname; + } - tao_args += idl_mapping_jni::taoParam(arg->field_type(), - arg->direction()) + ' ' + argname; args_jsig += in ? idl_mapping_jni::jvmSignature(arg->field_type()) : "L" + idl_mapping::scoped_helper(arg->field_type()->name(), @@ -1409,9 +1417,8 @@ void write_native_operation(UTL_ScopedName *name, const char *javaStub, idl_mapping_jni::scoped_helper(name, "_") << "JavaPeer::" << opname_cxx << " (" << tao_args << ")\n" "{\n"; - std::string hidden_impl; - if (is_hidden_op_in_java(op, &hidden_impl)) { - be_global->stub_impl_ << " " << hidden_impl << "\n"; + if (hidden) { + be_global->stub_impl_ << ret_exception; } else { be_global->stub_impl_ << " JNIThreadAttacher _jta (jvm_, cl_);\n" @@ -1433,26 +1440,34 @@ void write_native_operation(UTL_ScopedName *name, const char *javaStub, } be_global->stub_impl_ << - "extern \"C\" JNIEXPORT " << ret << " JNICALL\n" << - fnName << " (JNIEnv *_jni, jobject _jthis" << args << ")\n" - "{\n" - " CORBA::Object_ptr _this_obj = recoverTaoObject (_jni, _jthis);\n" - " try\n" - " {\n" - " " << cxx << "_var _this = " << cxx << "::_narrow (_this_obj);\n" - << argconv_in << - " " << retval << "_this->" << (isCxxKeyword(opname) ? "_cxx_" : "") - << opname << " (" << cxx_args << ");\n" - << argconv_out - << retconv << - //FUTURE: catch declared user exceptions - " }\n" - " catch (const CORBA::SystemException &_se)\n" - " {\n" - " throw_java_exception (_jni, _se);\n" - " }\n" - << ret_exception << - "}\n\n"; + "extern \"C\" JNIEXPORT " << ret << " JNICALL\n" << + fnName << "(JNIEnv* _jni, jobject _jthis" << args << ")\n" + "{\n"; + if (hidden) { + be_global->stub_impl_ << + " (void)_jni;\n" + " (void)_jthis;\n"; + } else { + be_global->stub_impl_ << + " CORBA::Object_ptr _this_obj = recoverTaoObject (_jni, _jthis);\n" + " try\n" + " {\n" + " " << cxx << "_var _this = " << cxx << "::_narrow (_this_obj);\n" + << argconv_in << + " " << retval << "_this->" << (isCxxKeyword(opname) ? "_cxx_" : "") + << opname << " (" << cxx_args << ");\n" + << argconv_out + << retconv << + // FUTURE: catch declared user exceptions + " }\n" + " catch (const CORBA::SystemException &_se)\n" + " {\n" + " throw_java_exception (_jni, _se);\n" + " }\n"; + } + be_global->stub_impl_ + << ret_exception + << "}\n\n"; } void recursive_bases(AST_Interface *interf, set &bases,