2012-02-16 8 views
2

プロジェクトのすべてのパッケージを反映させるにはどうすればよいですか?私はPackage.getPackages()を使い始めましたが、それは現在のパッケージに関連付けられているすべてのパッケージしか持っていませんでした。これを行う方法はありますか?プロジェクト内のすべてのパッケージを反射的に入手できますか?

+1

あなたはプロジェクトとして何を定義しますか? – Perception

+0

@Perception - トップレベルパッケージとすべてのサブパッケージ。私はおそらく、プロジェクトをローカルプロジェクト、つまり単数のapiに置き換えるべきです。 – AedonEtLIRA

+1

http://stackoverflow.com/questions/1498122/java-loop-on-all-the-classes-in-the-classpath –

答えて

1

PhilippWendlerさんのコメント@。私は再帰的にするためにメソッドを少し微調整しました。

/** 
    * Recursively fetches a list of all the classes in a given 
    * directory (and sub-directories) that have the @UnitTestable 
    * annotation. 
    * @param packageName The top level package to search. 
    * @param loader The class loader to use. May be null; we'll 
    * just grab the current threads. 
    * @return The list of all @UnitTestable classes. 
    */ 
    public List<Class<?>> getTestableClasses(String packageName, ClassLoader loader) { 
     // State what package we are exploring 
     System.out.println("Exploring package: " + packageName); 
     // Create the list that will hold the testable classes 
     List<Class<?>> ret = new ArrayList<Class<?>>(); 
     // Create the list of immediately accessible directories 
     List<File> directories = new ArrayList<File>(); 
     // If we don't have a class loader, get one. 
     if (loader == null) 
      loader = Thread.currentThread().getContextClassLoader(); 
     // Convert the package path to file path 
     String path = packageName.replace('.', '/'); 
     // Try to get all of nested directories. 
     try { 
      // Get all of the resources for the given path 
      Enumeration<URL> res = loader.getResources(path); 
      // While we have directories to look at, recursively 
      // get all their classes. 
      while (res.hasMoreElements()) { 
       // Get the file path the the directory 
       String dirPath = URLDecoder.decode(res.nextElement() 
         .getPath(), "UTF-8"); 
       // Make a file handler for easy managing 
       File dir = new File(dirPath); 
       // Check every file in the directory, if it's a 
       // directory, recursively add its viable files 
       for (File file : dir.listFiles()) { 
        if (file.isDirectory()) 
         ret.addAll(getTestableClasses(packageName + '.' + file.getName(), loader)); 
       } 
      } 
     } catch (IOException e) { 
      // We failed to get any nested directories. State 
      // so and continue; this directory may still have 
      // some UnitTestable classes. 
      System.out.println("Failed to load resources for [" + packageName + ']'); 
     } 
     // We need access to our directory, so we can pull 
     // all the classes. 
     URL tmp = loader.getResource(path); 
     System.out.println(tmp); 
     if (tmp == null) 
      return ret; 
     File currDir = new File(tmp.getPath()); 
     // Now we iterate through all of the classes we find 
     for (String classFile : currDir.list()) { 
      // Ensure that we only find class files; can't load gif's! 
      if (classFile.endsWith(".class")) { 
       // Attempt to load the class or state the issue 
       try { 
        // Try loading the class 
        Class<?> add = Class.forName(packageName + '.' + 
          classFile.substring(0, classFile.length() - 6)); 
        // If the class has the correct annotation, add it 
        if (add.isAnnotationPresent(UnitTestable.class)) 
         ret.add(add); 
        else 
         System.out.println(add.getName() + " is not a UnitTestable class"); 
       } catch (NoClassDefFoundError e) { 
        // The class loader could not load the class 
        System.out.println("We have found class [" + classFile + 
          "], and couldn't load it."); 
       } catch (ClassNotFoundException e) { 
        // We couldn't even find the damn class 
        System.out.println("We could not find class [" + classFile + ']'); 
       } 
      } 
     } 
     return ret; 
    } 
0

あなたはクラスパスを自分で歩く必要があるので、難しいかもしれませんが高価です。ここではTestNGのは、それをしないか、あなたはおそらく自分のために重要な部分を抽出することができます:私は必要なものを達成するための方法に私を導いた

https://github.com/cbeust/testng/blob/master/src/main/java/org/testng/internal/PackageUtils.java

+0

このコードのように、クラスメンバnames.seemsのVectorと "m_"プレフィックスの接頭辞を使用するためのリンク - > Downvoteを少し見てください – aviad

+0

lol ...あなたの他の答えはオフトピックだった?高級。 –

+0

私はあなたを "笑"にさせてうれしいです。あなたの答えに私の最初のコメントでdownvoteの(部分的な)理由が説明されています。個人的なことはまったくありませんが、あなたのソリューションは間違っていて、コードは醜いと思います。時には、すぐに使いこなせるように考えて、その目的に最も適した技術を使用することは良いことです。 – aviad

-2

(それはjavaの「反射」という点で正確ではないため)オフトピックかもしれませ... しかし、どのように以下の解決策について:

Javaパッケージをフォルダとして扱うことができます(またはLinux \ UNIX上のディレクトリ)。 ルートパッケージとその絶対パスが知られているあなたは、あなたが再帰的根拠として次のバッチを使用して.javaファイルまたは* .classファイルを*しているすべてのサブフォルダを印刷することができていると仮定すると:

@echo off 
rem List all the subfolders under current dir 

FOR /R "." %%G in (.) DO (
Pushd %%G 
Echo now in %%G 
Popd) 
Echo "back home" 

することができますこのバッチをjavaでラップするか、またはLinux \ Unixで実行すると、いくつかのシェルスクリプトでそれを書き換えます。

Good Luck!

Aviad。

+1

これはJavaではなく、たとえそうであったとしても、カレントディレクトリのサブディレクトリを一覧表示するだけです。これは質問された質問とは関係ありません。 –

+0

@Cedric Beust、ここでは、解決策がJavaにあることがわかっていますか?(このプロジェクトはJavaにありますが、作成者は解決策について何の制限も言及していませんでした)。 Javaであまりにも多くの読み込み不可能なコーディングを伴うタスクが目的に合った他の "技術"でどのように実装できるかというアイデアを示しています。バッチが何をしているかについては、カレントディレクトリのサブディリストと何が問題なのか私のコメントは、あなたが "奇妙な"気分になったのですか?(あなたはいつでも投票の後に戻ることができます:) – aviad

+0

いいえ、質問はプロジェクトの "パッケージ"を見つける方法を尋ねます。"パッケージ"はJavaのコンセプトであり、質問には "java"というタグが付いているので、純粋にJavaの質問をしていることは明らかです。そして、これが当てはまらない場合でも、あなたのコードはパッケージではなくディレクトリの検索方法を示します。 –

0

この方法では、すべてのパッケージのみを表示します(少なくともルート "packageName"を最初に指定する必要があります)。

上記のものです。

package devTools; 

import java.io.File; 
import java.io.IOException; 
import java.net.URL; 
import java.net.URLDecoder; 
import java.util.ArrayList; 
import java.util.Enumeration; 
import java.util.List; 

public class DevToolUtil { 

    /** 
    * Method prints all packages (at least a root "packageName" has to be given first). 
    * 
    * @see http://stackoverflow.com/questions/9316726/reflectively-get-all-packages-in-a-project 
    * @since 2016-12-05 
    * @param packageName 
    * @param loader 
    * @return List of classes. 
    */ 
    public List<Class<?>> getTestableClasses(final String packageName, ClassLoader loader) { 
     System.out.println("Exploring package: " + packageName); 

     final List<Class<?>> ret = new ArrayList<Class<?>>(); 

     if (loader == null) { 
      loader = Thread.currentThread().getContextClassLoader(); 
     } 

     final String path = packageName.replace('.', '/'); 

     try { 
      final Enumeration<URL> res = loader.getResources(path); 

      while (res.hasMoreElements()) { 
       final String dirPath = URLDecoder.decode(res.nextElement().getPath(), "UTF-8"); 
       final File dir = new File(dirPath); 

       if (dir.listFiles() != null) { 
        for (final File file : dir.listFiles()) { 
         if (file.isDirectory()) { 
          final String packageNameAndFile = packageName + '.' + file.getName(); 
          ret.addAll(getTestableClasses(packageNameAndFile, loader)); 
         } 
        } 
       } 
      } 
     } catch (final IOException e) { 
      System.out.println("Failed to load resources for [" + packageName + ']'); 
     } 

     return ret; 
    } 

    public static void main(final String[] args) { 
     new DevToolUtil().getTestableClasses("at", null); 
    } 
} 
関連する問題