【问题标题】:Dynamically loading Jar and instanciate an Object of a loaded Class动态加载 Jar 并实例化已加载类的对象
【发布时间】:2013-04-12 20:18:13
【问题描述】:

我尝试将一个 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)

您对此有任何想法吗?谢谢。

【问题讨论】:

  • 通过接口代理它
  • 谢谢。我知道。问题在于识别接口或类或加载的 jar 中的任何内容。
  • 不,在您的项目中为 Service 类定义一个接口并使用它。添加加载jar并返回类实例的工厂方法,classname应该是工厂方法的String参数。或者知道类名,直接通过Class.forName(String)方法获取实例
  • 你为什么要向系统类加载器添加一个 URL,而不是创建你自己的使用系统类加载器作为父类的 URLClassLoader? Java VM 甚至不需要系统类加载器,因此这是非常脆弱的代码。
  • @Mehdi,您的类加载器创建现在看起来更好了。

标签: java web-services dynamic client classloader


【解决方案1】:

您的文件网址似乎无效。

"File URIs in Windows"

对于本地 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);

file: 之后只有两个斜杠。也许

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

应该是

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

或者你也可以这样使用java.io.File.toURI

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();

适当的异常处理。

【讨论】:

  • 对不起,但你知道我是否想动态加载我不应该使用 getParameterTypes() 知道的方法的参数类型。谢谢你:)
  • @Mehdi, Class.getDeclaredMethods 将让您遍历这些方法并选择一个看起来合适的方法。请务必检查修饰符以确保它是公开的。
  • @Mehdi,我不明白你的问题。如果您知道如何动态加载类,那么您不知道如何动态加载参数类吗?
  • 谢谢。但我想做的是将以下行替换为:simpleWrite = Jarred.getMethod("simpleWrite", new Class[] {String.class}); 类似:simpleWrite = Jarred.getMethod("simpleWrite", new Class[] {PARAMS TYPES LOADED DYNAMICALLY});
  • 对不起,我的意思是方法的签名
猜你喜欢
  • 1970-01-01
  • 2015-03-19
  • 1970-01-01
  • 2018-06-15
  • 2012-11-10
  • 1970-01-01
  • 1970-01-01
  • 2016-02-26
  • 2018-07-31
相关资源
最近更新 更多