ClassNotFoundException当在eclipse构建路径(minecraft插件)中使用另一个jar文件时



我正在尝试使用我作为当前项目的API创建的.JAR文件。这是API的GitHub页面,这是我正在开发的插件的代码

我得到这些错误:

04.01 17:32:03 [Server] INFO Caused by: java.lang.NoClassDefFoundError: me/Andrew/XenforoAPI/SiteAPI
04.01 17:32:03 [Server] INFO at me.Andrew.BreezeSiteLink.APICaller.postApplication(APICaller.java:16) ~[?:?]
04.01 17:32:03 [Server] INFO at me.Andrew.BreezeSiteLink.Main.onCommand(Main.java:84) ~[?:?]
04.01 17:32:03 [Server] INFO at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spigot.jar:git-Spigot-5391d73-0ebb9c7]
04.01 17:32:03 [Server] INFO ... 15 more
04.01 17:32:03 [Server] INFO Caused by: java.lang.ClassNotFoundException: me.Andrew.XenforoAPI.SiteAPI
04.01 17:32:03 [Server] INFO at java.net.URLClassLoader$1.run(URLClassLoader.java:359) ~[?:1.7.0_121]
04.01 17:32:03 [Server] INFO at java.net.URLClassLoader$1.run(URLClassLoader.java:348) ~[?:1.7.0_121]
04.01 17:32:03 [Server] INFO at java.security.AccessController.doPrivileged(Native Method) ~[?:1.7.0_121]
04.01 17:32:03 [Server] INFO at java.net.URLClassLoader.findClass(URLClassLoader.java:347) ~[?:1.7.0_121]
04.01 17:32:03 [Server] INFO at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:101) ~[spigot.jar:git-Spigot-5391d73-0ebb9c7]

在Eclipse中,会选中"Export as JAR file"(但不会选中"Runnable JAR file")。

如何解决这个问题并让API使用插件进行编译?

如前所述,错误是由于插件找不到API库而导致的。在大多数情况下,我建议您将该依赖项包含在插件的JAR中。

但是,如果这个API(它本身不是一个插件)被多个插件使用,请在服务器根目录创建一个lib目录,并将API JAR放在其中位于该目录中的任何JAR文件都将由Bukket/Spigot加载,并可用于所有插件

编辑:

正如我在评论中提到的,我已经使用这种技术很长时间了,我认为这是Bukkit的一个特点。唉,事实并非如此。

在MANIFEST.MF中添加Classpath

将以下maven-jar-plugin配置添加到POM中,可以确保任何范围为compile的依赖项都将添加到插件的类路径中。类路径相对于插件的位置(plugin目录),因此../lib/是服务器根目录中的lib目录。

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifestEntries>
<Built-By>You</Built-By>
</manifestEntries>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>../lib/</classpathPrefix>
</manifest>
</archive>
/configuration>
</plugin>

本质上,这在插件的META-INF/MANIFEST.MF中创建了一个引用API库的条目,类似于以下内容:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: You
Class-Path: ../lib/my-api.jar
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_73

创建一个Uber JAR

上面的解决方案对我们来说效果很好,为维护我们几个内部插件使用的库提供了一个单一的位置。然后,我们运行自己的服务器。

如果你的长期计划是发布你的插件供他人使用,这个解决方案并不理想。虽然它可以工作,但它需要服务器操作员的额外工作,除非API库的安装是自动化的。再说一遍,安装服务器操作员所期望的以外的文件可能也不是一个好主意。

一个更好的解决方案是创建一个uber-JAR,其中包括您的代码和任何唯一的依赖项,例如您的API。它消除了安装API JAR的需要,就像上面的例子一样。更重要的是,随着插件的新版本发布,它避免了潜在的版本不匹配。

将下面的maven-shade-plugin配置添加到POM中,将创建一个uber-JAR,其中包括单个JAR中的插件和API类和接口。该示例假设您的API具有Maven坐标me.andy:myapi:1.0

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>me.andy:myapi:1.0</artifact>
<includes>
<include>**</include>
</includes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>

运行mvn install后,您将在target目录中找到三个JAR文件(文件名明显不同):

  • original-myplugin-1.0.jar-原始JAR,因为它本来是正常创建的
  • myplugin-1.0-shaded.jar-组合JAR
  • myplugin-1.0.jar-具有减少依赖关系的组合JAR。这是最后一个插件JAR

您可以验证任何流行的ZIP工具中包含的内容。

右键单击Projct->Java构建路径->库->添加外部Jars

然后,您可以选择要在项目中使用的jar/api,但也不要忘记将其添加到plugin.yml中的依赖项中:

depend: [Plugin1, Plugin2...]

最新更新