How to make annotationProcessor transitive from custom lib - gradle

I'm using my own lib, which configuring core dependencies and other stuff for micro-service product (some kind of custom starter).
To make dependencies transitive (auto-import in inherited projects) i'm using gradle api(dependency) in lib like
api(libs.bundles.util) //dependency alias from version-catalog
Is there any way to make scope annotationProcessor() transitive like api() for using it similar? The solution i want should looks like this, or describe why i can't do it.
apiAnnotationProcessor(libs.mapstruct.processor) //interesting in transitive mapstruct and lombok processors

Related

Protobuf marshallers not registering when using Gradle?

I have a project where I'm trying to get protobuf to work with infinispan, quarkus and gradle. The problem is that although I'm following the instructions given in the Quarkus homepage: https://quarkus.io/guides/infinispan-client, it seems that when I'm using gradle, the marshallers are not generated and registered as they should be. To me it seems like this comes down to the org.infinispan.protostream:protostream-processor not executing when gradle is the build tool. Is this a conscious decision that only Maven is supported, or am I missing something obvious in my gradle setup?
Replications of the most simple cases can be found here: https://github.com/radiosphere/gradle-java-protobuf for gradle and here for maven: https://github.com/radiosphere/mvn-java-protobuf. These projects are extremely basic, basically trying to run a simple code on startup:
public void onStartup(#Observes StartupEvent startupEvent) {
RemoteCache<String, CounterState> cache = cacheManager.administration().getOrCreateCache("default", DefaultTemplate.DIST_SYNC);
cache.put("a", new CounterState(2L));
CounterState state = cache.get("a");
logger.infof("State: %s", state);
}
In the maven project this works, in the gradle project an exception is thrown saying that no marshaller can be found. Apart from build tool choice the projects should be identical.
The annotation processor runs in the Maven build because io.quarkus:quarkus-infinispan-client has a compile dependency on org.infinispan.protostream:protostream-processor.
Looks like Gradle made a decision to not use annotation processors found in the compile classpath:
Since implementation details matter for annotation processors, they must be declared separately on the annotation processor path. Gradle ignores annotation processors on the compile classpath.
That means you have to add an explicit annotationProcessor dependency:
annotationProcessor 'org.infinispan.protostream:protostream-processor:4.4.0.Final'

How to combining multiple dependencies into a maven artifact?

I have a dependency in a project of mine that does not declare its own required dependencies. How may I combine the dep and its deps into a single maven artifact, so that I can depend on this single artifact instead?
The first (and maybe? second) implementation dependency is the actual public API.
repositories {
maven {
url 'http://devsite.ctr-electronics.com/maven/release/'
}
}
dependencies {
implementation "com.ctre.phoenix:api-java:5.14.1"
implementation "com.ctre.phoenix:wpiapi-java:5.14.1"
implementation "com.ctre.phoenix:cci:5.14.1"
implementation "com.ctre.phoenix:canutils:5.14.1"
implementation "com.ctre.phoenix:platform-stub:5.14.1"
}
Use the java-library plugin (emphasis mine):
https://docs.gradle.org/current/userguide/java_library_plugin.html
The api configuration should be used to declare dependencies which are exported by the library API, whereas the implementation configuration should be used to declare dependencies which are internal to the component.
So change implementation to api for the dependencies you want exposed on the classpath.

Dealing with other dependencies in your own Maven dependency

I want to reuse and centralize the utils I created for my Spring REST API for my future projects. That's why I thought I'd outsource them to my own project and make them available as a Maven dependency.
These Util files e.g. a basic service, basic controllers also contain Spring annotations, i.e. I need some Spring dependencies in my Util dependency. Now I'm a bit unsure whether I'm making a mistake or not.
First of all, I'm not sure if I should even use spring dependencies in a utility dependency or try to remove everything. Otherwise, I'll have to specify a spring version, but it might differ from the version I want to use later in the project it's included in. How am I supposed to solve this?
It is perfectly reasonable to have dependencies for your dependencies (these are called transitive dependencies). Of course, you should keep the number as low as possible, but on the other hand, you do not want to reinvent the wheel.
When somebody uses your dependency, they will automatically draw the transitive dependency on spring. Now, several cases can occur:
If this is the only reference to spring, the version is just used as you stated it.
If at some other point, a different version of spring is given, Maven dependency mediation kicks in. It decides by a "nearest is best" rule which version to take.
But: You can always set the spring version in <dependencyManagement> and then overwrite all transitively given version numbers.
That is the main concept of Maven. Your utility module must shipped together with Spring dependencies. It's called transitive dependencies.
Try to imagine that situation when all dependencies had excluded. In that case nobody will never know what kind and which version of Spring dependencies are needed.
Maven has a very good dependency conflict resolution. It's based on nearest-newest principle. So you can override those Spring versions easily and your application will use only one of that.
Take a look at these:
[1] Dependency Mechanism
[2] Dependency Mediation and Conflict Resolution

make implementation dependency available in another submodule

I have submodule rest that defines couple of dependencies with implementation. And I have another module app that uses implementation project(":rest").
However the dependencies of the rest declared with implementation are not available for app. I know implementation does that by design, but how to make them available without using original compile configuration?
It seems I need to use plugin java-library and use api configuration for that dependency.

The transitive reference don't works in gradle when use implementation project

I have a Core project where it has dependencies to other library.
Core build.gradle
dependencies {
implementation 'com.jakewharton:butterknife:9.0.0-rc2'
annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0-rc2'
}
And I have other User project that reference to Core.
When the User project, does reference to Core library:
User build.gradle
dependencies {
implementation 'com.example: core: 1.0'
}
In User project I can acces at butterknife classes but when I reference at Core project
User build.gradle
dependecies{
implementation project(":core")
}
I can't access to butterknife classes (Compilation failed; see the compiler error output for details.)
Is there any way to reference core and be able to use the dependencies referenced by core?
This is the way implementation configuration works.
The plugin exposes two configurations that can be used to declare dependencies: api and implementation. The api configuration should be used to declare dependencies which are exported by the library API, whereas the implementation configuration should be used to declare dependencies which are internal to the component.
Dependencies appearing in the api configurations will be transitively exposed to consumers of the library, and as such will appear on the compile classpath of consumers. Dependencies found in the implementation configuration will, on the other hand, not be exposed to consumers, and therefore not leak into the consumers' compile classpath.
Either declare Butter Knife as an api dependency, or depend on it explicitly in user/build.gradle.

Resources