2011-10-19 10 views
5

私は30クラス以上のjarファイルを持っています。私が望むのは、メインメソッドの冒頭で、このジャーの中からJavaのリフレクション機能を使用して、jarの各クラスへの参照がClassという参照を取得するクラスを呼び出すことです。私の最終的な目標は、何らかの操作を実行し、すべてのクラスに対して定義された変数を照会することです。基本的に私は何かのようなものを探しています。標準的なリフレクションAPIを使用してこれを行う簡単な方法はありますか、または動作するソリューションを作るのは面倒です。jarの各クラスのClassオブジェクトを取得する方法

List l = Reflection.getAllClasses(); 
String var; 
foreach(Class c : l) { 
    var = c.getField("fieldname"); 
    doSomething(var); 
} 

編集:

ちょうどそれを明確にする:コードを検査瓶をwithingから実行されます。

+0

Jarファイルが作成されたときにクラスのリストを(たとえば 'Properties'ファイルを使用して)含めないでください。終わりの目標を述べるのに+1。 –

+0

@AndrewThompson私はこの管理負担を負いたくないので、常にファイルのリストを覚えています。 – LordDoskias

+0

リストをビルドプロセスの一部として準備するクラスを書くことは自明です。負担が全くありません。 –

答えて

6

は、これは私のためのトリックを行います。

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Collection; 
import java.util.Enumeration; 
import java.util.jar.JarEntry; 
import java.util.jar.JarFile; 


public class ClassFinder 
{ 
    public static void main(String[] args) throws IOException 
    { 
    Collection<Class<?>> classes = new ArrayList<Class<?>>(); 

    JarFile jar = new JarFile("/home/nono/yamts/yamts.jar"); 
    for (Enumeration<JarEntry> entries = jar.entries() ; entries.hasMoreElements() ;) 
    { 
     JarEntry entry = entries.nextElement(); 
     String file = entry.getName(); 
     if (file.endsWith(".class")) 
     { 
      String classname = file.replace('/', '.').substring(0, file.length() - 6); 
      try 
      { 
       Class<?> c = Class.forName(classname); 
       classes.add(c); 
      } 
      catch (Throwable e) 
      { 
       System.out.println("WARNING: failed to instantiate " + classname + " from " + file); 
      } 
     } 
    } 

    for (Class<?> c : classes) 
     System.out.println(c); 
    } 
} 
+0

しかし、これは外部のjarファイルのために働くでしょう。上記のコードがターゲットと同じjarを使って実行される場合はどうなりますか?編集:また、あなたのコードは私のために動作しません。すべてのクラスについて、「インスタンス化に失敗しました」と返されます。 – LordDoskias

+0

jarがクラスパスにある限り、クラス定義を取得できます。指定されたjarがクラスパスにない場合は、おそらくカスタムクラスローダーに余分な作業をする必要があります。 – dagnelies

+0

完璧に働いた、ありがとう非常に – LordDoskias

1

JARファイル内のすべてのクラスをリストすることは、リフレクションで行うことはできません。

ただし、JarInputStreamを使用して行うことができます。

+0

また、JarInputStreamを使わないで、JarFile(受け入れられた答えが示すように)を使って:) – Grodriguez

0

次のソリューションは、あなたのclasspathにしたり、classpath外にあるjarで動作します。

try { 
     File pathToJar = new File("C:/some.jar"); 

     JarFile jarFile; 
      jarFile = new JarFile(pathToJar); 
     Enumeration<JarEntry> e = jarFile.entries(); 

     URL[] urls = { new URL("jar:file:" + pathToJar+"!/") }; 
     URLClassLoader cl = URLClassLoader.newInstance(urls); 

     while (e.hasMoreElements()) { 
      JarEntry je = e.nextElement(); 
      if(je.isDirectory() || !je.getName().endsWith(".class")){ 
       continue; 
      } 
      // -6 because of .class 
      String className = je.getName().substring(0,je.getName().length()-6); 
      className = className.replace('/', '.'); 
      System.out.println("Checking for class " + className); 
      Class c = cl.loadClass(className); 


      System.out.println("Class object " + c.getName()); 

     } 
    } catch (IOException | ClassNotFoundException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 
関連する問題