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

时间:2017-01-04 17:54:31

标签: java eclipse jar bukkit

我正在尝试使用我作为当前项目的API制作的.JAR文件。 This是API的GitHub页面,this是我正在处理的插件的代码。

我收到了这些错误:

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中,"导出为JAR文件"被检查(但不是" Runnable JAR文件")。

如何解决此问题并使用插件编译API?

2 个答案:

答案 0 :(得分:0)

右键单击您的项目 - > Java构建路径 - > Libaries - >添加外部罐子

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

depend: [Plugin1, Plugin2...]

答案 1 :(得分:0)

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

但是,如果此API本身不是插件,则由多个插件使用,请在服务器根目录创建一个lib目录,并将API JAR放入其中。 位于此目录中的任何JAR文件都将由Bukkit / 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中,将在单个JAR中创建一个包含插件和API类和接口的uber-JAR。该示例假设您的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工具中包含的内容。