Java 尝试使用包含自定义类的构造函数实例化动态加载的类时,NoSuchMethodException
我试图用一个构造函数实例化一个动态加载的类(带有自定义类加载器),该构造函数包含一个String对象和我创建的自定义类 我在我的项目之外重新创建了问题,这是假设Java 尝试使用包含自定义类的构造函数实例化动态加载的类时,NoSuchMethodException,java,reflection,constructor,Java,Reflection,Constructor,我试图用一个构造函数实例化一个动态加载的类(带有自定义类加载器),该构造函数包含一个String对象和我创建的自定义类 我在我的项目之外重新创建了问题,这是假设A.class已经在目标文件夹中 主要方法: public class simplifiedMainMethod { static boolean propagate = false; static Class<?> projectActions = null; static Object oInstance; publi
A.class
已经在目标文件夹中
主要方法:
public class simplifiedMainMethod {
static boolean propagate = false;
static Class<?> projectActions = null;
static Object oInstance;
public static void main (String[] args)
{
String projectName = "A";
String baseUrl = "https://www.google.com/";
simplifiedReport reporter = new simplifiedReport();
try
{
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Reloader r = new Reloader(cl);
if (propagate)
Thread.currentThread().setContextClassLoader(r);
projectActions = r.loadClass("autobots_framework."+projectName);
Constructor<?> c = projectActions.getConstructor(String.class, simplifiedReport.class);
oInstance = c.newInstance(baseUrl, reporter);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
A.java
:
public class A
{
public A(String testString, simplifiedReport testReport)
{
System.out.println(testString);
testReport.testMethod();
}
}
下面是我正在使用的CustomClassLoader
:
public class ClassLoaderCompiler
{
public ClassLoaderCompiler()
{}
public static boolean compileCode(String fileDirectory, String projectName) throws IOException
{
JavaCompiler compiler = new EclipseCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromStrings(Arrays.asList(fileDirectory));
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits);
try
{
task.call();
fileManager.close();
return true;
}
catch(Exception e)
{
fileManager.close();
return false;
}
}
public static void moveClassFile(String projectName)
{
try
{
Files.deleteIfExists(new File(System.getProperty("user.dir")+"/target/classes/autobots_framework/"+projectName+".class").toPath());
Files.deleteIfExists(new File(System.getProperty("user.dir")+"/target/classes/autobots_framework/L_"+projectName+".class").toPath());
if (Files.exists(Paths.get(System.getProperty("user.dir")+"/projects/"+projectName+"/"+projectName+".class")))
{
Path temp = Files.move (Paths.get(System.getProperty("user.dir")+"/projects/"+projectName+"/"+projectName+".class"),Paths.get(System.getProperty("user.dir")+"/target/classes/autobots_framework/"+projectName+".class"));
Path tempLocator = Files.move (Paths.get(System.getProperty("user.dir")+"/projects/"+projectName+"/L_"+projectName+".class"),Paths.get(System.getProperty("user.dir")+"/target/classes/autobots_framework/L_"+projectName+".class"));
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
/**
* adapted from http://stackoverflow.com/a/3971771/7849
*/
class Reloader extends ClassLoader {
static URL url;
ClassLoader orig;
Reloader(ClassLoader orig) {
this.orig = orig;
}
@Override
public Class<?> loadClass(String s) {
return findClass(s);
}
@Override
public Class<?> findClass(String s) {
try {
byte[] bytes = loadClassData(s);
return defineClass(s, bytes, 0, bytes.length);
} catch (IOException ioe) {
try {
return super.loadClass(s);
} catch (ClassNotFoundException ignore) {
ignore.printStackTrace(System.out);
}
ioe.printStackTrace(System.out);
return null;
}
}
private byte[] loadClassData(String className) throws IOException {
try {
/*
* get the actual path using the original classloader
*/
Class<?> clazz = orig.loadClass(className);
url = clazz.getResource(clazz.getSimpleName() + ".class");
/*
* force reload
*/
File f = new File(url.toURI());
int size = (int) f.length();
byte buff[] = new byte[size];
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
dis.readFully(buff);
dis.close();
return buff;
} catch (Exception ex) {
throw new IOException(ex);
}
}
}
产生这个结果:
public autobots_framework.A(java.lang.String,autobots_framework.simplifiedReport)
令人沮丧的是,这与我在这里所说的非常相似:
Constructor<?> c = projectActions.getConstructor(String.class, simplifiedReport.class);
oInstance = c.newInstance(baseUrl, reporter);
Constructor c=projectActions.getConstructor(String.class,simplifiedReport.class);
oInstance=c.newInstance(baseUrl,reporter);
我知道这与我的类有关,因为当我在构造函数中省略了simplifiedReport
,只使用String.class
实例化它时,我成功了。我在课堂上缺少什么修饰语来完成这项工作
这都是我的应用程序的一个函数,用于动态编译代码,然后实例化它们以运行自定义代码和方法。您如何验证类
a
具有类似public a(String testString,simplifiedReport testReport)的构造函数
@Gautam当我使用Constructor.toGenericString()
命令并收到以下结果时,在原始帖子中描述了这一点:public autobots\u framework.A(java.lang.String,autobots\u framework.simplifiedReport)
您如何验证类A
具有类似public A的构造函数(String testString,simplifiedReport testReport)
@Gautam当我使用构造函数.toGenericString()
命令并收到以下结果时,在原始帖子中描述了这一点:public autobots\u framework.A(java.lang.String,autobots\u framework.simplifiedReport)
for (Constructor c : projectActions.getDeclaredConstructors())
{
System.out.print(c.toGenericString());
}
public autobots_framework.A(java.lang.String,autobots_framework.simplifiedReport)
Constructor<?> c = projectActions.getConstructor(String.class, simplifiedReport.class);
oInstance = c.newInstance(baseUrl, reporter);