4

Rodリフレクションを使用して、jar ファイルからカスタム オブジェクト ( ) をロードしようとしています。jarファイルを見つけてクラスをスキャンして必要な注釈を取得することができましたが、呼び出すたびに、ロードしようとしているクラスが拡張されているクラスをclassLoader.loadClass()取得します。ClassNotFoundException

これは ClassLoader のコードです。

public static Set<Rod> getRods(File rodDirectory) throws Exception {
    rodDirectory.mkdir();
    URLClassLoader classLoader;
    Set<Rod> rods = new HashSet<Rod>();

    for (File f : rodDirectory.listFiles()) {
        if (f.isDirectory() || !f.getName().endsWith(".jar"))
            continue;

        JarFile jar = new JarFile(f);
        Enumeration<JarEntry> e = jar.entries();
        classLoader = URLClassLoader.newInstance(new URL[]{new URL("jar:file:" + f.getAbsolutePath() + "!/")});

        while (e.hasMoreElements()) {
            JarEntry j = (JarEntry) e.nextElement();
            if(j.isDirectory() || !j.getName().endsWith(".class")){
                continue;
            }
            Class<?> c = classLoader.loadClass(j.getName().substring(0, j.getName().length() - 6));
            CustomRod a = c.getAnnotation(CustomRod.class);
            if (a == null)
                continue;
            if (a.minimumVersion() < RodsTwo.getVersion())
                continue;
            rods.add((Rod) c.getConstructor().newInstance());
        }

        jar.close();

    }
    return rods;
}

これは、ロードしようとしている jar 内のコードです。

import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;

import ca.kanoa.RodsTwo.Objects.ConfigOptions;
import ca.kanoa.RodsTwo.Objects.CustomRod;
import ca.kanoa.RodsTwo.Objects.Rod;

@CustomRod(minimumVersion=1.001)
public class Test extends Rod {

    public Test() throws Exception {
        super("Test", 1, 46, new ConfigOptions(), 200);
    }

    @Override
    public boolean run(Player arg0, ConfigurationSection arg1) {
        arg0.sendMessage("HI!");
        return true;
    }



}

そして、私の他のすべてのコードはhere で見つけることができます。

リフレクションをいじり始めたところです。

4

2 に答える 2

0

JAR には、カスタム サブクラスが必要とする他のクラスが存在する可能性がありますが、1 つのクラス ファイルのみを選択しています。

たとえば、誰かが作成AbstractCustomRodし、それMyCustomRodを拡張して両方を JAR ファイルに入れるのはどちらでしょうか? コードは をスキップしAbstractCustomRod、読み込めMyCustomRodません。

Rod から以外の継承がなく、JAR ファイルにヘルパー クラスがないことを指定したい場合、JAR が追加する唯一の価値は、署名できることです。それを気にしない場合は、プレーンな .class ファイルを受け取ることができます。これにより、正確に 1 つのクラスであることが保証されます。

実際に行っていることによっては、この全体的な設計を再考する必要がある場合があります。この種のことは、親クラスの変更に対して非常に脆弱であり、これらのカスタム サブクラスがどこから来たのかによっては、非常に簡単に実行してしまう可能性があります。悪質なコード。

于 2013-09-16T17:40:12.417 に答える
0

OP コードは から名前を取得しJarEntry、 を取り除き、".class"を呼び出しますClassLoader.loadClass

ZIP エントリの「名前」は、「/」文字で区切られた相対パスです (すべてのプラットフォーム)。ただし、loadClass「.」で区切られたバイナリ名が必要です。文字。したがって、名前のすべての「/」文字を「.」に置き換えます。

.replace('/', '.')
于 2021-02-02T18:24:55.893 に答える