自定义类加载器,用于在小程序中加载dll

发布于 2024-12-09 14:06:41 字数 3708 浏览 0 评论 0 原文

使用小程序解决 .dll 文件加载/卸载问题。我正在按照本教程加载.dll使用自定义类加载器的文件如下:

1-类加载器(复制自教程)

public class CustomClassLoader extends ClassLoader {
    private static final String CLASS_NAME = CustomClassLoader.class.getName();

    private Map<String, Class<?>> classes;

    public CustomClassLoader() {
        super(CustomClassLoader.class.getClassLoader());
        classes = new HashMap<String, Class<?>>();
    }

    public String toString() {
        return CustomClassLoader.class.getName();
    }

    @Override
    public Class<?> findClass(String name) throws ClassNotFoundException {

        if (classes.containsKey(name)) {
            return classes.get(name);
        }

        String path = name.replace('.', File.separatorChar) + ".class";
        byte[] b = null;

        try {
            b = loadClassData(path);
        } catch (IOException e) {
            throw new ClassNotFoundException("Class not found at path: " + new File(name).getAbsolutePath(), e); **
        }

        Class<?> c = defineClass(name, b, 0, b.length);
        resolveClass(c);
        classes.put(name, c);

        return c;
    }

    private byte[] loadClassData(String name) throws IOException {
        String methodName = CLASS_NAME + ".loadClassData";
        byte buff[] = null;

        try {
            File file = new File(name);
            int size = (int) file.length();
            buff = new byte[size];
            DataInputStream in = new DataInputStream(new FileInputStream(name));
            in.readFully(buff);
            in.close();

        } catch (IOException e) {
            throw new IOException(e.getMessage());
        }
        return buff;
    }
}

2- 加载 .dll 文件的类

public class DllLoader {

    private static final String CLASS_NAME = AppletReload.class.getName();

    static String javaHome = System.getProperty("java.io.tmpdir");
    private static String dllPath = javaHome + Constant.SMARTCARD_JACSPCSC_DLL_NAME;
    private static String dllPath1 = javaHome + Constant.SMARTCARD_RXTXSERIAL_DLL_NAME;

    public DllLoader() {
    }

    static {
        try {
            System.load(dllPath);
            Logger.write(LoggerConstant.TRACE, "JACSPCSC Dll loaded from the path: " + dllPath, "Dll Loader");
            System.load(dllPath1);
            Logger.write(LoggerConstant.TRACE, "RXTXSERIAL Dll loaded from the path: " + dllPath1, "Dll Loader");
        } catch (Exception e) {
        // Log exception;
        }
    }
}

这就是我使用这个类加载器的方式:

cl = new CustomClassLoader();
ca = cl.findClass("com.DllLoader");
a = ca.newInstance();

使用自定义类加载器加载 .dll 背后的动机是它也能保证卸载,这是大多数有关 .dll 加载/卸载问题的答案所建议的。但就我而言,loadClassData()(我的类加载器中的一个函数)抛出此异常:

   loadClassData,Error: com\DllLoader.class (The system cannot find the path specified)
    java.io.FileNotFoundException: com\DllLoader.class (The system cannot find the path specified)

并且文件的绝对路径显示记录为:

**C:\Program Files\Mozilla Firefox\com。 DllLoader

我认为这是它搜索文件的地方,而小程序的 .jar 文件不位于此处。

如果有人能指出我所犯的错误或告诉我如何引导浏览器在正确的文件夹中查找类文件,我将不胜感激。

PS:请注意,看似重复的答案问题不能解决这个问题。

To address the .dll file loading/unloading issue with applets. I am loading, following this tutorial, .dll files using a custom class loader as :

1- Class Loader (Copied from tutorial)

public class CustomClassLoader extends ClassLoader {
    private static final String CLASS_NAME = CustomClassLoader.class.getName();

    private Map<String, Class<?>> classes;

    public CustomClassLoader() {
        super(CustomClassLoader.class.getClassLoader());
        classes = new HashMap<String, Class<?>>();
    }

    public String toString() {
        return CustomClassLoader.class.getName();
    }

    @Override
    public Class<?> findClass(String name) throws ClassNotFoundException {

        if (classes.containsKey(name)) {
            return classes.get(name);
        }

        String path = name.replace('.', File.separatorChar) + ".class";
        byte[] b = null;

        try {
            b = loadClassData(path);
        } catch (IOException e) {
            throw new ClassNotFoundException("Class not found at path: " + new File(name).getAbsolutePath(), e); **
        }

        Class<?> c = defineClass(name, b, 0, b.length);
        resolveClass(c);
        classes.put(name, c);

        return c;
    }

    private byte[] loadClassData(String name) throws IOException {
        String methodName = CLASS_NAME + ".loadClassData";
        byte buff[] = null;

        try {
            File file = new File(name);
            int size = (int) file.length();
            buff = new byte[size];
            DataInputStream in = new DataInputStream(new FileInputStream(name));
            in.readFully(buff);
            in.close();

        } catch (IOException e) {
            throw new IOException(e.getMessage());
        }
        return buff;
    }
}

2- A class to load .dll files

public class DllLoader {

    private static final String CLASS_NAME = AppletReload.class.getName();

    static String javaHome = System.getProperty("java.io.tmpdir");
    private static String dllPath = javaHome + Constant.SMARTCARD_JACSPCSC_DLL_NAME;
    private static String dllPath1 = javaHome + Constant.SMARTCARD_RXTXSERIAL_DLL_NAME;

    public DllLoader() {
    }

    static {
        try {
            System.load(dllPath);
            Logger.write(LoggerConstant.TRACE, "JACSPCSC Dll loaded from the path: " + dllPath, "Dll Loader");
            System.load(dllPath1);
            Logger.write(LoggerConstant.TRACE, "RXTXSERIAL Dll loaded from the path: " + dllPath1, "Dll Loader");
        } catch (Exception e) {
        // Log exception;
        }
    }
}

And this is how I am using this class loader:

cl = new CustomClassLoader();
ca = cl.findClass("com.DllLoader");
a = ca.newInstance();

The motivation behind loading .dll using custom class loader is that it would guarantee the unloading as well and this is what most of the answers to question on .dll loading/unloading suggest. But in my case, loadClassData() (a function in my classLoader) thows this exception:

   loadClassData,Error: com\DllLoader.class (The system cannot find the path specified)
    java.io.FileNotFoundException: com\DllLoader.class (The system cannot find the path specified)

and the absolute path of file is show logged as:

**C:\Program Files\Mozilla Firefox\com.DllLoader

I think this is where its searching for the file, and .jar file of applet isn't located here.

I would appreciate if anyone can point out mistake I am making or tell how can I guide browser to look for class file in correct folder.

P.S: Kindly note that a answer to seemingly duplicate question don't solve this problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文