I have a jvm only multi module project using java...
# community-support
p
I have a jvm only multi module project using java-test-fixtures and I get an error when storing CC because
:restclient:jar' (type 'Jar') uses this output of task ':api:jar' without declaring dependency
. And I don't understand, how this could happen. Do you have any hints where I should look at the Build scan?
1
v
Well, purely from that one line I'd guess you try to shade the classes in
:api:jar
into the
:restclient:jar
(a bad idea imho, almost always), but do not have declared proper inputs for the
:restclient:jar
. You probably even do not do save cross-project publication but simply get the tasks result by reaching into the other projects model or by just configuring the jar path or similar. If you really must do such a shading, at least do proper and safe cross-project publication, getting the jar by project dependency on some configuration, and then using it properly in a way it is identified as input including necessary implicit task dependencies. But just a wild guess from that little information. 🙂
p
I just found the bug by removing almost all Gradle code and adding them step by step again until the error occurs again, and you are right. How did you know? 🤯 Yes, you are correct, I did shade the files… But there are only used to simply the upload to the server because I did the upload manually in the past… sounds like I should upload all files.
Copy code
tasks.jar {
    manifest.attributes["Main-Class"] = "Imp"
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    from(configurations.runtimeClasspath.map {
        it.map {
            if (it.isDirectory) it else zipTree(it)
        }
    })
}
v
How did you know?
Many years of Gradle experience, excellent problem solving skills, and often helping other people with their problems. 🙂 Yeah, the
.map
is the problem, as it is not the lazy
Provider.map
of Gradle that preserves task dependencies, but the stdlib
Iterable<File>.map
which means you get the files at configuration time and use them, which also means you might have stale file used or maybe a failure if you are unlucky and on a clean worktree as the file might not be there yet. If you really need to do this, you should probably use
runtimeClasspath.elements
which is a
Provider<List<FileSystemLocation>>
and then
.map
on that to preserve the task dependency and do the logic lazily. But yes, if you feel the need to separate code into multiple modules, it is usually best to also publish those modules as separate artifacts and have the proper dependencies. It is much easier and much cleaner and then also cannot result in problems like having the classes available in mutliple jars on the classpath which becomes a problem if they are in different versions.