EDIT:   See also this elegant answer using a function instead of the bottom preprocessor macro.
If you want to implement JNI, this is how I did:
Let's imagine the below class in file example.java:
package my.group.mypackage;
public class Example {
  static {
    System.loadLibrary("my-DLL-name");
  }
  public Example() {
    /* ... */
  }
  private native int    function1(int); //declare DLL functions
  private native String function2(int); //using the keyword
  private native void   function3(int); //'native'
  public void dosomething(int value) {
    int result = function1(value);  
    String str = function2(value);  //call your DLL functions
    function3(value);               //as any other java function
  }
}
Generate example.class from example.java (using javac or your EDI or maven...). Then generate C/C++ header file Java_my_group_mypackage_example.h from example.class using javah.
The declaration of C/C++ functions are in Java_my_group_mypackage_example.h. Now we implement the definition (body) of these functions in Java_my_group_mypackage_example.cpp for instance. Prefer using C++ (instead of C) to catch exceptions from other DLLs.
JNIEXPORT jlong JNICALL Java_my_group_mypackage_example_function1
  (JNIEnv *env, jobject object, jlong value)
{
  try 
  {
    /* ... my processing ... */
    return jlong(result);
  }
  CATCH_CPP_EXCEPTION_AND_THROW_JAVA_EXCEPTION
  return 0;
}
JNIEXPORT jstring JNICALL Java_my_group_mypackage_example_function2
  (JNIEnv *env, jobject object, jlong value)
{
  try 
  {
    /* ... my processing ... */
    jstring jstr = env->NewStringUTF("my result");
    return  jstr;
  }
  CATCH_CPP_EXCEPTION_AND_THROW_JAVA_EXCEPTION
  return 0;
}
JNIEXPORT void JNICALL Java_my_group_mypackage_example_function3
  (JNIEnv *env, jobject object, jlong value)
{
  try 
  {
    /* ... my processing ... */
  }
  CATCH_CPP_EXCEPTION_AND_THROW_JAVA_EXCEPTION
}
The C preprocessor macro CATCH_CPP_EXCEPTION_AND_THROW_JAVA_EXCEPTION is defined below. It converts the C++ exceptions into Java exceptions. Customize that code using your your own mypackage::Exception and put it in a common header (not in `Java_my_group_mypackage_example.h' because this could be regenerated again).
#define CATCH_CPP_EXCEPTION_AND_THROW_JAVA_EXCEPTION              \
                                                                  \
  catch (const mypackage::Exception& e)                           \
  {                                                               \
    jclass jc = env->FindClass("my/group/mypackage/Exception");   \
    if(jc) env->ThrowNew (jc, e.what());                          \
    /* if null => NoClassDefFoundError already thrown */          \
  }                                                               \
  catch (const std::bad_alloc& e)                                 \
  {                                                               \
    /* OOM exception */                                           \
    jclass jc = env->FindClass("java/lang/OutOfMemoryError");     \
    if(jc) env->ThrowNew (jc, e.what());                          \
  }                                                               \
  catch (const std::ios_base::failure& e)                         \
  {                                                               \
    /* IO exception */                                            \
    jclass jc = env->FindClass("java/io/IOException");            \
    if(jc) env->ThrowNew (jc, e.what());                          \
  }                                                               \
  catch (const std::exception& e)                                 \
  {                                                               \
    /* unknown exception */                                       \
    jclass jc = env->FindClass("java/lang/Error");                \
    if(jc) env->ThrowNew (jc, e.what());                          \
  }                                                               \
  catch (...)                                                     \
  {                                                               \
    /* Oops I missed identifying this exception! */               \
    jclass jc = env->FindClass("java/lang/Error");                \
    if(jc) env->ThrowNew (jc, "unidentified exception");          \
  }
Compile Java_my_group_mypackage_example.cpp to produce a DLL. Set your PATH or move that DLL within your java run-time directory (usually target). 
Do not forget to replace "my-DLL-name" in the java source code by the name of your DLL without the extension (e.g. myname.dll ->  "myname").
This also works using Linux/Unix shared library (*.so) ;-)