У меня есть метод getAllTests (), который загружает внешний jar-файл в папку и с помощью метода поиска Reflection с Annotation Test (@Test). Я использую:
URLClassLoader
класс для загрузки Jar File;
Class currentClass=child.loadClass(classname);
для класса загрузки;
Method method = currentClass.getMethods()[i];
Annotation annTest = method.getAnnotation(Test.class);
для получения метода и получения аннотации.
Мой код такой:
public static void getAllTests() throws IllegalArgumentException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException,LinkageError, ClassNotFoundException {
TestLoaderApplication.testClassObjMap.clear(); <--is a HashMap class
LoadLibrary loadLibrary=new LoadLibrary();<--used for search all file .jar in folder
List<JarFile> jarList= loadLibrary.getListJar(pathJars).stream().map(f -> {
try {
return new JarFile(f);
} catch (IOException e) {
e.printStackTrace();
}
return null;
})
.collect(Collectors.toList());
for (JarFile j : jarList) {
URLClassLoader child = new URLClassLoader(
new URL[] {new File(j.getName()).toURI().toURL()},
ServiceUtil.class.getClassLoader()
);
for (Enumeration<JarEntry> entries = j.entries(); entries.hasMoreElements(); ) {
JarEntry entry = entries.nextElement();
String file = entry.getName();
if (file.endsWith(".class")) {
String classname = file.replaceAll("/", ".")
.substring(0, file.lastIndexOf("."));
try {
Class currentClass=child.loadClass(classname);
List<String> testMethods = new ArrayList<>();
for (int i = 0; i < currentClass.getMethods().length; i++) {
Method method = currentClass.getMethods()[i];
Annotation annTest = method.getAnnotation(Test.class);
Annotation annTestFactory = method.getAnnotation(TestFactory.class);
if (annTest != null || annTestFactory != null) {
testMethods.add(method.getName());
}
}//fine for metodi
if (testMethods.size() >=1) {
testClassObjMap.put(j.getName().substring(j.getName().lastIndexOf("\\")+1),classname,testMethods);
TestLoaderApplication.testClassObjMap.put(j.getName().substring(j.getName().lastIndexOf("/")+1),classname,testMethods);
LOGGER.info(String.format("%s %s %s",j.toString(),classname,testMethods));
}
}catch (NoClassDefFoundError e) {
LOGGER.warn("WARNING: failed NoClassDefFoundError " + classname + " from " + file);
}
catch (Throwable e) {
LOGGER.warn("WARNING: failed to instantiate " + classname + " from " + file);
}
}//if .class
}//chiudo jarentry for
j.close();
child.close();
child=null;
}//chiudo jarfile for
System.gc();
LOGGER.info("Test Loader Console Back-End:\tFine Reflection Scan");
}
В конце этой функции я закрываю JarFile (j) и classLoader (child) и set child = null и agter вызывают сборщик мусора. Но если я вызову этот метод много раз в конце, у меня будет около 100% памяти, используемой java веб-приложениями.
Этот метод используется в проекте начальной загрузки, и я использую Tomcat для веб-сервера.
* 1023 Можете ли вы порекомендовать некоторую оптимизацию при использовании classLoader, и если это правильный способ поиска методов с аннотацией @Test в Java? Спасибо