【问题标题】:URLClassLoader keeps throwing ClassNotFoundException. What am I doing wrong?URLClassLoader 不断抛出 ClassNotFoundException。我究竟做错了什么?
【发布时间】:2014-06-21 09:07:29
【问题描述】:

我正在从事一个大学 Java 项目,该项目需要我实现一个简单的插件架构。项目 A 中的主应用程序必须从位于另一个项目 B 中的指定目录加载插件。在对该主题(包括 stackoverflow)进行了一些研究之后,我决定使用 URLClassLoader 来加载我可能会实例化的类。项目 B 引用项目 A 并且所有插件都扩展了一个通用插件类(也可能是一个接口,但不应该有任何区别)。这是我到目前为止所得到的:

我尝试加载的插件类的源代码:

package plugin;

import de.uks.student.pluginpattern.model.EditorPlugin;

public class Circle extends EditorPlugin
{
   @Override
   public void init()
   {

   }
}

以及应该加载类的代码:

public void init(String[] args)
   {
      editorPane = new EditorPane().withWidth(500).withHeight(500);
      toolBar = new ToolBar();
      plugins = new EditorPluginSet();
      // load plugins
      File pluginDir = new File(PLUGIN_PATH);
      if (!pluginDir.exists())
      {
         System.err.println("Plugin path not found!!");
         return;
      }
      String[] plugins = pluginDir.list();
      if (plugins == null)
      {
         System.err.println("Plugin path points to a file!!");
         return;
      }

      for (String pluginString : plugins)
      {
         for (String argString : args)
         {
            if (pluginString.contains(argString))
            {
               System.out.println("Loading plugin from " + pluginString);
               File pluginFile = new File(PLUGIN_PATH + "/");
               // as getAbsolutePath embeds the relative path ... /../pluginProject ...
               // which may not be processed correctly by the OS (Windows at least),
               // we correct the path manually (just to be on the safe side)
               String absolutePath = pluginFile.getAbsolutePath();
               String[] split = absolutePath.split("\\\\");

               List<String> splitsimpleList = Arrays.asList(split);
               ArrayList<String> splitList = new ArrayList<>(splitsimpleList);
               for (int i = 0; i < splitList.size() - 1; ++i)
               {
                  if (splitList.get(i + 1).equals(".."))
                  {
                     splitList.remove(i);
                     splitList.remove(i);
                     break;
                  }
               }
               StringBuilder b = new StringBuilder();
               for (String string : splitList)
               {
                  b.append(string);
                  b.append("/");
               }
               File pluginFileForRealThisTime = new File(b.toString());

               URL pluginURL = null;
               try
               {
                  pluginURL = pluginFileForRealThisTime.toURI().toURL();
               } catch (MalformedURLException e)
               {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
               }
               URL[] urls = {pluginURL};
               ClassLoader parentClassLoader = this.getClass().getClassLoader();
               URLClassLoader uLoader = new URLClassLoader(urls, parentClassLoader);
               Class<?> pluginClass = null;
               try
               {
                  String className = "plugin." + argString;
                  pluginClass = uLoader.loadClass(className);
               } catch (ClassNotFoundException e)
               {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
               }
            }
         }
      }
   }

现在我总是以 ClassNotFoundException 告终:

java.lang.ClassNotFoundException: plugin.Circle at java.net.URLClassLoader$1.run(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) 在 java.net.URLClassLoader.findClass(未知来源)在 java.lang.ClassLoader.loadClass(Unknown Source) 在 java.lang.ClassLoader.loadClass(Unknown Source) 在 de.uks.student.pluginpattern.model.EditorSystem.init(EditorSystem.java:412) 在 de.uks.student.pluginpattern.EditorSystem.main(EditorSystem.java:13)

我已经检查过了

  • 生成的 URL 可以被任何网络浏览器和 Windows 资源管理器正确解析。
  • Circle.class 已构建并存在于使用的 URL 引用的目录中
  • className 解析为“plugin.Circle”,这应该是要使用的正确二进制名称
  • 从 plugin.Circle 中删除继承没有任何区别。

我几乎没有什么可以尝试的想法。我做错了什么?

【问题讨论】:

  • 确保您添加到 ClassLoader 的文件确实存在于您所在的位置,您可以使用 File#exists 进行测试
  • 并且您应该能够使用 File#getCanonicalFile 来解析到“直接”路径等效的相对路径
  • 另外,根据您的代码,您可能正在加载多个文件,每个文件都在自己的类加载器中,这可能意味着您要查找的类可能不存在于您刚刚加载的文件中。 ..
  • 我让它工作了!我的错误是将 URLClassLoader 指向插件目录,而我应该使用 bin 目录。现在可以使用了。
  • 所有这些字符串操作看起来都非常混乱。 file.toURI().normalize().toURL() 有效吗?

标签: java classloader classnotfoundexception urlclassloader


【解决方案1】:

我必须将 ClassLoader 指向 bin 文件夹而不是 bin/plugins 文件夹

【讨论】:

    猜你喜欢
    • 2016-06-11
    • 2013-08-06
    • 1970-01-01
    • 2022-06-10
    • 2023-01-19
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 2019-12-23
    相关资源
    最近更新 更多