Java 使用KyroNet时出现NoClassDefFoundError

Java 使用KyroNet时出现NoClassDefFoundError,java,Java,当我尝试使用kyronet(用于联网)时,我会遇到这个错误。代码中似乎没有任何错误,我正确地导出了它。以下是日志: [TextRPG] Starting TextRPG server version: 1.0 [TextRPG] Please ignore any messages by kyronet. This is just the API I used for networking. [TextRPG] Getting server directory... [TextRPG] Chec

当我尝试使用kyronet(用于联网)时,我会遇到这个错误。代码中似乎没有任何错误,我正确地导出了它。以下是日志:

[TextRPG] Starting TextRPG server version: 1.0
[TextRPG] Please ignore any messages by kyronet. This is just the API I used for networking.
[TextRPG] Getting server directory...
[TextRPG] Checking for server properties...
[TextRPG] Properties exists, injecting..
Exception in thread "main" java.lang.NoClassDefFoundError: com/esotericsoftware/kryo/io/Output
at com.esotericsoftware.kryonet.Server.<init>(Server.java:109)
at com.esotericsoftware.kryonet.Server.<init>(Server.java:91)
at dsboy08.TextRPGServer.ServerStartMain.<init>(ServerStartMain.java:34)
at dsboy08.TextRPGServer.ServerStartMain.main(ServerStartMain.java:69)
Caused by: java.lang.ClassNotFoundException:com.esotericsoftware.kryo.io.Output
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)
... 4 more
[TextRPG]正在启动TextRPG服务器版本:1.0
[TextRPG]请忽略kyronet发送的任何消息。这就是我用于联网的API。
[TextRPG]正在获取服务器目录。。。
[TextRPG]正在检查服务器属性。。。
[TextRPG]属性存在,正在注入。。
线程“main”java.lang.NoClassDefFoundError中出现异常:com/esotericsoftware/kryo/io/Output
位于com.esotericsoftware.kryonet.Server.(Server.java:109)
位于com.esotericsoftware.kryonet.Server.(Server.java:91)
位于dsboy08.TextRPGServer.ServerStartMain.(ServerStartMain.java:34)
位于dsboy08.TextRPGServer.ServerStartMain.main(ServerStartMain.java:69)
原因:java.lang.ClassNotFoundException:com.esotericsoftware.kryo.io.Output
位于java.net.URLClassLoader.findClass(URLClassLoader.java:381)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:424)
位于sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 4更多
以下是主类中的代码:

package dsboy08.TextRPGServer;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Scanner;

import javax.swing.JOptionPane;

import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;
import com.esotericsoftware.yamlbeans.YamlException;
import com.esotericsoftware.yamlbeans.YamlReader;
import com.esotericsoftware.yamlbeans.YamlWriter;

import dsboy08.TextRPGServer.ConfigVars.ServerProperties;
import dsboy08.TextRPGServer.Packets.Packet;

public class ServerStartMain {

/*
 * Variables & Declaration
 */

static double version = 1.0;
static String currentJarPath;
Server server = new Server();
public int ServerPort;
public int MaxPlayers;
public String ServerName;
public String MOTD;
public boolean serverEnabled = false;

/*
 * Server Start Sequence
 */

public static void main(String[] args) {
    System.out.println("[TextRPG] Starting TextRPG server version: "+version);
    System.out.println("[TextRPG] Please ignore any messages by kyronet. This is just the API I used for networking.");
    System.out.println("[TextRPG] Getting server directory...");
    //Get current jar path
    final Class<?> referenceClass = ServerStartMain.class;
    final URL url =
        referenceClass.getProtectionDomain().getCodeSource().getLocation();
    try{
        final String jarPath = new File(url.toURI()).getParentFile().toString();
        currentJarPath = jarPath;
    } catch(final URISyntaxException e){
        JOptionPane.showMessageDialog(null, "A critical error happended while trying to get the current directory of the jar. Please report this to @3dsboy08.");
        System.exit(-1);
    }
    System.out.println("[TextRPG] Checking for server properties...");
    File f = new File(currentJarPath + "/properties.yml");
    if(f.exists() && !f.isDirectory()) {
        System.out.println("[TextRPG] Properties exists, injecting..");
        //Server config exists. Get it for future reference
        ServerProperties config;
        try {
            YamlReader reader = new YamlReader(new FileReader(currentJarPath+"/properties.yml"));
            config = reader.read(ServerProperties.class);
            new ServerStartMain().readYML(config);
            System.out.println("[TextRPG] Binding to IP: "+getIpAddress());
        } catch (YamlException | FileNotFoundException e) {
            JOptionPane.showMessageDialog(null, "A critical error happended while trying to read the servers config file. Please report this to @3dsboy08.");
            System.exit(-1);
        }

    }else{
        System.out.println("[TextRPG] File properties.yml doesn't exist, creating it.");
        try {
            f.createNewFile();
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "A critcal error happended while trying to create the servers properties. Please report this to @3dsboy08.");
            System.exit(-1);
        }
        serverSetupWizard();
        //Server setup wizard is done. Get the output.
        try {
            YamlReader reader = new YamlReader(new FileReader(currentJarPath+"/properties.yml"));
            ServerProperties config = reader.read(ServerProperties.class);
            new ServerStartMain().readYML(config);
        } catch (FileNotFoundException | YamlException e) {
            JOptionPane.showMessageDialog(null, "A critical error happended while trying to read the servers config file. Please report this to @3dsboy08.");
            System.exit(-1);
        }
    }

}

/*
 * Server Setup Wizard.
 */

public static void serverSetupWizard(){
    boolean maxPlayersInvalid = true;
    boolean portInvalid = true;
    System.out.println("[TextRPG] Starting server setup wizard.");
    ServerProperties config = new ServerProperties();
    while(maxPlayersInvalid == true){
        String MaxPlayers = JOptionPane.showInputDialog(null, "Please enter in a maximum amount of players for the server.");
        try{
            config.MaxPlayers = Integer.parseInt(MaxPlayers);
            maxPlayersInvalid = false;
            break;
        }catch(NumberFormatException e){
            JOptionPane.showMessageDialog(null, "Error: Invalid amount of players.");
        }
    }
    config.MOTD = JOptionPane.showInputDialog(null, "Please enter in a MOTD for your server.");
    config.ServerName = JOptionPane.showInputDialog(null, "Please enter in a server name for your server.");
    while(portInvalid == true){
        String Port = JOptionPane.showInputDialog(null, "Please enter in a port for your server (it must be a 5-digit number).");
        try{
            if(!(Port.length() == 5)){
                JOptionPane.showMessageDialog(null, "Error: Invalid amount of port characters (must be 5)");
            }else{
                config.ServerPort = Integer.parseInt(Port);
                portInvalid = false;
                break;
            }
        }catch(NumberFormatException e){
            JOptionPane.showMessageDialog(null, "Error: Invalid port number.");
        }
    }
    try {
        YamlWriter writer = new YamlWriter(new FileWriter(currentJarPath+"/properties.yml"));
        writer.write(config);
        writer.close();
        System.out.println("[TextRPG] Successfully created server properties. Please restart the server.");
        System.exit(-1);
    } catch (IOException e) {
        JOptionPane.showMessageDialog(null, "A critical error happended while trying to write to the server properties. Please report this to @3dsboy08.");
        System.exit(-1);
    }
}

/*
 * Read YML
 */
public void readYML(ServerProperties config){
    MOTD = config.MOTD;
    ServerName = config.ServerName;
    ServerPort = config.ServerPort;
    MaxPlayers = config.MaxPlayers;
}

/*
 * Start Server
 */

public void startServer(){
    System.out.println("[TextRPG] Binding packets...");
    server.getKryo().register(Packet.class);
    System.out.println("[TextRPG] Done!");
    server.start();
    try {
        server.bind(ServerPort);
    } catch (IOException e) {
        JOptionPane.showMessageDialog(null, "A critical error happended while trying to bind to a server port (server in use). Please stop the server and try agian.");
    }
    server.addListener(new Listener(){
        public void received (Connection connection, Object object){
            if(object instanceof Packet){

            }
        }
    });

    while(serverEnabled == true){
        Scanner scanner = new Scanner(System.in);
        String commandNotConverted = scanner.nextLine();
        String[] command = commandNotConverted.split(" ");
        if(command[0].equalsIgnoreCase("stop")){
            serverEnabled = false;
            stopServer();
            break;
        }
    }

}

/*
 * Admin commands
 */

public void stopServer(){
    //TODO: Send server closing packet to all players
    System.out.println("[TextRPG] Server closing!");
    server.close();
    System.exit(0);
}


/*
 * Get IP Address 
 */

public static String getIpAddress() 
{ 
        URL myIP;
        try {
            myIP = new URL("http://api.externalip.net/ip/");

            BufferedReader in = new BufferedReader(
                    new InputStreamReader(myIP.openStream())
                    );
            return in.readLine();
        } catch (Exception e) 
        {
            try 
            {
                myIP = new URL("http://myip.dnsomatic.com/");

                BufferedReader in = new BufferedReader(
                        new InputStreamReader(myIP.openStream())
                        );
                return in.readLine();
            } catch (Exception e1) 
            {
                try {
                    myIP = new URL("http://icanhazip.com/");

                    BufferedReader in = new BufferedReader(
                            new InputStreamReader(myIP.openStream())
                            );
                    return in.readLine();
                } catch (Exception e2) {
                    e2.printStackTrace(); 
                }
            }
        }

    return null;
}
}
包dsboy08.TextRPGServer;
导入java.io.BufferedReader;
导入java.io.File;
导入java.io.FileNotFoundException;
导入java.io.FileReader;
导入java.io.FileWriter;
导入java.io.IOException;
导入java.io.InputStreamReader;
导入java.net.URISyntaxException;
导入java.net.URL;
导入java.util.Scanner;
导入javax.swing.JOptionPane;
导入com.esotericsoftware.kryonet.Connection;
导入com.esotericsoftware.kryonet.Listener;
导入com.esotericsoftware.kryonet.Server;
导入com.esotericsoftware.yamlbeans.YamlException;
导入com.esotericsoftware.yamlbeans.YamlReader;
导入com.esotericsoftware.yamlbeans.YamlWriter;
导入dsboy08.TextRPGServer.ConfigVars.ServerProperties;
导入dsboy08.TextRPGServer.Packets.Packet;
公共类ServerStartMain{
/*
*变量与声明
*/
静态双版本=1.0;
静态字符串路径;
服务器=新服务器();
公共int服务器端口;
公共int最大玩家;
公共字符串ServerName;
公共字符串MOTD;
public boolean serverEnabled=false;
/*
*服务器启动顺序
*/
公共静态void main(字符串[]args){
System.out.println(“[TextRPG]启动TextRPG服务器版本:“+version”);
System.out.println(“[TextRPG]请忽略kyronet的任何消息。这只是我用于联网的API。”);
System.out.println(“[TextRPG]正在获取服务器目录…”);
//获取当前jar路径
最终类引用类=ServerStartMain.Class;
最终URL=
referenceClass.getProtectionDomain().getCodeSource().getLocation();
试一试{
最后一个字符串jarPath=新文件(url.toURI()).getParentFile().toString();
currentJarPath=jarPath;
}捕获(最终URI异常e){
showMessageDialog(null,“试图获取jar的当前目录时发生了一个严重错误。请将此报告给@3dsboy08”);
系统退出(-1);
}
System.out.println(“[TextRPG]检查服务器属性…”);
文件f=新文件(currentJarPath+“/properties.yml”);
如果(f.exists()&&!f.isDirectory()){
System.out.println(“[TextRPG]属性存在,注入..”);
//服务器配置已存在。请获取它以备将来参考
服务器属性配置;
试一试{
YamlReader=newyamlreader(newfilereader(currentJarPath+“/properties.yml”);
config=reader.read(ServerProperties.class);
新的ServerStartMain().readYML(config);
System.out.println(“[TextRPG]绑定到IP:+getIpAddress());
}catch(YamlException | FileNotFound异常){
showMessageDialog(null,“尝试读取服务器配置文件时发生严重错误。请将此报告给@3dsboy08”);
系统退出(-1);
}
}否则{
System.out.println(“[TextRPG]File properties.yml不存在,正在创建它”);
试一试{
f、 createNewFile();
}捕获(IOE异常){
showMessageDialog(null,“尝试创建服务器属性时发生严重错误。请将此报告给@3dsboy08”);
系统退出(-1);
}
服务器设置向导();
//服务器安装向导已完成。获取输出。
试一试{
YamlReader=newyamlreader(newfilereader(currentJarPath+“/properties.yml”);
ServerProperties config=reader.read(ServerProperties.class);
新的ServerStartMain().readYML(config);
}catch(FileNotFoundException | YamlException e){
showMessageDialog(null,“尝试读取服务器配置文件时发生严重错误。请将此报告给@3dsboy08”);
系统退出(-1);
}
}
}
/*
*服务器安装向导。
*/
公共静态void服务器设置向导(){
布尔值maxPlayersInvalid=true;
布尔portInvalid=true;
System.out.println(“[TextRPG]启动服务器安装向导”);
ServerProperties config=newserverproperties();
while(maxPlayersInvalid==true){
String MaxPlayers=JOptionPane.showInputDialog(null,“请输入服务器的最大播放机数量”);
试一试{
config.MaxPlayers=Integer.parseInt(MaxPlayers);
maxPlayersInvalid=false;
打破
}捕获(数字格式){
showMessageDialog(null,“错误:无效的玩家数量”);
}
}
config.MOTD=JOptionPane.showInputDialog(null,“请为您的服务器输入MOTD”);
config.ServerName=JOptionPane.showInputDialog(null,“请输入服务器的服务器名称”);
while(portInvalid==true){
String Port=JOptionPane.showInputDialog(null),“请输入服务器的端口(它必须