Re: Patch for pjsua2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Christian,

Unfortunately both options are still not ideal :)

To make all generated Java methods to throw exceptions may require a
lot of changes in existing PJSIP Java apps, which is of course
undesirable.

We still prefer the idea of replacing throw() with PJ_THROW(), which
will translate to no-op for C/C++ and throw() for SWIG. This way,
backward incompatibility is minimized while full feature is
maintained.

Best regards,
Ming

On Wed, Oct 17, 2018 at 4:46 AM, Christian Hoff <christian_hoff@xxxxxxx> wrote:
> I am fordwarding this mail to the mailing list as well.
>
>
> On 16/10/18 22:42, Christian Hoff wrote:
>
> Hello Ming,
>
> you are absolutely right and I am sorry for the confusion. Of course the
> SWIG Java bindings throw "java.lang.Exception" and not the
> "RuntimeException" as I assumed.
>
> You actually discovered a bug in my patch. The problem with my patch is that
> I am throwing a java.lang.Exception from the Java JNI code, but this
> Exception is now no longer mentioned in the "throws" specification of the
> Java methods generated by SWIG - even though it is a checked exception. In
> fact my change (unintentionally) removed the "throw" specification also on
> the Java side! For this reason you no longer get compile errors when
> omitting the "catch" blocks in your sample code. This is a bug. Because the
> Exception is thrown from JNI C++ code, Java cannot find out that the
> generated C++ JNI code is actually violating the Java exception
> specification of the generated method (which declares that no checked
> exceptions should be thrown).
>
> After some reading of the SWIG documentation, I found out that there is a
> relatively simple way to fix this issue and to restore the "throw"
> specification on the Java side. To do this, please replace the line no. 50
> in file "pjsip-apps/src/swig/pj_error.i" by
>
>   %javaexception("java.lang.Exception") {
>
> This should restore the "throw" specification for all PJSIP Java methods. I
> tested this briefly and it works. One possible downside of this change is
> however that this change will add a "throw Exception" specification to all
> generated Java methods inside PJSIP, so every PJSIP Java generated method
> now explicitly throws java.lang.Exception. This could be an issue if there
> are some PJSIP methods that cannot throw "pj::Error". In this case the user
> has to handle an exception that can never occur. However I am not even sure
> if such methods exist.
>
> Another option would be throw non-checked exceptions - such as
> RuntimeException - from the PJSIP Java bindings. But I think you like the
> idea of exception specifications and checked exceptions and therefore
> probably the first option will be the better one. As I said, the fix works
> by just changing a single line.
>
>
> Best regards,
>
>    Christian
>
>
> On 16/10/18 11:24, Ming wrote:
>
> Hi Christian,
>
> Thanks for your detailed explanation, which I'm sure help us
> (especially me) improve our knowledge about Java.
>
> After checking the code (in pjsua2.i), our current exception actually
> uses java.lang.Exception, which, according to the reference below,
> belongs to checked exceptions. I verified this by trying to compile
> our sample code and remove a try-catch block and it did fail to
> compile.
>
> Ref: https://www.geeksforgeeks.org/checked-vs-unchecked-exceptions-in-java/
>
> Best regards,
> Ming
>
> On Tue, Oct 16, 2018 at 2:45 PM, Christian Hoff <christian_hoff@xxxxxxx>
> wrote:
>
> Hello Ming,
>
> thank you very much for your quick feedback and I am happy to hear that the
> propagation of exceptions works well with my patch!
>
> Regarding your point about exceptions and thr "throw (...)" specification:
> You are right in saying that an exception specification is still an
> important in programming languages such as Java. However in Java two kinds
> of exceptions exist and only one kind of them (the checked exception) works
> with exception specifications:
>
> Checked exceptions. Checked exceptions are the kind of exceptions that you
> are talking about, where the programmer is forced to somehow handle the
> exception. Handling the exception can mean either installing a catch handler
> or adding this exception type to the "throws" declaration of your method. If
> the exception is not handled, a compile error will be generated - as you
> wrote.
> Unchecked exceptions. Unchecked exceptions are the kind of exceptions that
> the programmer is not forced to handle. For this kind of exception, the
> programmer is not forced to install a "catch" handler, so no compile error
> will be generated if the exception is not handled at all. Such exceptions
> also do not appear in the "throws" declaration of the methods. Unchecked
> exceptions are all exceptions that derive from the RuntimeException and
> Error classes.
>
> For PJSIP a "pj::Error" was mapped to a RuntimeException up to now (already
> before my changes), so a "pj::Error" from the C++ PJSIP library raises an
> unchecked exception. This is true before and after my changes. This means
> that - as of now - a Java programmer is not forced to handle a "pj::Error"
> from the C++ code. This is because the "pj::Error" will be mapped to an
> unchecked exception. The consequence is that there is no compile error if
> the user forgets to install a catch handler on the Java side for errors from
> PJSIP. The exception for the "pj::Error" also does not appear in the
> "throws" declaration of the Java methods generated by SWIG as only checked
> exceptions should appear there, but not unchecked exceptions such as
> "RuntimeException".
>
> What I want to say in short is that my patch does not change anything in
> terms of exception handling on the Java side. The old behaviour was already
> to throw an unchecked exception that the user was not required to catch and
> the new approach is the same. And already before my changes we were not
> using exception specifications on the Java side as we were using unchecked
> exceptions. Or have I missed or overlooked something?
>
> What we might want to consider for the PJSIP Java bindings is to change the
> exception handling there to throw checked exceptions if a "pj::Error" is
> thrown from the C++ code, in order to force users to handle a "pj::Error".
> But this is more or less a separate change that does not really have
> anything to do with my changes.
>
> Thanks again for the quick testing and the quick feedback!
>
>
> Have a nice day and best regards,
>
>     Christian
>
>
> On 16/10/18 06:31, Ming wrote:
>
> Hi Christian,
>
> I did some testing here and the exception does work great during runtime
> now!
>
> However, in my opinion, the "throw()" specification is still important
> for SWIG. While it's true that throw() is deprecated for C++, it
> remains a valid (and important) part of other languages such as Java.
> And having throw() in the declaration of the function will help the
> programmers during the development process.
>
> For example, if you try to call a function which throws an exception
> in Java but forget to put try and catch, the compiler will give an
> error such as:
> sample.java:155: error: unreported exception Exception; must be caught
> or declared to be thrown
>
> But it's now gone, so the developer must now carefully check each
> function in order to know whether it can throw an exception.
>
> Best regards,
> Ming
>
> On Mon, Oct 15, 2018 at 10:18 AM, Ming <ming@xxxxxxxxx> wrote:
>
> Hi Christian,
>
> Thank you for the hard work. Let us review and test this. Given the
> scale of the platforms and language binding affected, this may take
> some time. We will update you again.
>
> Best regards,
> Ming
>
>
> On Mon, Oct 15, 2018 at 4:19 AM, Christian Hoff <christian_hoff@xxxxxxx>
> wrote:
>
> Hello all,
>
> during the last weeks, I worked hard on the patch for PJSUA2 and C++ 17
> compatibility again. For those who have forgotten: Currently the PJSUA2
> headers cannot be compiled with C++ 17 because C++ 17 removes support for
> exception specifications. But unfortunately PJSUA2 makes have use of
> exception specifications.
>
> The open issue with my last patch was that SWIG no longer generates catch
> handlers that catch "pj::Error", as Ming pointed out. I have now updated the
> patch so that SWIG also generates the required catch handlers. Doing so has
> been a quite difficult, tedious and time-consuming task. But finally I am
> done and I am happy to share the resulting patch for inclusion into pjsip.
> The updated patch is attached to this mail.
>
> The magic on the SWIG side is done with the "%exception" directive, which
> installs a default global exception handler. In my updated patch, I am now
> using this "%exception" directive to generate the catch handler for
> "pj::Error" (see the new file "pjsip-apps/src/swig/pj_error.i"). The
> rationale behind this was that I really wanted to remove all the "throw
> (pj::Error)" from the header files, so I did not want to have a "PJ_THROW"
> that would expand to nothing during the compile and expand to the old "throw
> (...)" when using SWIG. "throw (...)" is now deprecated syntax and we should
> not keep it around for the sake of SWIG in my opinion.
>
> Some basic testing was also done:
>
> To verify the C++ 17 compatibility, I compiled my application with the
> installed adopted pjsua2 header files.
> To verify the generated SWIG language bindings and catch handlers:
>
> For the Python language binding, I verified that the compile works.
> Afterwards I installed the generated language binding and ran the test file
> "test.py". "test.py" also verifies the exception handling. I also inspected
> the generated catch handlers for pj::Error visually.
> For the Java and C# bindings, I verified that the compile works and
> inspected the generated catch handlers visually. Unfortunately I did not
> find a suitable unit test for the exception handling, but I am optimistic
> that it works nevertheless. I could not run the generated code for the C#
> bindings because I do not have Xamarin installed on my machine. But as I
> said, at least I can compile the C++ wrapper code for C#.
>
> I hope that this patch can now be considered for inclusion into PJSIP.
>
>
> Best regards,
>
>     Christian
>
>
> On 25/09/18 10:26, Max Truxa wrote:
>
> Hello Christian,
>
> how about replacing the throw specifications with a macro that expands
> to nothing when compiling as C++ but `throw(Error)` when being parsed
> by SWIG?
>
> Something like this:
>
> #ifdef SWIG // defined if SWIG is parsing the file
> #   define PJ_CAN_THROW     throw(Error)
> #else
> #   define PJ_CAN_THROW
> #endif
>
> struct Foo
> {
>     void bar() PJ_CAN_THROW;
> };
>
> Regards,
>
> - Max
>
> On Tue, Sep 25, 2018 at 8:30 AM Christian Hoff <christian_hoff@xxxxxxx>
> wrote:
>
> Hello Ming,
>
> this is also an interesting idea. But will this actually work..? I am
> wondering because SWIG only parses the header files of PJSUA2. However
> the actual function implementation is in the ".cpp" source files and in
> these files you can find the code that throws the exceptions and that
> could use "PJ_THROW()". But to my knowledge SWIG does not parse the
> source files and would thus not know which functions may call
> "PJ_THROW". Or am I wrong about this?
>
>
> Best regards,
>
>     Christian
>
>
> On 25/09/18 03:08, Ming wrote:
>
> Hi Christian,
>
> We haven't found a good way either. Our idea is to put PJ_THROW()
> macro to replace throw(), which can somehow be used by SWIG to
> generate the exception specs.
>
> Regards,
> Ming
> On Tue, Sep 25, 2018 at 4:21 AM Christian Hoff <christian_hoff@xxxxxxx>
> wrote:
>
> Hello Ming and all,
>
> I have now done some research into SWIG and exceptions. After reading
> the SWIG documentation, I found out that SWIG indeed parses the C++
> exception specification to figure out for what types of exceptions
> "catch(..)" should be generated (see
> http://www.swig.org/Doc3.0/SWIGDocumentation.html#SWIGPlus_exception_specifications
> ). Exception types that are specified in the exception specification are
> automatically propagated to the higher language (Java, C# etc.). Now
> that we need to remove the exception specification, we lose that
> capability. Thanks to Ming for the hint. However there is the
> possibility to adapt the SWIG interface file
> ("pjsip-apps/src/swig/pjsua2.i") and to add explicit "%catches"
> statements for each method that describe which types of exceptions the
> method could possibility throw. So I guess I need to rework my patch for
> this. I just hope that I will find some way to avoid having to annotate
> every method with "%catches".... I'll see. Or if someone knows how to do
> it, then I would be very grateful for a reply.
>
>
> Best regards,
>
>       Christian
>
>
> On 24/09/18 12:43, Christian Hoff wrote:
>
> Hello Ming,
>
> thanks for your reply! I will have a look into the SWIG topic this
> evening and will let you know my findings.
>
>
> Best regards,
>
>     Christian
>
>
> On 24/09/18 09:03, Ming wrote:
>
> Hi Christian,
>
> We apologize for the delay in response. We're currently reviewing it
> and have also managed to do some testing. While for C/C++, this seems
> to be okay, we're still considering how to best handle this for our
> Android and Java (via SWIG binding), which may still need the "throw"
> specifications in order for the developers to know that the functions
> may throw some exceptions.
>
> If you have any feedback regarding this, please let us know.
>
> Best regards,
> Ming
>
> On Mon, Sep 24, 2018 at 2:32 PM Christian Hoff
> <christian_hoff@xxxxxxx> wrote:
>
> Hello all,
>
> some feedback for this patch is still appreciated. In general I am
> getting somewhat frustrated about the collaboration with people who
> want
> to contribute to the project. Already in the past other people have
> posted patches here to this list, but did not get any response - not
> even a response what needs to be changed for the patch to be
> accepted. I
> think this is not a good mode of collaboration. Everyone who posts a
> patch here to this mailing list has done this with the intention to
> help
> the project PJSIP to move along (and has spent much time developing the
> patch), so you should at least return the favour and review the patch.
>
> This particular issue that I am trying to address with my patch (that
> the PJSUA2 headers don't compile against C++17) is an issue that you
> will eventually need to fix anyhow, so why not fix it right now? As of
> now, modern versions of GCC use C++ 14 by default, it is only a matter
> of time until C++ 17 will become the default and people will start
> complaining that there are compile errors from the PJSUA2 headers.
>
> Besides this, my own app uses PJSUA2 with C++ 17 features, so I would
> have to revert back to C++14 if this patch is not accepted upstream.
> This would be really unnecessary. So I would really appreciate a patch
> review.
>
> Best regards,
>
>      Christian
>
>
> On 18/09/18 20:57, Christian Hoff wrote:
>
> Hello all,
> Hello Ming & Riza,
>
> do you have any feedback regarding this patch for C++ 17 support? I am
> also willing to rework it if required, but some feedback would be
> nice.
>
>
> Thanks in advance and kind regards,
>
>       Christian
>
>
> On 12/09/18 18:23, Christian Hoff wrote:
>
> Hello all,
>
> currently it is not possible to compile a pjsua2 application with
> C++17. The reason is that C++17 removes support for dynamic exception
> specifications (that is "throws ..." declarations at the end of a
> function). Unfortunately PJSUA2 makes heavy use of exception
> specifications and most PJSUA2 functions are declared as "throw
> (Error)" - meaning that they can throw an exception of type "Error"
> that the programmer is supposed to catch.
>
> The consequence is that a lot of compile errors can be observed when
> compiling a pjsua2 application with C++17. The compile errors look as
> follows:
>
> /usr/local/include/pjsua2/json.hpp:80:33: error: ISO C++17 does not
> allow dynamic exception specifications
>        virtual string saveString() throw(Error);
>                                    ^~~~~
>
> The compile of the same application worked fine when using the C++14
> standard, but it got broken when I switched from C++14 to the C++17
> standard.
>
> See
> https://www.bfilipek.com/2017/05/cpp17-details-fixes-deprecation.html#removing-deprecated-exception-specifications-from-c17
>
> and
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0003r0.html
> for more background about the removal of exception specifications.
>
> To make the application compile again, I had to remove "throw(Error)"
> in the whole PJSUA2 source code and include files. This seems to be
> the only viable and good fix for this issue. I wrote my own "sed"
> script to do that and made some cosmetic corrections afterwards. Then
> I generated the attached patch file. Could you please apply this
> patch to the code base or give me feedback what I still need to
> improve? I verified that pjsip compiles fine with the patch applied.
>
> Thank you very much!
>
>
> Best regards,
>
>      Christian
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip@xxxxxxxxxxxxxxx
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip@xxxxxxxxxxxxxxx
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip@xxxxxxxxxxxxxxx
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip@xxxxxxxxxxxxxxx
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip@xxxxxxxxxxxxxxx
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip@xxxxxxxxxxxxxxx
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip@xxxxxxxxxxxxxxx
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
>
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip@xxxxxxxxxxxxxxx
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip@xxxxxxxxxxxxxxx
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
>
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip@xxxxxxxxxxxxxxx
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip@xxxxxxxxxxxxxxx
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>
>
>
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing list
> pjsip@xxxxxxxxxxxxxxx
> http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org
>

_______________________________________________
Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@xxxxxxxxxxxxxxx
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org



[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux