我正在尝试在外部java .jar文件中检索方法列表。该外部jar不会包含在我的构建路径中,我需要通过在外部代码中对其进行引用来完全获取信息。用例是在.jars中搜索已弃用的方法,这些方法已加载到我使用的应用程序中。
我在网上找到了一些解决方案并应用了它们,但是他们都希望Java或buildpath可以提供某些解决方案。我将只能提供文件/文件路径作为参数,并基于此派生所有内容。
现在,我的代码如下,我正在寻找有关如何以所需方式使用此代码的解决方案。任何帮助将不胜感激!
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);
}
最佳答案
您可以使用外部jar文件构造一个URLClassLoader
,并使用它来加载您在jar中发现的类。当拥有类对象时,可以调用getMethods()
和getDeclaredMethods()
来获取类的私有,受保护和公共方法。
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));
}