Java NoClassDefFoundError(更改类名)
我试图通过重写loadClass(String,Boolean)方法来更改类名 我正在创建一个BukkitPlugin。可以找到Bukkitsource 类加载器本身工作正常,我对它进行了测试,所有的类都工作正常,在我开始更改类名后,错误开始出现 方法如下:Java NoClassDefFoundError(更改类名),java,noclassdeffounderror,urlclassloader,Java,Noclassdeffounderror,Urlclassloader,我试图通过重写loadClass(String,Boolean)方法来更改类名 我正在创建一个BukkitPlugin。可以找到Bukkitsource 类加载器本身工作正常,我对它进行了测试,所有的类都工作正常,在我开始更改类名后,错误开始出现 方法如下: import java.io.File; import java.lang.reflect.Field; import java.net.URL; import java.net.URLClassLoader; import java.ut
import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import org.bukkit.plugin.java.JavaPlugin;
public class PluginClassLoader extends URLClassLoader {
private final HashMap<String, String> replace;
public PluginClassLoader(JavaPlugin p, HashMap<String, String> replace) throws Exception {
super(new URL[0], p.getClass().getClassLoader());
this.replace = replace;
File f = null;
Field file = JavaPlugin.class.getDeclaredField("file");
file.setAccessible(true);
f = (File) file.get(p);
addURL(f.toURI().toURL());
}
private final HashMap<String, Class<?>> classes = new HashMap<>();
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
String s = replace.get(name);
if(s != null)
name = s;
Class<?> c;
try {
c = findClass(name);
} catch (Exception e) {
c = super.loadClass(name);
}
return c;
}
@Override
protected Class<?> loadClass(String name, boolean b)
throws ClassNotFoundException {
String s = replace.get(name);
if(s != null)
name = s;
Class<?> c;
try {
c = findClass(name);
} catch (ClassNotFoundException e) {
c = super.loadClass(name, b);
}
return c;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
if ((name.startsWith("org.bukkit."))
|| (name.startsWith("net.minecraft."))) {
throw new ClassNotFoundException(name);
}
Class<?> result = classes.get(name);
if (result == null) {
result = super.findClass(name);
classes.put(name, result);
}
return result;
}
}
IEPlugin.java:25是这样的:
CraftServer server = (CraftServer) Bukkit.getServer();
jvm正在搜索错误的类定义,它在查找包为“v1_5_R3”的类,但我将loadClass()中的类名称替换为“v1_6_R2” 我正在将类名“org.bukkit.craftbukkit.v1_5_R3.CraftServer”替换为“org.bukkit.craftbukkit.v1_6_R2.CraftServer” 包含v1_5_R3的包中的类不存在,因此我在loadClass(String,Boolean)方法中将其更改为v1_6_R2
感谢您的阅读和希望即将到来的解决方案。首先,当您重写一个方法时,建议在其“@override”之前写入该方法。有些程序(如Eclipse)会告诉您覆盖是否不正确(如果您建议使用某些覆盖规则) 其次,您的类是受保护的,这意味着它将只在它实现的包中看到。您确定重写的类与此类在同一个包中吗?也许这就是你犯这样一个错误的原因
如果你发布了更大一部分的代码,就更有可能得到帮助。这样,也许有人能够准确地告诉您问题所在。通常,ClassNotFoundException表示未找到当前类,NoClassDefFoundError表示未找到当前加载类的依赖类(请参见此)。可能您替换的类具有类路径中不存在的依赖项。首先,向我们显示您的
noclasdefounderror
。第二,尝试这样重命名一个类是非常愚蠢的。请共享错误消息,也不要重写该方法。为什么不更改类名,即String,然后将其传递给该方法。jvm正在搜索错误的类定义,但整个错误不会在控制台中打印出来。errorloag dosent显示了“真实”原因。虽然您已将该类替换为v1_6_R2,但类装入器仍然开始加载v1_5_R3类。所以,我相信报告的错误仍然是v1_5_R3。您可能希望将v1_5_R3的字节流替换为v1_6_R2的ByTestStream,并调用defineClass,而不是使用新的类名再次重定向到loadClass。找到并返回CraftServer类时没有错误,返回类后会发生错误,我打印了加载程序搜索的类和加载程序返回的类,并且正确返回了serverclass。这意味着错误不是在loadclass中抛出的,而是在其他地方抛出的。
CraftServer server = (CraftServer) Bukkit.getServer();