Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to exclude certain jars from copyDependencies task (duplicate handling strategy) #400

Open
2 of 5 tasks
streamingdv opened this issue Apr 11, 2024 · 8 comments
Open
2 of 5 tasks
Labels
fixed Issue fixed and release pending

Comments

@streamingdv
Copy link

I'm submitting a…

  • bug report
  • feature request
  • other

Short description of the issue/suggestion:
I have a special setup where I include my own compiled 'javafx-graphics-22-win.jar' because I compiled it with enabling the OpenGL rendering pipeline. My own javafx graphics lib is called 'javafx.graphics..jar' which is in my libs folder of my project and it gets imported like this

implementation fileTree(include: ["*.jar"], dir: "libs")

This is my javapackager task

tasks.register('packageApplication', PackageTask) {
    // mandatory
    mainClass = 'com.grill.app.Launcher'
    // optional
    bundleJre = true
    generateInstaller = true
    administratorRequired = false
    copyDependencies = true
    vmArgs = [
            '--module-path=libs',

            '--add-modules=javafx.graphics,javafx.controls,javafx.fxml,javafx.base,javafx.web',

            '--add-opens=javafx.base/com.sun.javafx=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.prism=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.prism.ps=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.prism.shader=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.prism.impl=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.scenario.effect.impl=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.scenario.effect.impl.prism=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.prism.impl.ps=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.glass.utils=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.glass.ui=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.prism.es2=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.javafx.geom.transform=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.prism.paint=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.javafx.scene.layout=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.javafx.tk=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED',
            '--add-opens=javafx.graphics/javafx.scene.image=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.javafx.util=ALL-UNNAMED',
            '--add-opens=javafx.graphics/com.sun.javafx.application=ALL-UNNAMED',
            '--add-opens=javafx.base/com.sun.javafx.logging=ALL-UNNAMED',

            '-Dprism.forceGPU=true',
            '-XX:+UseZGC',
            '-XX:+ZGenerational'
    ]
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        vmArgs.add('--add-opens=javafx.graphics/com.sun.prism.d3d=ALL-UNNAMED')
        winConfig {
            headerType = HeaderType.gui
            icoFile = file('src/main/resources/com/grill/app/image/icon.ico')
        }
    } else if (Os.isFamily(Os.FAMILY_UNIX)) {
        linuxConfig {
            pngFile = file('src/main/resources/com/grill/app/image/icon_256.png')
        }
    }

}

Because of this I have now dublicated graphics jar files in my generated libs folder of javapackager and I get following error when I try to start the application

Error occurred during initialization of boot layer
java.lang.module.FindException: Two versions of module javafx.graphics found in libs (javafx.graphics.jar and javafx-graphics-22-win.jar)

So in order to mitigate this issue I have another task which deleted the other unwanted graphics jar

tasks.register('deleteNativePackages', Delete) {
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        delete fileTree(dir: file("$buildDir/App/libs"), include: '**/javafx-graphics-*.jar')
    }

    doLast {
        logger.lifecycle "Deleted unwanted javafx jars in the build folder."
    }
}

packageApplication.finalizedBy deleteNativePackages

This works for the generated exe in the folder but is already too late for the installer, which means my installers will get generated with the additional graphics jar bundled. This leads to the same crash as mentioned above when executing my installed application on a PC (because it bundles the two graphics jar libs).

I tried to name the graphics jar the same as the original (javafx-graphics-22-win.jar) but this leads to following error

  • What went wrong:
    Execution failed for task ':packageApplication'.

Entry javafx-graphics-22-win.jar is a duplicate but no duplicate handling strategy has been set. Please refer to https://docs.gradle.org/8.5/dsl/org.gradle.api.tasks.Copy.html#org.gradle.api.tasks.Copy:duplicatesStrategy for details.

Not sure why I get this erros as I have defined these rules which are working in other tasks

tasks.configureEach {
    if (it instanceof Copy || it instanceof Zip || it instanceof Tar) {
        it.duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    }
}

Steps to reproduce the issue/enhancement:

  1. [First Step] include a second javafx graphics module for example in your libs folder and include it into your project
  2. [Second Step] Define a basic javapackager task
  3. [Other Steps...] execute the javapackager task and with copyDependencies and try to execute the compiled exe and the installer.

What is the expected behavior?

Would be nice if there is a way to handle such a scenario in JavaPackager, but maybe there is or maybe there is a workaround for that? Maybe a hook to a task which allows you to do certain things before the installer gets created?

What is the current behavior?

I think there is no easy way to handle that scenario with javapackager but I might be wrong?

Please tell us about your environment:

  • JavaPackager version: v1.7.5
  • OS version: Windows 11
  • JDK version: JDK 21
  • Build tool:
    • Maven
    • Gradle
@fvarrui
Copy link
Owner

fvarrui commented Apr 21, 2024

Hi @streamingdv!

I planned to split some JP features into several Maven plugins and Gradle tasks, so you can combine them, e.g, you can call CreateAppTask, run your stuff, and then call GenerateInstallerTask. I think this could bring a lot of possibilities. JP internal logic is able to do this:

public void doPackage() throws Exception {
Packager packager = createPackager();
// generates app, installers and bundles
File app = packager.createApp();
List<File> installers = packager.generateInstallers();
List<File> bundles = packager.createBundles();
// sets generated files as output
outputFiles = new ArrayList<>();
outputFiles.add(app);
outputFiles.addAll(installers);
outputFiles.addAll(bundles);
}

Anyway, I'll try to reproduce your issue and find a simple solution or a workaround.

If you want to do some research by yourself, take a look into this:

protected File doApply(Packager packager) {
File libsFolder = new File(packager.getJarFileDestinationFolder(), "libs");
Project project = Context.getGradleContext().getProject();
copyLibsTask = (Copy) project.getTasks().findByName("copyLibs");
if (copyLibsTask == null) {
copyLibsTask = project.getTasks().create("copyLibs", Copy.class);
}
copyLibsTask.from(project.getConfigurations().getByName("runtimeClasspath"));
copyLibsTask.into(project.file(libsFolder));
copyLibsTask.getActions().forEach(action -> action.execute(copyLibsTask));
return libsFolder;
}

This is the snipet of code which copies dependencies in Gradle.

@fvarrui fvarrui added the working on Work in progress on this issue label Apr 21, 2024
@fvarrui
Copy link
Owner

fvarrui commented Apr 21, 2024

Hi again!
I've managed to reproduce your issue:

C:\Users\fvarrui\GitHub\HelloWorldGradle>build\HelloWorldGradle\HelloWorldGradle.exe
Error occurred during initialization of boot layer
java.lang.module.FindException: Two versions of module javafx.graphics found in libs (javafx-graphics-22-win.jar and javafx-graphics-20.0.1-win.jar)

The problem is not about duplicated jars, but duplicated modules (javafx.graphics module is twice) ... what if you call your custom javafx.graphics.jar with the same name as the JAR which is being included by javafx-gradle-plugin ('javafx-graphics-22-win.jar), so it'll be ovewriten with your custom JavaFX jar. I've just released a SNAPSHOT version with DuplicatesStrategy=EXCLUDE when copying libraries to avoid this error: 1.7.6-20240421.230018-6 ... try it and give me some feedback, please.

@fvarrui fvarrui added feedback Waiting for feedback and removed working on Work in progress on this issue labels Apr 22, 2024
@streamingdv
Copy link
Author

Could not find io.github.fvarrui:javapackager:1.7.6-20240421.230018-6
Which maven repo should I include in my gradle script in order to use the snapshot?

@fvarrui
Copy link
Owner

fvarrui commented Apr 22, 2024

It's explained here

@fvarrui
Copy link
Owner

fvarrui commented Apr 23, 2024

New snapshot released: 1.7.6-20240423.010107-7.

Now duplicatesStrategy=WARN by default, but you can set a different duplicates strategy to your PackageTask:

tasks.register('packageApplication', PackageTask) {
    // mandatory
    mainClass = 'com.grill.app.Launcher'
    // optional
    bundleJre = true
    generateInstaller = true
    administratorRequired = false
    copyDependencies = true
    [...]
    duplicatesStrategy = DuplicatesStrategy.[EXCLUDE|FAIL|INCLUDE|INHERIT|WARN]
}

and this should work too:

tasks.configureEach {
    if (it instanceof Copy || it instanceof Zip || it instanceof Tar || it instanceof PackageTask) {
        it.duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    }
}

@streamingdv
Copy link
Author

Thanks, it works now with the provided Snapshot. :)
I hope this will make it into the next release.

@fvarrui fvarrui added fixed Issue fixed and release pending and removed feedback Waiting for feedback labels Apr 25, 2024
@fvarrui
Copy link
Owner

fvarrui commented Apr 30, 2024

Please, let's keep this issue open untill it's released

@fvarrui fvarrui reopened this Apr 30, 2024
@fvarrui
Copy link
Owner

fvarrui commented Apr 30, 2024

Branch issue-400 merged into devel, ready to be released in 1.7.6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed Issue fixed and release pending
Projects
None yet
Development

No branches or pull requests

2 participants