3

The code in question is a JNI interface between a Java and a native code. The h file is produced by the javah utility, whereas the cpp file is created by human.

If the Java part is renamed then javah produces function prototypes with the corresponding names, like it should. However, nothing makes sure the functions in the cpp file are renamed as well - all compiles as usual. The problem will only arise when the Java code invokes the native API at runtime.

How could one catch a mismatch between the h file produced by javah and the implementation cpp file produced by human during the compilation?

Carl Manaster
  • 39,912
  • 17
  • 102
  • 155
mark
  • 59,016
  • 79
  • 296
  • 580
  • 1
    Sounds like a job for a static code analyzer or linter. – Kerrek SB Nov 29 '12 at 19:08
  • Great, please provide a working example, so that your reply could be accepted as the answer. – mark Nov 29 '12 at 19:52
  • There are several different software packages that provide this functionality, and I don't know a specific one that does exactly what you want - but this should give you a starting point to *look* for a product that meets your needs... – Kerrek SB Nov 29 '12 at 20:59
  • I fixed that with [JavaCPP](http://code.google.com/p/javacpp/) by generating the whole .cpp source file, not just the .h header file like `javah`. – Samuel Audet Dec 01 '12 at 05:02
  • @SamuelAudet Would you consider your code production ready? – mark Dec 01 '12 at 10:57
  • Well, JavaCPP itself not really no, but I'm opened to suggestions about its future :) – Samuel Audet Dec 02 '12 at 10:59

1 Answers1

2

How about referring to the generated function declarations somewhere in the C++ code?

E.g. in (say) generated_check.cpp create a function that calls your prototypes with dummy parameters (but never call it):

#include "generated.h" // your javah output

static void neverCalled() {
     // Compiler errors here mean that the functions have changed:
     Java_com_example_package_MyClass_myFunc1(0, 0, 0);
     Java_com_example_package_MyClass_myFunc2(0);
}

Edit, in response to your comments:

Another (or complementary) approach would be to create a script that runs as part of your build process and have it back up the old generated.h before javah is run, and cause a build error if the new generated.h is different to the old one. It could even run a diff program to give you an error message to pinpoint the change.

Martin Stone
  • 12,682
  • 2
  • 39
  • 53
  • This is a great idea. Let me check it. – mark Nov 29 '12 at 19:21
  • This answers the case when the Java code is renamed, then the compiler fails the build, just what I want. There is a downside - the dev must have the discipline to add new methods to neverCalled. +1 in the meantime. – mark Nov 29 '12 at 19:40
  • It would be nice, though, to be protected not only against renames, but also against the parameter type changes. In your solution (which is great) one will have to cast the zeros to the respected types to achieve this effect, which is a bit dull. – mark Nov 29 '12 at 19:51
  • Yes, true -- Added an alternative approach in the main answer. – Martin Stone Nov 29 '12 at 20:00