Creating a source jar reflecting the "uber jar"
Is it possible to use the Shadow plugin to create a source code and maybe even a javadoc jar that reflects the state after "merging"?
I need to import ASM in my project, i.e. the original packaging cannot be used for anything since this would violate compatibility. However, if someone added a dependency to my project, they could not navigate the dependency or read any documentation since the uber jar does not come with such information.
If this is not yet possible, is it consider to implement such functionality? I really need it and I want to move a first release to Maven Central soon, so I would be more than greatful. Great plugin, by the way, even without that feature!
It's on the list of things to do. It's a native feature of Maven Shade, so I'd like to do it as well...Not sure when I'll have the time to do it though.
Thanks for your quick reply. Are you sure that this is possible using the Maven Shade plugin? I asked a question about this on the Gradle forum where the existence of such a tool was questioned. I also looked for documentations on this regarding Maven's shadowing plugin but I did not find any documentation on this. Could you provide a link or tell me where within the plugin this is implemented?
I've never used it but: https://maven.apache.org/plugins/maven-shade-plugin/shade-mojo.html#createSourcesJar
I just tried it and it works! Thanks so much for the link, I must have read to quickly through the descriptions because I did not see it when I came looking.
I really hope you are integrating the source code shifting feature one day. I just had to migrate my build from Gradle to Maven for this feature... Too bad. Thanks for considering to do it some day! I'll keep my Gradle build as a secondary option until this happens.
@johnrengelman how's this coming?
+1 for this feature, migrating to Maven isn't really an option.
Any news on this? Are there other workarounds? @johnrengelman what would be the approach for implementing support for this?
Up to the current shadow version 4.0.4, this kind of "all-sources.jar" feature is still missing, afaik.
In one of my internal Gradle-MultiProject's I create and publish a single "...-all.jar" for my internal clients. To produce an accompanying "...-all-sources.jar" I collect all the sources from the dependent projects ("modules") with the following groovy snippet in my build.gradle file
...
task sourcesJar(type: Jar, dependsOn: classes) {
group = 'build'
classifier = 'sources'
from { collectSourceSetsIncludingSubmodules(project) } // we return here a closure to do this lazy, after all projects are configured by gradle
}
// workaround for missing gradle shadow plugin feature, see https://github.com/johnrengelman/shadow/issues/41
private Set<SourceDirectorySet> collectSourceSetsIncludingSubmodules(Project project){
Set<SourceDirectorySet> result = [].toSet()
recursiveCollectSourceSets(project, [].toSet(), result)
return result
}
private void recursiveCollectSourceSets(Project visitingProject,
Set<Project> visitedProjects,
Set<SourceDirectorySet> collectedSourceSets) {
if (!visitedProjects.contains(visitingProject)) {
visitedProjects.add(visitingProject)
collectedSourceSets.add(visitingProject.sourceSets.main.allSource)
visitingProject.configurations.implementation.getAllDependencies().withType(ProjectDependency).each { ProjectDependency pd ->
recursiveCollectSourceSets(pd.getDependencyProject(), visitedProjects, collectedSourceSets)
}
}
}
artifacts {
archives sourcesJar
}
shadowJar.dependsOn sourcesJar
shadowJar {
...
}
...
It's not perfect (I'm not a gradle expert), but works for me. Maybe this helps someone else looking for a solution.
(I'm using Gradle 4.10.x)
What is the gradle.kts version for this workaround?
I tried the following with gradle.kts but it didn't work for me =/, at least not yet:
val sourcesJar by tasks.creating(Jar::class) {
dependsOn("classes")
group = "build"
archiveClassifier.value("sources")
from(collectSourceSetsIncludingSubmodules(project))
}
fun collectSourceSetsIncludingSubmodules(project: Project): MutableSet<SourceDirectorySet> {
val result: MutableSet<SourceDirectorySet> = mutableSetOf()
recursiveCollectSourceSets(project, mutableSetOf(), result)
return result
}
fun recursiveCollectSourceSets(
visitingProject: Project,
visitedProjects: MutableSet<Project>,
collectedSourceSets: MutableSet<SourceDirectorySet>
) {
if (!visitedProjects.contains(visitingProject)) {
visitedProjects.add(visitingProject)
collectedSourceSets.add(visitingProject.sourceSets.getByName("main").allSource)
visitingProject.configurations.implementation.get().allDependencies.withType<ProjectDependency>().forEach {
pd: ProjectDependency ->
recursiveCollectSourceSets(pd.getDependencyProject(), visitedProjects, collectedSourceSets)
}
}
}
artifacts {
archives(sourcesJar)
}
A question because this was reopened: Does this mean you are planning to work (or already working) on this issue? If not, would you accept a PR? I'd love to see the shadow plugin being able to create the correct source jar. This would also make life a whole lot easier for publishing an artifact with shaded dependencies.