Maven Mojo для чтения классов приложений и создания Java
Я хочу написать плагин maven, который будет исследовать путь к классу моего приложения во время сборки, искать классы с определенной аннотацией и генерировать некоторые java-коды, добавляющие утилиты для этих классов, которые должны быть скомпилированы в JAR-приложении.
Поэтому я написал моджо, наследуя от AbstractMojo
и получить проект через:
@Parameter(defaultValue = "${project}", readonly = true, required = true)
private MavenProject project;
У меня есть большая часть кода, и мой mojo действительно выполняется, но у меня возникают проблемы при вставке моего mojo на правильной фазе сборки.
Если я подключу это так:
@Mojo(name = "generate", defaultPhase = LifecyclePhase.GENERATE_SOURCES,
requiresDependencyResolution = ResolutionScope.COMPILE)
тогда код Java, который я генерирую, компилируется в файл JAR.
Обратите внимание, что я использую project.addCompileSourceRoot
зарегистрировать выходную папку.
Но этого недостаточно для меня, потому что это слишком рано в сборке: я не могу прочитать путь к классам и найти классы из своего проекта. Я думаю, что они еще не скомпилированы.
Я ищу классы так:
final List<URL> urls = List.ofAll(project.getCompileClasspathElements())
.map(element -> Try.of(() -> new File(element).toURI().toURL()).get());
final URLClassLoader classLoader = new URLClassLoader(urls.toJavaList().toArray(new URL[0]), Thread.currentThread().getContextClassLoader());
final Set<Class<?>> entities = HashSet.ofAll(new Reflections(classLoader).getTypesAnnotatedWith(MyAnnotation.class));
(Я использую VAVR, но вы получите суть в любом случае)
Итак, подключив мой код на GENERATE_SOURCES
фаза, этот код не работает, и я не нахожу никаких классов.
Тем не менее, если я подключу мой модж на PROCESS_CLASSES
фаза:
@Mojo(name = "generate", defaultPhase = LifecyclePhase.PROCESS_CLASSES,
requiresDependencyResolution = ResolutionScope.COMPILE)
Затем мои классы найдены, я могу получить доступ к остальной части кода из приложения, но код, который я генерирую, не учитывается в сборке, несмотря на использование addCompileSourceRoot
,
Как заставить обе функции работать одновременно: возможность исследовать код из остальной части приложения и возможность генерировать код, который будет скомпилирован с остальной частью JAR?
Я предполагаю, что возможным ответом будет "вы не можете", но, насколько я могу судить, querydsl и immmutables делают это (я пытался прочитать их источник, но не смог найти соответствующий код).
1 ответ
Таким образом, @khmarbaise был прав, я хотел не maven mojo, а процессор аннотаций maven.
Я обнаружил, что это пошаговое руководство было очень полезно при его создании, а также этот ответ от stackru пригодился.