【问题标题】:Load class within Jar file and get it's path在 Jar 文件中加载类并获取它的路径
【发布时间】:2013-09-06 20:15:15
【问题描述】:

我知道这里已经有很多类似的问题,但我无法从它们那里得到更聪明的答案。我想在 jar 文件中加载一个类,此时这没问题,但是当我想将路径传递给我自己的 ClassLoader 时,它会抛出一个异常,它找不到该类。是否可以使用绝对路径在 jar 中加载类?例如,
Class cls = loader.loadClass(/path/MyPlugin.jar/MyPlugin.class);

但是当我这样做时:

File test = new File("path/plugins/MyPlugin.jar/MyPlugin.class");
System.out.println(test.exists());

它打印出错误。我尝试使用有时在网络上看到的 MyPlugin.jar!/MyPlugin.classMyPlugin.jar.jar!MyPlugin.class,尽管我真的不知道这意味着什么...

当我这样做时,它会找到类:

URLClassLoader loader = new URLClassLoader(new URL[] { "path/plugins/MyPlugin.jar" });
Class cl = loader.loadClass("MyPlugin");

但是现在,我怎样才能接收到路径? URL url = cl.getResource("MyPlugin"); 之类的东西(返回 null)

【问题讨论】:

  • 弱猜测:你试过cl.getResource(),而不是cls.getResource();
  • 对不起,我的错,只是打字错误。

标签: java plugins jar classloader urlclassloader


【解决方案1】:

您可以使用ClassLoader.getResources 获取类路径资源的 URL。要查找具有特定类的 jar,您可以使用以下

URL url = classLoader.getResource("com/example/SomeClass.class");
JarURLConnection connection = (JarURLConnection) url.openConnection();
JarFile file = connection.getJarFile();
String jarPath = file.getName();

其中classLoader 是任何能够找到您要加载的类的类加载器。如果 jar 是应用程序类路径的一部分,则可以使用系统类加载器:

ClassLoader classLoader = ClassLoader.getSystemClassloader();

否则需要事先知道jar文件位置,并创建URLClassLoader的实例,在构造函数中传递jar:

ClassLoader classLoader = new URLClassLoader(new URL[]{new URL("path/to/the/jar/file.jar")});

然后用它来加载你的类。

【讨论】:

  • 我试过了,虽然我不知道我是否做对了。这在实践中会是什么样子?
  • 再想想,手动字符串操作是没有必要的。查看我的编辑。
  • 对不起,我是新来的。类加载器指的是什么?那么example实际上是一个名为example.jar的jar?
  • 好吧...如果您知道类名和 jar 位置,则可以使用我回答的第二部分中的方法。如果您已经加载了该类,则可以使用第一部分的建议。否则,我看不出有什么办法;如果该类不在类路径中并且您不知道哪些 jar 包含其定义,则无法加载该类。
  • 嗯,这是因为当路径存在时,File API 不支持 jar。它无法查看 jar 内部并看到确实有 MyPlugin.class 文件。如果不更改PluginClassLoader,恐怕您无法做到。
【解决方案2】:

如果你想访问你的 jar 文件中的一个文件,你必须把它和类文件放在同一个目录中。

例如,如果 Main.class 在 bin/my/pkg/Main.class 中,您可以将 MyPlugin.class 存储在同一目录 (bin/my/pkg/MyPlugin.class) 中,然后,如果您想访问该文件使用

URL url = Main.getResource("MyPlugin.class");

它使用你项目中 Main.class 的位置作为根。

希望对你有帮助!

【讨论】:

  • 这不太对。 Jar 文件需要在类路径中。将 jar 放在类路径上不会使其成为类路径的一部分。
  • 尝试此URL url = PluginTest.getResource("MyPlugin.class"); 时出错。并在尝试此操作时收到 null:URL url = this.getClass().getClassLoader().getResource("MyPlugin.class");
  • 您知道您需要使用完全限定名称,用/ 代替点吗?
  • 所以我需要做这个“MyPlugin/class”?
  • 假设你的插件是com.example.MyPlugin,你需要com/example/MyPlugin.class。如果它在默认包中,MyPlugin.class 确实应该这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-29
  • 2018-12-31
  • 2014-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多