# HG changeset patch
# User Ernst Reissner <rei3ner@arcor.de>
# Date 1471309156 -7200
#      Tue Aug 16 02:59:16 2016 +0200
# Node ID d05388cc88d78a83c4258a7867f3f417bfaab284
# Parent  51553d55681f02bea229a7c2366c68ba7bbc5720
bugfix #48795: take in invokeMember/StaticMethod static modifier into account:
added method findMethod(....,boolean isStatic,...)
and base invokeMember/StaticMethod on this new method.

diff -r 51553d55681f -r d05388cc88d7 libinterp/octave-value/ov-java.cc
--- a/libinterp/octave-value/ov-java.cc	Mon Aug 15 17:47:34 2016 +0200
+++ b/libinterp/octave-value/ov-java.cc	Tue Aug 16 02:59:16 2016 +0200
@@ -2316,7 +2316,7 @@
       if (unbox (jni_env, args, arg_objs, arg_types))
         {
           jclass_ref helperClass (jni_env, find_octave_class (jni_env, "org/octave/ClassHelper"));
-          jmethodID mID = jni_env->GetStaticMethodID (helperClass, "invokeMethod",
+          jmethodID mID = jni_env->GetStaticMethodID (helperClass, "invokeMemberMethod",
                                                       "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;[Ljava/lang/Class;)Ljava/lang/Object;");
           jstring_ref methName (jni_env, jni_env->NewStringUTF (name.c_str ()));
           jobjectArray_ref resObj (jni_env, reinterpret_cast<jobjectArray> (jni_env->CallStaticObjectMethod (helperClass, mID,
diff -r 51553d55681f -r d05388cc88d7 scripts/java/org/octave/ClassHelper.java
--- a/scripts/java/org/octave/ClassHelper.java	Mon Aug 15 17:47:34 2016 +0200
+++ b/scripts/java/org/octave/ClassHelper.java	Tue Aug 16 02:59:16 2016 +0200
@@ -594,7 +594,7 @@
   }
 
 
-  //! Return the first method in class @c cls
+  //! Return the first method found in class @c cls
   //! with name @c name and parameter types @c argTypes
   //! or @c null if no such method is found.
   //! Note that if there are more than one method fitting the criteria,
@@ -608,7 +608,7 @@
   //! @param argTypes
   //!    the argument types of the method.
   //! @return
-  //!    a method in class @c cls
+  //!    a method in class @c cls, 
   //!    with name @c name and parameter types @c argTypes
   //!    or @c null if no such method exists.
   private static Method findMethod (Class cls, String name, Class[] argTypes)
@@ -636,6 +636,35 @@
       }
   }
 
+  //! Return the first method found in class @c cls
+  //! with name @c name, static if and only if @c isStatic 
+  //! and with parameter types @c argTypes
+  //! or @c null if no such method is found.
+  //! Note that if there are more than one method fitting the criteria,
+  //! an arbitrary one is returned, and there is no notification,
+  //! that the solution is not unique.
+  //!
+  //! @param cls
+  //!    the class of the method.
+  //! @param name
+  //!    the name of the method.
+  //! @param isStatic
+  //!    whether the method to be returned is static. 
+  //! @param argTypes
+  //!    the argument types of the method.
+  //! @return
+  //!    a method in class @c cls, static if and only if @c isStatic, 
+  //!    with name @c name and parameter types @c argTypes
+  //!    or @c null if no such method exists.
+  private static Method findMethod (Class cls, String name, boolean isStatic, 
+                                    Class[] argTypes)
+  {
+    Method meth = findMethod (cls, name, argTypes);
+    return (meth == null || Modifier.isStatic(meth.getModifiers()) != isStatic)
+      ? null : meth;
+  }
+
+
   //! Return the first constructor in class @c cls
   //! with parameter types @c argTypes
   //! or @c null if no such constructor is found.
@@ -763,11 +792,11 @@
   // #do_javaMethod(void*, std::string&, octave_value_list&)
   // in <code>ov-java.cc</code> only.
   // getField(Object, String)
-  public static Object invokeMethod (Object target, String name, Object[] args,
-                                     Class[] argTypes)
+  public static Object invokeMemberMethod (Object target, String name, 
+                                           Object[] args, Class[] argTypes)
     throws Throwable
   {
-    Method m = findMethod (target.getClass (), name, argTypes);
+    Method m = findMethod (target.getClass (), name, false, argTypes);
     if (m == null)
       {
         throw new NoSuchMethodException (name);
@@ -775,6 +804,7 @@
 
     try
       {
+        // may throw IllegalAccessException, InvocationTargetException
         Object result = invokeMethod (m, target,
                                       castArguments (args, argTypes,
                                                      m.getParameterTypes ()));
@@ -782,6 +812,7 @@
       }
     catch (InvocationTargetException ex)
       {
+        // may throw general Throwable
         throw ex.getCause ();
       }
 
@@ -795,9 +826,10 @@
     throws ClassNotFoundException, NoSuchMethodException,
     IllegalAccessException, Throwable
   {
+    
     // forName may throw ClassNotFoundException
     Method m = findMethod (Class.forName (cls, true, loader), 
-                           name, argTypes);
+                           name, true, argTypes);
     if (m == null)
       {
         throw new NoSuchMethodException (name);
@@ -806,6 +838,8 @@
     try
       {
         // may throw IllegalAccessException, InvocationTargetException
+        // NullPointerException if m is an instance method 
+        // FIXME: Bug #48795 
         Object result = m.invoke (null,
                                   castArguments (args, argTypes,
                                                  m.getParameterTypes ()));
@@ -838,6 +872,7 @@
       }
     catch (InvocationTargetException ex)
       {
+        // may throw general Throwable
         throw ex.getCause ();
       }
 
@@ -871,7 +906,8 @@
         try
           {
             // may throw Throwable if so does method name()
-            return invokeMethod (target, name, new Object[0], new Class[0]);
+            return invokeMemberMethod (target, name, 
+                                       new Object[0], new Class[0]);
           }
         catch (NoSuchMethodException ex2)
           {
