Java 动态加载Jar并实例化已加载类的对象

Java 动态加载Jar并实例化已加载类的对象,java,web-services,dynamic,client,classloader,Java,Web Services,Dynamic,Client,Classloader,我尝试将jar动态加载到Java项目中 下面是类装入器的代码: public class ClassLoad { public static void main(String[] args) { String filePath = new String("C:/Users/Mehdi/Desktop/JavaClassLoader/jarred.jar"); URL myJarFile = null; try { myJarFile = new UR

我尝试将jar动态加载到Java项目中

下面是类装入器的代码:

public class ClassLoad {

public static void main(String[] args) {

    String filePath = new String("C:/Users/Mehdi/Desktop/JavaClassLoader/jarred.jar");

    URL myJarFile = null;
    try {
        myJarFile = new URL("file://"+filePath);
    } catch (MalformedURLException e1) {
        System.out.println("1");
        e1.printStackTrace();
    }

    URLClassLoader cl = URLClassLoader.newInstance(new URL[]{myJarFile});

    Class Jarred = null;
    try {
        Jarred = cl.loadClass("com.jarred.exp.Jarred");
    } catch (ClassNotFoundException e) {
        System.out.println("2");
        e.printStackTrace();
    }

    Method simpleWrite = null;
    try {
        simpleWrite = Jarred.getMethod("simpleWrite", new Class[] {String.class});
    } catch (SecurityException e) {
        System.out.println("3");
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        System.out.println("4");
        e.printStackTrace();
    }

    Object JarredObj = null;
    try {
        JarredObj = Jarred.newInstance();
    } catch (InstantiationException e) {
        System.out.println("5");
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        System.out.println("6");
        e.printStackTrace();
    }

    try {
        Object response = simpleWrite.invoke(JarredObj, "\nHello Mehdi ! It works hamdoulillah :D");
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
}
}
以及包含在Jar中的类:

package com.jarred.exp;

public class Jarred {

public void simpleWrite(String str) {
    System.out.println(str);
}
}

它给了我:

2
java.lang.ClassNotFoundException: com.jarred.exp.Jarred
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.net.FactoryURLClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at ClassLoad.main(ClassLoad.java:25)
Exception in thread "main" java.lang.NullPointerException
at ClassLoad.main(ClassLoad.java:32)

你知道这件事吗?谢谢。

您的文件URL似乎无效

用于本地Windows文件路径

C:\Documents and Settings\davris\FileSchemeURIs.doc

Windows中相应的有效文件URI为:

file:///C:/Documents%20and%20Settings/davris/FileSchemeURIs.doc

这表明冒号后面需要三个斜杠,但是您正在计算的URL

String filePath = new String("C:/Users/Mehdi/Desktop/JavaClassLoader/jarred.jar");

URL myJarFile = null;
try {
    myJarFile = new URL("file://"+filePath);
文件之后只有两个斜杠:
。或许

    myJarFile = new URL("file://"+filePath);
应该是

    myJarFile = new URL("file:///"+filePath);
或者你也可以这样用


通过适当的异常处理。

通过接口代理它。我知道。问题在于识别接口、类或加载的jar中的任何东西。不,在项目中为服务类定义一个接口并使用它。添加一个加载jar并返回类实例的工厂方法,classname应该是工厂方法的字符串参数。或者,由于您知道类的名称,您可以通过class.forName(String)方法直接获取实例。为什么要向系统类加载器添加URL,而不是创建自己的URLClassLoader,将系统类加载器用作父类?Java虚拟机甚至不需要系统类加载器,因此这是一个非常脆弱的代码。@Mehdi,您的类加载器创建现在看起来更好了。对不起,您知道我是否想动态加载方法的参数类型,而我不应该使用
getParameterTypes()
来了解它们。谢谢:)@Mehdi,
Class.getDeclaredMethods
将允许您循环使用这些方法并选择一个合适的方法。一定要检查修改器以确保它是公开的。@Mehdi,我不理解你的问题。如果您知道如何动态加载类,那么您不知道如何动态加载param类吗?谢谢。但我要做的是替换以下行:
simpleWrite=Jarred.getMethod(“simpleWrite”,新类[]{String.Class})类似于:
simpleWrite=Jarred.getMethod(“simpleWrite”,新类[]{动态加载的参数类型})
;对不起,我指的是方法的签名
File myJarFile = new File("C:\\Users\\Mehdi\\Desktop\\JavaClassLoader\\jarred.jar");
if (!myJarFile.isFile()) {
  throw new FileNotFoundException("Missing required JAR: " + myJarFile.toString());
}
URL myJarUrl = myJarFile.toURI().toURL();