カスタムアプリケーション用のプラグインをクラスロードすると、noclassdeffounderrorが生成されます
-
27-09-2019 - |
質問
クラスロードの概念に頭を巻きつけている問題がいくつかあります。しばらくの間プログラミングをしていますが、クラスロードの仕組みを比較的知っています。クラスロードとクラス自体の背後には、ある程度理解していますが、ある程度は私を逃れ、検索に優しい用語に入れるのはかなり難しいと思われます。
基本的に、私はMinecraftのために開発してきたゲームモードの「ギルド」を作成しようとしています。これらのギルドは独自のクラスにあり、スタートアップ時またはメソッド「reloadguildfiles()」が発行されるたびにゲームにロードされています。メインアプリケーションを最初にエクスポートし、作成されているギルドのクラスパスに追加し、メインアプリケーションの依存関係に追加することにより、これらのクラスを開発します。
これが「reloadguildfiles」メソッドです。
public void reloadGuildFiles() {
unloadGuildFiles();
synchronized ( _sync ) {
System.out.println( "Loading guild class files." );
File guildDataSourceDirectory = new File( "Prospect/Guilds/" );
URLClassLoader urlcl = null;
try {
urlcl = URLClassLoader.newInstance( new URL[] { guildDataSourceDirectory.toURI().toURL() }, Thread.currentThread().getContextClassLoader() );
} catch ( Exception e ) {
e.printStackTrace();
return;
}
if ( urlcl == null )
return;
for ( File guildDataFile : guildDataSourceDirectory.listFiles() ) {
if ( !guildDataFile.getName().endsWith( ".class" ) ) {
System.out.println( "Skipping " + guildDataFile.getName() );
continue;
}
try {
String className = guildDataFile.getName().substring( 0, guildDataFile.getName().lastIndexOf( "." ) );
System.out.println( "Loading: " + className + "\n" +
"\tfrom: " + guildDataFile.getPath() );
Class<?> clazz = urlcl.loadClass( className );
Object object = clazz.newInstance();
if ( object instanceof Guild == false ) {
System.out.println( "Object loaded is not an instance of Guild." );
continue;
}
Guild guild = ( Guild ) object;
if ( _guildMap.containsKey( guild.getName() ) ) {
System.out.println( "Duplicate guild names in guild map: " + guild.getName() );
continue;
}
_guildMap.put( guild.getName(), guild );
guild.onGuildLoaded();
} catch ( Exception e ) {
System.out.println( e.getMessage() );
e.printStackTrace();
continue;
}
}
}
}
}
メインアプリケーションに含まれるギルドクラスは次のとおりです。
public abstract class Guild {
public abstract String getName();
public void onGuildLoaded() {
System.out.println( "Loaded: " + getName() );
}
}
これが私がクラスロードしようとしているクラスです
public class Warrior extends Guild {
public String getName() {
returns "Warrior";
}
}
これが私に与えているエラーです:
java.lang.NoClassDefFoundError: Guild
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.net.FactoryURLClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at GuildManager.reloadGuildFiles(GuildManager.java:53)
at Prospect.enable(Prospect.java:64)
at PluginLoader.load(PluginLoader.java:205)
at PluginLoader.reloadPlugin(PluginLoader.java:189)
at je.d(je.java:1196)
at je.a(je.java:430)
at bg.a(SourceFile:24)
at bh.a(SourceFile:218)
at je.a(je.java:56)
at dp.a(SourceFile:85)
at net.minecraft.server.MinecraftServer.h(SourceFile:267)
at net.minecraft.server.MinecraftServer.run(SourceFile:208)
at bw.run(SourceFile:482)
Caused by: java.lang.ClassNotFoundException: Guild
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.net.FactoryURLClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 25 more
私が収集できるものから、私が理解していることから、メインアプリケーションはロードされるクラスのビルドパスにありますが、クラスローダーはクラスギルドを認識しません。クラスローダーにメインアプリケーションに含まれるギルドクラスを認識させる必要があると思います。
解決
ここで見ることができる唯一の問題はそれです Thread.currentThread().getContextClassLoader()
何らかの理由で、アクセスに使用できないクラスローダーを作成します Guild
クラス。
代わりにこれを試してください:
urlcl = URLClassLoader.newInstance( new URL[] { guildDataSourceDirectory.toURI().toURL() }, Guild.class.getClassLoader());
所属していません StackOverflow