首页 > 解决方案 > 如何从另一个 jar 文件中调用一个类?

问题描述

我目前正在尝试加载一个类或通过使用 java 的反射从 jar 文件中调用主类来运行它。

每当我尝试运行它时,我都会收到以下错误:

`java.lang.ClassNotFoundException: MyClass
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at com.test.Test.main(Test.java:43)`

该程序还将找到说 Found MyClass 的 jar,并且我还将主类初始化为它找到的类。问题是它根本找不到类,即使它在技术上已经找到并设置好了。

我已经尝试过使用调用的方法来加载项目内部的主类,效果很好。

`private static JarFile jarFile;

@SuppressWarnings("unused")
public static void main(String[] args) throws IOException
{
    /** Input of jar file */
    jarFile = new JarFile("MyJarFile.jar");
    Enumeration<JarEntry> e = jarFile.entries();
    URL[] urls = { new URL("jar:file:" + "MyJarFile.jar" +"!/") };
    URLClassLoader cl = URLClassLoader.newInstance(urls);

    Class<?> mainClass = null;

    while (e.hasMoreElements()) 
    {
        JarEntry je = e.nextElement();
        if(je.isDirectory() || !je.getName().endsWith(".class")){
            continue;
        }

        String className = je.getName().substring(0, je.getName().length()-6);
        className = className.replace('/', '.');
        try
        {
            Class<?> c = cl.loadClass(className);
            if (className.equals("MyClass"))
            {
                mainClass = c;
                System.out.println("Found MyClass");
                try
                {
                    /** The method I use to invoke the main class */
                    Class<?> cls = Class.forName(className);
                    Method method = cls.getMethod("main", String[].class);
                    String[] params = new String[]{};
                    method .invoke(null, (Object) params);
                    jarFile.close();
                }
                catch (Exception ex)
                {
                    ex.printStackTrace();
                }
            }
            System.out.println("Loaded: " + className);
        }

        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }

    if (mainClass == null)
    {
        return;
    }
}
`

我基本上希望程序在 jar 中运行 main 方法并启动它。

标签: javaclassloader

解决方案


我真的不知道你为什么要Class.forName在你已经从正确的类加载器加载类时使用ClassLoader.loadClass.

删除线

Class<?> cls = Class.forName(className);

(它试图从行本身运行的类加载器加载类,这不是可以加载的类加载器MyClass

并将其后的行更改为:

Method method = c.getMethod("main", String[].class);

推荐阅读