我需要在运行时使用反射在JAR文件中的类上调用方法。
到目前为止我的代码看起来像这样:
package com;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
public class MyJarImport {
public static void main(String[] args) throws Exception{
// C:\\KnimeIntegrationProjekt\\Knime\\pmmlj
// C:\\Users\\marcel.hoffmann\\JavaWorkspace\\HelloWorld\\bin\\Hello
//C:\\Knime\\ClusterJar
File file = new File("C:\\Knime\\ClusterJar");
try{
URL url = file.toURI().toURL();
URL[] urls = new URL[]{url};
URLClassLoader cl = new URLClassLoader(urls);
//loading the jar file from directory
Class<?> cls = cl.loadClass("MainModel");
Constructor<?> constructor = cls.getConstructor();
//instantiate the classfile
Object MainModelObj = constructor.newInstance();
/* searching the methods in order to get an instance*/
Method mGetInput = cls.getMethod("getInputFields");
Method mNumInputs = cls.getMethod("getNumInputs");
int dim = (int) mNumInputs.invoke(MainModelObj);
Method mMining = cls.getMethod("getMiningFunction");
String miningFunction = "";
/*returns either Classification, Regression or Clustering
not used yet, but maybe later to figure out what miningfunction has been used
that effects the content of evalOutputs[]*/
miningFunction = (String)mMining.invoke(MainModelObj);
String[] inputFieldUnsorted = new String[dim];
inputFieldUnsorted = (String[]) mGetInput.invoke(MainModelObj);
Object[] sortedInputs = new Object[dim];
int index = 0;
/*sorting the inputs from getInputFields respecting the getInputFieldIndex returns*/
for(int i= 0; i<inputFieldUnsorted.length;i++){
Method mInputIndex = cls.getMethod("getInputFieldIndex",String.class);
index = (int) mInputIndex.invoke(MainModelObj, inputFieldUnsorted[i]);
sortedInputs[index] = inputFieldUnsorted[i];
}
/* sortedInputs[] contains the column names of the iris.csv table
invoking the evaluate method. concerning the documentation the method u need to call
in order to use the model inside the jarfile*/
Method mEvaluate= cls.getMethod("evaluate", Object[].class);
/* allocating an array for the outputs of the evaluate method*/
Object[] evalOutputs = new Object[dim];
evalOutputs = (Object[]) mEvaluate.invoke(MainModelObj, sortedInputs, inputFieldUnsorted);
/* closing the opened classloader*/
cl.close();
} catch(IOException e) {
System.out.println("File not found!");
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("Class not found!");
}
}
}
此代码抛出异常 - IllegalArgumentException:wrong number of arguments
:
Exception in thread "main" java.lang.IllegalArgumentException:
wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.MyJarImport.main(MyJarImport.java:58)
我提到了文档,它说方法签名是这样的:
Object[] MainModel.evaluate(Object[] inputs);
我调试了代码,根据变量的值,我认为一切正常。但这个电话似乎是个问题。
我刚读了一些关于调用的内容,说VM试图调用jar文件的main方法,主要方法需要它的String [] args参数,但是为什么要这样做,如果我想调用一个显式的方法
我希望有人可以帮我解决这个小问题。