ゲームで使用するクラスのリストを確実に取得できるように、jar 内の特定のディレクトリにあるファイルのリストを作成したい Java でゲームを作成しています。
たとえば、私のjarファイルにディレクトリがあるとします
mtd/entity/creep/
jar 内の別のクラスから Java コードを使用して、そのディレクトリ内のすべての .class ファイルのリストを取得したいと考えています。
そうするのに最適なコードは何ですか?
古いjava1.4コードですが、それはあなたにアイデアを与えるでしょう:
private static List getClassesFromJARFile(String jar, String packageName) throws Error
{
final List classes = new ArrayList();
JarInputStream jarFile = null;
try
{
jarFile = new JarInputStream(new FileInputStream(jar));
JarEntry jarEntry;
do
{
try
{
jarEntry = jarFile.getNextJarEntry();
}
catch(IOException ioe)
{
throw new CCException.Error("Unable to get next jar entry from jar file '"+jar+"'", ioe);
}
if (jarEntry != null)
{
extractClassFromJar(jar, packageName, classes, jarEntry);
}
} while (jarEntry != null);
closeJarFile(jarFile);
}
catch(IOException ioe)
{
throw new CCException.Error("Unable to get Jar input stream from '"+jar+"'", ioe);
}
finally
{
closeJarFile(jarFile);
}
return classes;
}
private static void extractClassFromJar(final String jar, final String packageName, final List classes, JarEntry jarEntry) throws Error
{
String className = jarEntry.getName();
if (className.endsWith(".class"))
{
className = className.substring(0, className.length() - ".class".length());
if (className.startsWith(packageName))
{
try
{
classes.add(Class.forName(className.replace('/', '.')));
} catch (ClassNotFoundException cnfe)
{
throw new CCException.Error("unable to find class named " + className.replace('/', '.') + "' within jar '" + jar + "'", cnfe);
}
}
}
}
private static void closeJarFile(final JarInputStream jarFile)
{
if(jarFile != null)
{
try
{
jarFile.close();
}
catch(IOException ioe)
{
mockAction();
}
}
}
おそらく最善の方法は、コンパイル時にクラスをリストすることです。
脆弱な実行時アプローチがあります。Class
(MyClass.class
の)を連れて行きますthis.getClass()
。コールしgetProtectionDomain
ます。コールしgetCodeSource
ます。コールしgetLocation
ます。コールしopenConnection
ます。(または、リソースを開きます。) にキャストしJarURLConnection
ます。コールしgetJarFile
ます。コールしentries
ます。チェックを繰り返しますgetName
。私は本当にこのアプローチをお勧めしません。
JARファイルは単に名前が変更されたZIPファイルであり、JavaでZIPファイルの内容を読み取るのは非常に簡単です。
File jarName = null;
try
{
jarName = new File (Dir.class.getProtectionDomain().getCodeSource().getLocation().toURI());
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
ZipFile zf=new ZipFile(jarName.getAbsoluteFile());
Enumeration e=zf.entries();
while (e.hasMoreElements())
{
ZipEntry ze=(ZipEntry)e.nextElement();
System.out.println(ze.getName());
}
zf.close();
} catch (IOException e)
{
e.printStackTrace();
}
Java は、クラスのロード元である jar ファイルへの直接アクセスを提供しないため、これは不可能です。java.class.path システム プロパティを解析して検索することもできますが、すべての状況でうまくいくとは限りません。または、jar ファイルが存在する必要がある場所を制限するか、別の方法で (たとえば、マニフェスト ファイルを介して) クラスのリストを提供することができます。