Загрузить класс проекта в maven mojo

Я пытаюсь загрузить класс проектов во время выполнения maven mojo.

К сожалению, эта операция завершается ошибкой, так как в загрузчике классов отсутствует указанный класс. Оглядевшись, я уже нашел подходы Плагин Maven mojo для загрузки класса из хостинг проекта и Плагин Maven не может загрузить класс

Я объединил два подхода, получив следующий код:

private ClassLoader getClassLoader(final MavenProject project) {

    try {

        final List<URL> classPathUrls = new ArrayList<>();

        // adding the projects dependency jars
        final Set<Artifact> artifacts = getProject().getDependencyArtifacts();
        for (final Artifact artifact : artifacts) {
            classPathUrls.add(artifact.getFile().toURI().toURL());
        }


        // adding the projects classes itself
        final List<String> classpathElements = project.getCompileClasspathElements();
        classpathElements.add(project.getBuild().getOutputDirectory());
        classpathElements.add(project.getBuild().getTestOutputDirectory());
        for (final String classpathElement : classpathElements) {
            classPathUrls.add(new File(classpathElement).toURI().toURL());
        }

        // creating a class loader
        final URL urls[] = new URL[classPathUrls.size()];
        for (int i = 0; i < classPathUrls.size(); ++i) {
            urls[i] = classPathUrls.get(i);
        }
        return new URLClassLoader(urls, this.getClass().getClassLoader());
    } catch (final Exception e) {
        getLog().debug("Couldn't get the classloader.");
        return this.getClass().getClassLoader();
    }
}

Класс, который не загружается, является реализацией интерфейса org.bson.codecs.Codec, содержащегося в org.mongodb:bson, который неявно импортируется через зависимость:

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-sync</artifactId>
    <version>4.1.1</version>
    <scope>provided</scope>
</dependency>

Эта зависимость имеет зависимость от другого jar (область: предоставлена), содержащего упомянутый интерфейс, который можно увидеть в дереве зависимостей maven:

$> mvn dependency:tree
[INFO] net.my.project:my-project:jar:1.0-SNAPSHOT
[INFO] +- org.mongodb:mongodb-driver-sync:jar:4.1.1:provided
[INFO] |  +- org.mongodb:bson:jar:4.1.1:provided
[INFO] |  \- org.mongodb:mongodb-driver-core:jar:4.1.1:provided

Когда я смотрю на элементы пути к классу созданного загрузчика классов, я вижу, что mongodb-driver-sync.jar включен, но поскольку он объявляет зависимость org.mongodb:bson с областью действия, при условии, что интерфейс все еще не находится в пути к классу .

Итак, последний вопрос: как я могу загрузить класс, который ссылается на класс из косвенной зависимости?


person Martin Ackermann    schedule 26.05.2021    source источник


Ответы (1)


Я заметил, что

project.getArtifacts()

был пуст, хотя javadoc говорит, что он должен содержать все зависимости (лениво заполненные).

Итак, в результате дополнительных исследований я обнаружил разработку пользовательских плагинов Maven - getArtifacts пуст, хотя зависимости включены, что предлагает настроить аннотацию @Mojo:

@Mojo(name = "mojoName", requiresDependencyResolution = ResolutionScope.COMPILE)

после корректировки аннотации достаточно даже использовать project.getCompileClasspathElements();, перебирать артефакты уже вообще не нужно.

person Martin Ackermann    schedule 26.05.2021