2017-02-27 25 views
0

外部java .jarファイル内のメソッドのリストを取得しようとしています。この外部ジャーは私のビルドパスには含まれません。私はコードを外部で参照することによって情報を完全に取得する必要があります。ユースケースは、私が扱っているアプリにロードされている.jars内の非推奨のメソッドを検索することです。外部Java .jarファイルからメソッドを取得

私はいくつかのソリューションをオンラインで見つけ出し、それらを適用しましたが、それらはすべて、Javaまたはビルドパスのネイティブであることを期待しています。私は引数としてファイル/ファイルパスのみを提供し、これに基づいてすべてを導き出すことができます。

私のコードは以下の通りですが、私はこれを私が必要としている方法でどのように使用するかについての解決策を探しています。どんな助けでも大歓迎です!

public static void main(String[] args) throws IOException { 

    Collection<Class<?>> classes = new ArrayList<Class<?>>(); 

    JarFile jar = new JarFile("C:\\app\\folder\\jar\\file.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); 
     System.out.println(classname); 

      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

まず、_classes_をJVMでロードするか、_bytecode_を配列で使用するかどうかを判断する必要があります。アプローチは大きく異なります。 –

+0

'java.util.ServiceLoader'をお探しですか? – EJP

答えて

1

あなたは、外部のjarファイルをURLClassLoaderを構築することができ、それはあなたが瓶の中に発見分類ロードするためにそれを使用。クラスオブジェクトがあるときは、getMethods()getDeclaredMethods()を呼び出して、クラスのprivate、protected、およびpublicメソッドを取得できます。

public static void main(String[] args) throws Exception { 
     Set<Class<?>> classes = new HashSet<>(); 

     URL jarUrl = new URL("file:///C:/app/folder/jar/file.jar"); 
     URLClassLoader loader = new URLClassLoader(new URL[]{jarUrl}); 
     JarFile jar = new JarFile("C:\\app\\folder\\jar\\file.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).split("\\$")[0]; 
//    System.out.println(classname); 

       try { 
        Class<?> c = loader.loadClass(classname); 
        classes.add(c); 
       } catch (Throwable e) { 
        System.out.println("WARNING: failed to instantiate " + classname + " from " + file); 
       } 
      } 
     } 
     Map<String, List<Method>> collected = 
       classes.stream().collect(Collectors.toMap(Class::getName, clz -> { 
        List<Method> methods = new ArrayList<>(Arrays.asList(clz.getDeclaredMethods())); 
        methods.addAll(Arrays.asList(clz.getMethods())); 
        return methods; 
       })); 

     collected.forEach((clz, methods) -> System.out.println("\n" + clz + "\n\n" + methods)); 
    } 
関連する問題