Java 使用KyroNet时出现NoClassDefFoundError
当我尝试使用kyronet(用于联网)时,我会遇到这个错误。代码中似乎没有任何错误,我正确地导出了它。以下是日志: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
[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),“请输入服务器的端口(它必须