Picocli должен проанализировать дерево команд. При этом ему необходимо загружать классы объектов домена для каждой команды, что замедляет запуск jvm.
Какие варианты есть, чтобы избежать этой задержки запуска? Одно решение, которое я придумал, описано в https://github.com/remkop/picocli/issues/482:
Я использую отражение, чтобы отложить загрузку любого класса до тех пор, пока не будет выбрана команда. Таким образом загружаются только сами классы команд и, наконец, классы, которые реализуют единственную команду, запрошенную пользователем:
abstract class BaseCommand implements Runnable {
interface CommandExecutor {
Object doExecute() throws Exception;
}
// find the CommandExecutor declared at the BaseCommand subclass.
protected Object executeReflectively() throws Exception {
Class<?> innerClass = getExecutorInnerClass();
Constructor<?> ctor = innerClass.getDeclaredConstructor(getClass());
CommandExecutor exec = (CommandExecutor) ctor.newInstance(this);
return exec.doExecute();
}
private Class<?> getExecutorInnerClass() throws ClassNotFoundException {
return getClass().getClassLoader().loadClass(getClass().getName() + "$Executor");
}
public void run() {
try {
executeReflectively();
} catch(...){
/// usual stuff
}
}
}
Конкретный класс рекомендаций:
@Command(...)
final class CopyProfile extends BaseCommand {
@Option String source;
@Option String dest;
// class must NOT be static and must be called "Executor"
public class Executor implements CommandExecutor {
@Override
public Object doExecute() throws Exception {
// you can basically wrap your original run() with this boilerplate
// all the CopyProfile's field are in scope!
FileUtils.copy(source, dest);
}
}
}
Похоже на https://github.com/remkop/picocli/issues/500 может обеспечить окончательное решение этой проблемы. Какие еще есть варианты до этого?