beryx / badass-jlink-plugin

Create a custom runtime image of your modular application
https://badass-jlink-plugin.beryx.org
Apache License 2.0
385 stars 27 forks source link

About the introduction of third-party packages "module com.demo.merged.module does not declare `uses`" #228

Closed ft0907 closed 1 year ago

ft0907 commented 1 year ago
plugins {
    id 'java'
    id 'application'
    id 'org.openjfx.javafxplugin' version '0.0.10'
    id 'com.github.johnrengelman.shadow' version '7.0.0'
    id 'org.beryx.jlink' version '2.26.0'
}

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

group 'com.zlg'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.openjfx:javafx-fxml:17'
    implementation 'org.openjfx:javafx-controls:17'
    implementation 'org.openjfx:javafx-web:17'
//     implementation ("cn.hutool:hutool-all:5.8.20")
    implementation 'com.itextpdf:html2pdf:3.0.0'
    implementation("com.itextpdf:font-asian:7.2.5")
    implementation 'org.freemarker:freemarker:2.3.31'
    implementation("cn.hutool:hutool-http:5.8.20")
    implementation("cn.hutool:hutool-core:5.8.20")
//     implementation('org.springframework:spring-core:6.0.9') {
//         exclude group: 'io.projectreactor', module: 'reactor-core'
//         exclude group: 'io.projectreactor', module: 'reactor-tools'
//     }
    implementation("org.apache.commons:commons-collections4:4.4")
    implementation("org.apache.commons:commons-lang3:3.12.0")
    implementation("commons-codec:commons-codec:1.15")
    implementation("com.alibaba:fastjson:2.0.19")
}

javafx {
    version = "17"
    modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.web' ]
}

application {
    mainModule = 'com.zlg'
    mainClassName = 'com.zlg.App'
}

shadowJar {
//     archiveClassifier.set('')
    manifest {
        attributes 'Main-Class': 'com.zlg.App'
    }
}

jlink {
    imageZip = project.file("${buildDir}/distributions/app-${javafx.platform.classifier}.zip")
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'app'
    }

    targetPlatform("win") {
        jdkHome = jdkDownload("https://github.com/AdoptOpenJDK/openjdk17-binaries/releases/download/jdk-2021-05-07-13-31/OpenJDK-jdk_x64_windows_hotspot_2021-05-06-23-30.zip")
        addExtraModulePath("/Users/yangfan/Desktop/javafx/lib")
    }

    targetPlatform("mac") {
        jdkHome = jdkDownload("https://github.com/AdoptOpenJDK/openjdk17-binaries/releases/download/jdk-2021-05-07-13-31/OpenJDK-jdk_x64_mac_hotspot_2021-05-06-23-30.tar.gz") {
            downloadDir = "$buildDir/myMac"
            archiveName = "my-mac-jdk"
            archiveExtension = "tar.gz"
            pathToHome = "jdk-17+20/Contents/Home"
            overwrite = true
        }
        addExtraModulePath("/Users/yangfan/Desktop/javafx/lib")
    }
}

jlinkZip {
    group = 'distribution'
}
module com.zlg {
    requires javafx.fxml;
    requires javafx.controls;
    requires javafx.web;
    requires java.desktop;
    requires freemarker;
    requires org.apache.commons.collections4;
    requires org.apache.commons.lang3;
    requires com.alibaba.fastjson2;
    requires fastjson;
    requires org.apache.commons.codec;
    requires kernel;
    requires html2pdf;
    requires layout;
    requires font.asian;
    requires java.sql;
    requires java.base;
    requires cn.hutool.core;
    requires cn.hutool.http;

    opens com.zlg to javafx.fxml;
    opens com.zlg.entity to freemarker;
    opens com.zlg.util to javafx.fxml;

    exports com.zlg;
    exports com.zlg.util;

    uses cn.hutool.core.convert.Converter;
    uses com.zlg.service.OrderRestService;
    uses com.zlg.service.LoginService;
}

above is my gradle dependency configuration and module-info.java file configuration,There is no problem when I directly use the jar to start, but as long as the package generated by jlink is run, the following error will be prompted Exception in thread "JavaFX Application Thread" java.util.ServiceConfigurationError: cn.hutool.core.convert.Converter: module com.zlg.merged.module does not declare usesAm I missing any configuration or there is a problem with jlink packaging and using modules, I hope friends who know can answer, thank you @aalmiray @larsroe @siordache @xp-vit @DJViking

kromar777 commented 1 year ago

Try to add mergeServiceFiles() to shadowJar task.

airsquared commented 1 year ago

I'll close this issue due to inactivity, if you're still having the issue you can comment to reopen it.

Borewit commented 1 year ago

I may have run into the same problem. For some reason I don't manage to get sl4j2 into my jpackage deployment.

Steps to reproduce, checkout this branch on a Windows machine.

Build the destribution

gradlew :jpackageImage

Run the application

build\jpackage\listFix()\listFix().exe

Throws the following error:

ERROR StatusLogger Unable to load services for service class org.apache.logging.log4j.spi.Provider
 java.util.ServiceConfigurationError: org.apache.logging.log4j.spi.Provider: module listFix.merged.module does not declare `uses`
        at java.base/java.util.ServiceLoader.fail(Unknown Source)
        at java.base/java.util.ServiceLoader.checkCaller(Unknown Source)
        at java.base/java.util.ServiceLoader.<init>(Unknown Source)
        at java.base/java.util.ServiceLoader.load(Unknown Source)
        at listFix.merged.module@3.0.1.6/org.apache.logging.log4j.util.ServiceLoaderUtil.callServiceLoader(Unknown Source)
        at listFix.merged.module@3.0.1.6/org.apache.logging.log4j.util.ServiceLoaderUtil$ServiceLoaderSpliterator.<init>(Unknown Source)
        at listFix.merged.module@3.0.1.6/org.apache.logging.log4j.util.ServiceLoaderUtil.loadClassloaderServices(Unknown Source)
        at listFix.merged.module@3.0.1.6/org.apache.logging.log4j.util.ServiceLoaderUtil.loadServices(Unknown Source)
        at listFix.merged.module@3.0.1.6/org.apache.logging.log4j.util.ServiceLoaderUtil.loadServices(Unknown Source)
        at listFix.merged.module@3.0.1.6/org.apache.logging.log4j.util.ProviderUtil.<init>(Unknown Source)
        at listFix.merged.module@3.0.1.6/org.apache.logging.log4j.util.ProviderUtil.lazyInit(Unknown Source)
        at listFix.merged.module@3.0.1.6/org.apache.logging.log4j.util.ProviderUtil.hasProviders(Unknown Source)
        at listFix.merged.module@3.0.1.6/org.apache.logging.log4j.LogManager.<clinit>(Unknown Source)
        at listFix.app/listfix.view.GUIScreen.<clinit>(Unknown Source)
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
Exception while removing reference.

Based on given suggestions I tried to use com.github.johnrengelman.shadow plugin in combination with mergeServiceFiles(), but it did not resolve this issue.

References:

Seems also related to: #209

Borewit commented 1 year ago

I manage to get it to working by each class generating a uses Exception, until no more exceptions are thrown. I wonder if the "merged.module" is merging module dependencies correctly.

jlink {
    //.....
    mergedModule {
        additive = true
        uses "org.apache.logging.log4j.spi.Provider"
        uses "org.apache.logging.log4j.core.util.WatchEventService"
        uses "org.apache.logging.log4j.core.util.ContextDataProvider"
    }
}
airsquared commented 1 year ago

I manage to get it to working by each class generating a uses Exception, until no more exceptions are thrown. I wonder if the "merged.module" is merging module dependencies correctly.

This is the correct solution. Not all uses can be automatically detected and some have to be manually added. Maybe there's a way to improve the detection, but I'm not sure how.