Disabling default jar task, creating more jars for a module and troubles with classpath

Hello everybody, first poster here.
I’m quite new to gradle but I’m trying to migrate a big workspace from multiple ant projects to a gradle multi project workspace (leaving ant out).
I’ve converted everything but there is something I can’t achieve, a slimmed down version here:

  • I have a :libraries:utilities project where:
    • I have disabled the default jar task for sake of cleanliness
    • created jarCore and jarRemote tasks for creating the same jars as in ant
    • added new jar tasks as artifacts in order to generate them with assemble task
  • A :utils:consumer project which uses implementation project(':libraries:utilities') as a dependancy
    • I build a classpath for execution or custom-deployment (for example) but can’t get my jars in it

When I try to use the runtimeClasspath of :libraries:utilities I only get ../build/libs/utilities.jar that does not even exists as the default jar task is disabled.

As a workaround I wrote a method that recursively travels dependencies and uses classes/resources dirs directly but gradle 7.5.1 complains about a deprecate out of context access that will be forbidden in future versions:

Resolution of the configuration :XXX:YYY:runtimeClasspath was attempted from a context different than the project context. Have a look at the documentation to understand why this is a problem and how it can be resolved. This behaviour has been deprecated and is scheduled to be removed in Gradle 8.0. See https://docs.gradle.org/7.5/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.
	at build_5vk3zmqix7ud8b3ybyt51lvko$_run_closure7$_closure11.doCall(.../XXX/YYY/build.gradle:56)
	(Run with --stacktrace to get the full stack trace of this deprecation warning.)

I tried to figure out how to include new jars in dependants projects without success… and didn’t even tried to remove utilities.jar from classpath.

Can anybody help?

From further investigation it seems they are 2 different problems:

  1. Resolution of the configuration... is because I need the runtime classpath without jars for an obfusction task (or whatever) including dependencies, here I build a configuration and use asPath which resolves the configuration with the dependencies of other projects, all accesses are though gradle.projectsEvaluated { ... } in order to have a consistent resolution

  2. runtimeClasspath includes jars while I need classDirs for the above tasks; for JavaExec I can go with jars if only it would include my custom jars and task dependencies.

Ok i managed to solve the Resolution of the configuration :XXX:YYY:runtimeClasspath was attempted from a context different.. by creating dependencies from closures of FileCollections, this makes the resolution lazy and everything seems to be fine.

What I still don’t understand is if there is an official way to get the dependencies classpath without jars… when I compile calling classes and testClasses I don’t see jars that get built but when I access runtimeClasspath I get jars.

You should have a look at feature variants and variant-aware resolution.
When using the java-library plugin, there are secondary variants that you can use to just get the classes directories instead of the jars, and for building your other jars, you should probably define feature variants, that you then can also depend on properly in the consumer projects.

I managed to solve all my out-of-context config resolutions by creating a local project config and adding the “other” project via dependencies.project(path: ':x:y', configuration: 'runtimeClasspathNoJar') but I can’t still figure out how to remove project artifacts from the runtimeClasspathNoJar I created even after reading about feature variants :frowning:

Use the outgoingVariants task on the producer project and you see the variants it provides, including their attributes. Then you can set up the attributes on the consuming configuration properly to get the variant you want to have.