rJava调用Java方法因签名不匹配出现找不到方法问题求助
解决rJava调用Java方法时找不到方法签名的问题
问题背景
使用rJava调用Java的performCurveFitting方法时,报错找不到签名为([D[DDD)Ljava/lang/String;的方法。
Java方法定义
public static String performCurveFitting(Double[] conc, Double[] resp, Double classificationSD, Double minYrange) { CurveFittingService fittingService = new CurveFittingServiceImpl(); FittingResult fittingResult = fittingService.doFit(conc, resp, classificationSD, minYrange); // Convert the fitting result to a String representation return fittingResult.toString(); // Assuming FittingResult has overridden toString() method }
无报错的R代码
.jinit('.') .jaddClassPath('inst/java/curve-fitting.jar') curvefit <- .jnew('gov/nih/ncats/ifx/qhts/curvefitting/CurveClassFit') .DollarNames(curvefit)
报错的R调用代码
.jcall(curvefit, returnSig = "Ljava/lang/String;", method = "performCurveFitting", c(5.5707525685E-10, 4.5123095805E-8, 1.2183235867E-6, 3.2894736842E-5),c(2,4,6,100), 5, 10)
错误信息
Error in .jcall(curvefit, returnSig = "Ljava/lang/String;", method = "performCurveFitting", :
method performCurveFitting with signature ([D[DDD)Ljava/lang/String; not found
解决方案
问题核心是Java方法参数类型与rJava传递的类型不匹配:
Java方法参数用的是Double[](包装类数组),而rJava默认传递的c(...)会被解析为double[](基本类型数组),两者的方法签名完全不同,导致找不到对应方法。
方案1:修改Java方法(推荐)
将Java方法的参数改为基本类型数组double[],适配rJava的默认传递逻辑,修改后代码如下:
import java.util.Arrays; public static String performCurveFitting(double[] conc, double[] resp, double classificationSD, double minYrange) { CurveFittingService fittingService = new CurveFittingServiceImpl(); // 如果doFit方法需要Double[],在这里做类型转换 Double[] concObj = Arrays.stream(conc).boxed().toArray(Double[]::new); Double[] respObj = Arrays.stream(resp).boxed().toArray(Double[]::new); FittingResult fittingResult = fittingService.doFit(concObj, respObj, classificationSD, minYrange); return fittingResult.toString(); }
重新编译打包jar包后,原R调用代码即可正常运行。
方案2:修改R代码(不推荐,繁琐)
若无法修改Java代码,需在R中手动创建Double包装类数组及参数:
# 创建Double类型数组 conc <- .jarray(c(5.5707525685E-10, 4.5123095805E-8, 1.2183235867E-6, 3.2894736842E-5), "Ljava/lang/Double;") resp <- .jarray(c(2,4,6,100), "Ljava/lang/Double;") # 创建Double类型参数 classificationSD <- .jnew("java/lang/Double", 5) minYrange <- .jnew("java/lang/Double", 10) # 调用方法 .jcall(curvefit, returnSig = "Ljava/lang/String;", method = "performCurveFitting", conc, resp, classificationSD, minYrange)
这种方式需要手动处理所有包装类类型,容易出错,仅作为无法修改Java代码时的备选方案。
内容的提问来源于stack exchange,提问作者Jui-Hua Hsieh
相关产品推荐
相关产品推荐

