【问题标题】:Import class in Java via absolute path通过绝对路径在Java中导入类
【发布时间】:2018-11-08 01:11:18
【问题描述】:

我一直在尝试在代码运行时通过绝对路径导入 .class,但我不知道该怎么做。

我通过Class.forName();找到了一种在项目的构建路径中导入类的方法,但我需要找到一种方法来加载不在构建路径中的类。

目标是:

  1. 用户可以上传自己的 .class 文件,然后将其本地保存到特定文件夹,路径保存在数据库中
  2. 通过 GUI 用户可以选择在代码运行时使用该文件
  3. 我的代码应该在代码运行时通过这个给定的绝对路径加载一个类

问题在于第三点,因为我不知道是否可以在代码运行时加载类。

我尝试使用 URLClassLoader,但遇到 ClassNotFound 错误。

编辑:

基本上,我有这个静态函数,它应该按其名称返回 Class,但 urlClassLoader.loadClass() 会抛出错误。

文件的名称是 J48.class,因此对于 className 参数,我尝试使用“J48”、“J48.class”,但没有任何效果。

此外,我尝试设置文件夹分类器来构建路径并将参数设置为“weka.classifiers.trees.J48”,这是该类的包的完整路径(包结构是 weka.classifiers.trees)。

`public static Class getClassByName(String className) throws MalformedURLException, ClassNotFoundException 
    {
        URLClassLoader urlClassLoader = URLClassLoader.newInstance(new URL[] {
                   new URL("file:///D:\\xampp\\htdocs\\prog-ing\\classifiers\\")
        });

        Class class = urlClassLoader.loadClass(className);

        return class;
    }`

【问题讨论】:

  • “我尝试过使用 URLClassLoader,但出现 ClassNotFound 错误。” - 将您的代码发布为minimal reproducible example,以便人们可以帮助您。
  • 我添加了负责类加载的函数。我尝试更改 URL(/ 和 \)并将类名从“J48”更改为“J48.class”。
  • 你要加载的类的包结构是什么?
  • 我是classifiers.J48,你需要将URL缩短一个路径元素,并将包名添加到类中。
  • 试过了,但没用。我可以知道包名吗?因为目标是让用户上传任何类,然后将其保存到文件夹分类器中,我正在从该文件夹加载类。此文件夹(D:/xampp/htdocs/prog-ing/classifiers)不在构建路径中,不确定是否应该在,但我试图避免这种情况。

标签: java class classloader classnotfoundexception


【解决方案1】:

我想我有一个建议可以解决您的问题...

我知道两种选择:

  • 选项 1:从目录中读取类文件。

例子:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class Test5 extends ClassLoader {

    private static final String PATH = "C://myFiles//";

    public static void main(String[] args) {
        Class clazz = getClassFromName("Test4");
        System.out.println(clazz);
    }

    private static Class getClassFromName(String className) {
        File file = new File(PATH + className + ".class");

        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            byte[] bytes = new byte[fileInputStream.available()];

            fileInputStream.read(bytes);

            return defineClass(className, bytes, 0, bytes.length);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

}

这将打印如下内容:

类Test4


- 选项 2:从 JAR 中读取类文件。

例子:

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

public class Test5 {

    private static final String PATH = "C://myFiles//";

    public static void main(String[] args) {
        Class clazz = getClassFromFile("myJar.jar", "com.mypackage.Test4");
        System.out.println(clazz);
    }

    private static Class getClassFromFile(String fromFile, String className) {
        try {
            URL url = new URL("file:////" + PATH + fromFile);
            URLClassLoader urlClassLoader = URLClassLoader.newInstance(
                new URL[] {
                    url
            });

            return urlClassLoader.loadClass(className);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        return null;
    }

}

这将打印如下内容:

com.mypackage.Test4 类

请注意,要读取 jar 文件,我必须将 包的完整路径 放到类文件中。

我希望我有所帮助。

【讨论】:

  • 在我尝试了第一个解决方案后,我收到了一个错误:Exception in thread "AWT-EventQueue-0" java.lang.ClassFormatError: Incompatible magic value 1212239428 in class file J48。我尝试将 .class 更改为 .java,同样的事情发生了。我猜文件由于某种原因没有被识别为 Java 类,但我确信它应该编译没有错误。
【解决方案2】:

好吧,经过一番思考,我只得到了一个解决方案(仍然不满意),如下所示:

需要由用户上传的每个类都保存到该项目的工作区中,因此我可以使用 Class.forName(); 指出上传类的这个“文件夹”来获取类,在我的例子中:Class.forName("classifiers.className");

【讨论】:

    猜你喜欢
    • 2022-10-24
    • 2022-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多