Java NoClassDefFoundError(更改类名)

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

我试图通过重写loadClass(String,Boolean)方法来更改类名

我正在创建一个BukkitPlugin。可以找到Bukkitsource

类加载器本身工作正常,我对它进行了测试,所有的类都工作正常,在我开始更改类名后,错误开始出现

方法如下:

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();