0

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;

    }
}

クラスローダーを使用すると、置き換えられたクラスのいずれかを使用するたびに NoClassDefFoundError が発生します。私の最善の推測は、別のメソッドをオーバーライドする必要があるということですが、それが何であるかはわかりません。

エラーログ:

java.lang.NoClassDefFoundError: org/bukkit/craftbukkit/v1_5_R3/CraftServer
at me.leo.itemeffects.IEPlugin.onEnable(IEPlugin.java:25)
at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:217)
at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:457)
at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:381)
at org.bukkit.craftbukkit.v1_6_R2.CraftServer.loadPlugin(CraftServer.java:282)
at org.bukkit.craftbukkit.v1_6_R2.CraftServer.enablePlugins(CraftServer.java:264)
at net.minecraft.server.v1_6_R2.MinecraftServer.l(MinecraftServer.java:313)
at net.minecraft.server.v1_6_R2.MinecraftServer.f(MinecraftServer.java:290)
at net.minecraft.server.v1_6_R2.MinecraftServer.a(MinecraftServer.java:250)
at net.minecraft.server.v1_6_R2.DedicatedServer.init(DedicatedServer.java:151)
at net.minecraft.server.v1_6_R2.MinecraftServer.run(MinecraftServer.java:391)
at net.minecraft.server.v1_6_R2.ThreadServerApplication.run(SourceFile:582)

IEPlugin.java:25 は次のとおりです。

CraftServer server = (CraftServer) Bukkit.getServer();

jvm は間違った classDefinition を検索しています。パッケージ '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 に変更します

読んでくれてありがとう、そしてうまくいけば今後の解決策をありがとう。

4

2 に答える 2

0

まず、メソッドをオーバーライドするときは、その前に「@Override」と書くことが好ましいです。Eclipse などの一部のプログラムは、オーバーライドが正しくないかどうかを教えてくれます (オーバーライド規則のいくつかを守らなかった場合)。

次に、クラスは保護されています。つまり、クラスが実装されているパッケージでのみ表示されます。オーバーライドされたクラスがこれと同じパッケージにあると確信していますか? このようなエラーが発生する理由はおそらくそれです。

コードの大部分を投稿すると、助けが得られる可能性が高くなります。そうすれば、誰かが問題の場所を正確に教えてくれるかもしれません。

于 2013-07-25T20:32:59.837 に答える