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

Shadow Jar for modular project with module-info #710

Closed
palexdev opened this issue Sep 13, 2021 · 7 comments
Closed

Shadow Jar for modular project with module-info #710

palexdev opened this issue Sep 13, 2021 · 7 comments

Comments

@palexdev
Copy link

Shadow Version

Version 7.0.0

Gradle Version

Version 7.2

Gradle Build Script(s)

jar {
    manifest {
        attributes(
                'Bundle-Name': project.name,
                'Bundle-Description': "...",
                'Bundle-SymbolicName': '...',
        )
    }
    enabled = false
    dependsOn(shadowJar)
}

shadowJar {
    mergeServiceFiles()
    archiveClassifier.set(null)
    configurations = [project.configurations.shadow]
}

I'm trying to build a shadow jar for my library that depends on another library, I'd like to ship my jar with the dependency already included.
The issue is that my project is a modular project, there's the library itself that is the "main" module and then there's a preview of the library which is the "demo" module
Both modules have their respective module-info.java, when I build the shadow jar the build fails because the "demo" module cannot find the required "main" module. In fact if I open the shadow jar there's no module info in the archive

@Marcono1234
Copy link
Contributor

module-info.class is excluded by default, see #352. Unfortunately the documentation was apparently not updated to reflect that.

@aoli-al
Copy link

aoli-al commented Aug 29, 2022

Is it possible to include module-info.class? I tried include "**/module-info.class" but it doesn't work.

@bademux
Copy link

bademux commented Oct 17, 2022

@johnrengelman the decision to exclude module-info was unfortunate.
The plugin is extremely useful to hackfix different legacy libs from (apache) cemetery to use modules.

Please leave module-info from the project as-is, but skip it from dependancies.
for now, my hackfix to restore module and expose the jar

configurations {
    moduleJar {
        canBeConsumed = true
        canBeResolved = false
    }
}

task appendModueInfo(type: Jar, dependsOn: tasks.shadowJar) {
    group 'shadow'

    from zipTree(tasks.shadowJar.archiveFile)
    from tasks.compileJava.destinationDirectory.file('module-info.class')
    archiveBaseName.set(tasks.shadowJar.archiveBaseName)
    archiveVersion.set(tasks.shadowJar.archiveVersion)
    archiveClassifier.set('module')
    duplicatesStrategy = DuplicatesStrategy.FAIL
}

artifacts {
    moduleJar(tasks.appendModueInfo) {
        builtBy(tasks.appendModueInfo)
    }
}

@johnrengelman johnrengelman added this to the 8.1.2 milestone Apr 10, 2023
@johnrengelman
Copy link
Collaborator

I started looking into this, but I'm not seeing an easy path to support it yet. ShadowJar extends from Gradle's built in Jar task (which itself extends from AbstractCopyTask) which is what provides all the include/exclude capabilities. None of that code is aware to the source of the files that are being copied so it doesn't appear possible to use the native capabilities to exclude module-info.class from dependencies, but include it from the local source set output.

The only idea i've got here is to not use exclude but hard code the exclusion lower down in the code that is processing through the entries of each Jar file. Since the local source set comes from a directory and not a jar, it wouldn't be handled by this code. The tradeoff here is that it's custom logic that doesn't offer any configurability.

@je-ik
Copy link

je-ik commented May 18, 2023

The following seems to work in my case:

shadowJar {
  ...
  excludes.remove("module-info.class")
}

@Steve973
Copy link

Steve973 commented Jan 31, 2025

Even if module-info is excluded from dependencies, it should NOT be excluded from being carried over from your original project jar. That would mean that you've effectively removed JPMS configuration from the jar. If that is happening, why would that be excluded? When I look at the resultant jar, it's not being carried over, which results in errors in my build.

I see that the plugin code code is very explicitly excluding module-info.class from the shadowed jar. Can someone explain why this is happening?

@Goooler Goooler removed this from the Next milestone Feb 8, 2025
@Goooler
Copy link
Member

Goooler commented Mar 3, 2025

You can try out #520 (comment) for including project module-info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants