Плагин Gradle jlink завершается с ошибкой во время createMergedModule с «реализацией сервиса нет конструктора по умолчанию» - PullRequest
0 голосов
/ 09 июня 2019

Я использую Gradle (4.10.3, но я пробовал большинство версий до 5.4.1) с JDK 12.0.1 и плагином org.beryx.jlink (2.10.4), но каждый раз сталкиваюсь с этой ошибкойвремя, когда я пытаюсь создать образ jlink:

-> Task: createMergedModule

Невозможно получить предложение использования из вызова загрузчика службы в: com / fastxml / jackson / databind / ObjectMapper $ 2.run ().

Невозможно получить условие использования из вызова загрузчика службы в: com / fastxml / jackson / databind / ObjectMapper.secureGetServiceLoader ().

Невозможно получить предложение использования из вызова загрузчика службы в:org / apache / commons / compress / utils / ServiceLoaderIterator. ().

C: \ Users \ MyName \ IdeaProjects \ myapp \ build \ jlinkbase \ tmpjars \ myapp.merged.module \ module-info.java:393: ошибка: реализация службы не имеет конструктора по умолчанию: XBeansXPath предоставляет org.apache.xmlbeans.impl.store.PathDelegate.SelectPathInterface с org.apache.xmlbeans.impl.xpath.saxon.XBeansXPath;

C: \ Users \MyName \ IdeaProjects \ myapp \ build \ jlinkbase \ tmpjars \ myapp.merged.module \ module-info.java: 394: ошибка: реализация службы не имеет конструктора по умолчанию: XBeansXQuery предоставляет org.apache.xmlbeans.impl.store.QueryDelegate.QueryInterface с org.apache.xmlbeans.impl.xquery.saxon.XBeansXQuery;2 ошибки

-> Задача: createMergedModule FAILED

Когда я нажимаю на строки, выбрасывающие ошибки в объединенном module-info.java, он указывает на эти два:

provides org.apache.xmlbeans.impl.store.PathDelegate.SelectPathInterface with org.apache.xmlbeans.impl.xpath.saxon.XBeansXPath;
provides org.apache.xmlbeans.impl.store.QueryDelegate.QueryInterface with org.apache.xmlbeans.impl.xquery.saxon.XBeansXQuery;

Мой build.gradle файл выглядит следующим образом:

plugins {
    id 'application'
    id 'idea'
    id 'java'
    id 'org.openjfx.javafxplugin' version '0.0.7'
    id 'org.beryx.jlink' version '2.10.4'
}

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.apache.commons:commons-csv:1.6'
    compile 'org.apache.poi:poi-ooxml:4.1.0'
    compile 'com.fasterxml.jackson.core:jackson-core:2.9.9'
    compile 'com.fasterxml.jackson.core:jackson-annotations:2.9.9'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.9.9'
    testCompile 'org.junit.jupiter:junit-jupiter-api:5.5.0-M1'
    testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.5.0-M1'
}

// ### Application plugin settings
application {
    mainClassName = "$moduleName/path.to.myapp"
}

// ### Idea plugin settings
idea {
    module {
        outputDir = file("out/production/classes")
    }
}

// ### Java plugin settings
sourceCompatibility = JavaVersion.VERSION_11

compileJava {
    options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}

test {
    useJUnitPlatform()
    testLogging {
        events 'PASSED', 'FAILED', 'SKIPPED'
    }
}

// ### JavaFX plugin settings
javafx {
    version = "12.0.1"
    modules = ['javafx.controls', 'javafx.fxml']
}

// ### jlink plugin settings
jlink {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'myapp'
    }
}

Любые идеи о том, как я могу решить эту проблему?

1 Ответ

1 голос
/ 09 июня 2019

Следующее возможное решение основано только на вашем файле сборки, без знания вашей информации о модуле или кода проекта, поэтому оно может не работать.

Это также основано на этой проблеме в хранилище плагина jlink.

Сначала позвольте мне объяснить, как работает этот плагин: поскольку инструмент (JDK) jlink не допускает немодулярных зависимостей, плагин попытается собрать их все и создать на лету модуль, который может быть добавленным в путь к модулю. Этот модуль называется $yourModuleName.mergedModule.

Теперь я добавляю ваши зависимости в простой проект JavaFX. Когда я запускаю ./gradlew jlink, я получаю те же ошибки, что и вы. Если вы проверите ошибки:

myapp \ build \ jlinkbase \ tmpjars \ myapp.merged.module \ module-info.java: 394: ошибка

Это показывает, что созданный модуль имеет имя myapp.merged.module и имеет дескриптор module-info. Если вы откроете его, вы увидите все exports (модуль будет экспортировать каждый пакет зависимостей по умолчанию), requires и provides:

open module myapp.merged.module {
    exports com.fasterxml.jackson.annotation;
    exports com.fasterxml.jackson.core;
    exports com.fasterxml.jackson.core.async;
    ...
    exports schemaorg_apache_xmlbeans.system.sXMLTOOLS;
    requires java.xml.crypto;
    requires java.logging;
    requires java.sql;
    requires java.xml;
    requires java.desktop;
    requires java.security.jgss;
    requires jdk.javadoc;
    uses java.nio.file.spi.FileSystemProvider;
    provides com.fasterxml.jackson.core.JsonFactory with com.fasterxml.jackson.core.JsonFactory;
    provides com.fasterxml.jackson.core.ObjectCodec with com.fasterxml.jackson.databind.ObjectMapper;
    provides org.apache.xmlbeans.impl.store.QueryDelegate.QueryInterface with org.apache.xmlbeans.impl.xquery.saxon.XBeansXQuery;
    provides org.apache.xmlbeans.impl.store.PathDelegate.SelectPathInterface with org.apache.xmlbeans.impl.xpath.saxon.XBeansXPath;
}

Итак, теперь возникает вопрос: стоит ли добавить дополнительные требования к вашему собственному модулю? Ответ объясняется здесь : это излишне увеличит размер вашего проекта. Лучше использовать блок сценариев mergedModule:

Блок mergedModule позволяет настроить дескриптор модуля объединенного модуля

И

дескриптор модуля создается с использованием алгоритма, реализованного задачей suggestMergedModuleInfo.

Если вы запустите ./gradlew suggestMergedModuleInfo, вы в основном получите то же содержимое для дескриптора объединенного модуля, что и выше.

Возможное решение - начать просто добавлять некоторые требования в дескриптор объединенного модуля и повторить попытку.

Я начал с:

jlink {

    mergedModule {
        requires "java.xml"
    }

    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'myapp'
    }
}

и я могу успешно запустить ./gradlew jlink.

Если вы сейчас проверите дескриптор объединенного модуля, он будет выглядеть так:

open module myapp.merged.module {
    requires java.xml;

    exports com.fasterxml.jackson.annotation;
    exports com.fasterxml.jackson.core;
    exports com.fasterxml.jackson.core.async;
    ...
    exports schemaorg_apache_xmlbeans.system.sXMLTOOLS;
}

содержит только явный requires, все экспорты, но без provides, поэтому ошибки исчезнут.

Поскольку у меня нет вашего кода, я не могу сказать, сработает ли это для вас, но у меня с теми же зависимостями.

...