Conversation
chanseokoh
left a comment
There was a problem hiding this comment.
Perhaps it'll cause less friction to remove benchmark in a separate PR.
I guess this is the first step, and it'll be (a lot of) more work we can eventually get rid of Gradle, right? Hopefully we don't end up keeping three build systems for a considerable amount of time.
| </exclusion> | ||
| <exclusion> | ||
| <groupId>com.google.errorprone</groupId> | ||
| <artifactId>error_prone_annotations</artifactId> |
There was a problem hiding this comment.
Is is basically a standard practice to exclude these dependencies? I feel the maintainers of the truth should fix their project setup so that these transitive dependencies are not exposed to library users?
No action needed.
There was a problem hiding this comment.
The reason I had to exclude it was because different dependencies were pulling in different versions of error_prone_annotations transitively and causing upper bound failures. Apparently, some error prone annotations have runtime scope. So, the dependency can't be provided.
@suztomo In case you have any comments on this.
Q: how can this be done? That is, how to ensure they both Bazel and Maven are always synced to use the same versions of all the JARs involved (whether for the compile classpath, runtime classpath, annotation classpath, etc.)? |
|
|
||
| <parent> | ||
| <groupId>com.google.cloud</groupId> | ||
| <artifactId>google-cloud-shared-config</artifactId> |
There was a problem hiding this comment.
Is this parent necessary? For what? The Gradle doesn't seem to use it? And we specify all the versions of the libraries in the dependency management section?
There was a problem hiding this comment.
This is to help us align better with client libraries. It has some checks and general configuration that is useful.
There was a problem hiding this comment.
Cool. Just wanted to make sure we don't diverge from the Bazel setup. Once we start doing that, it will be difficult to reconcile and maintain them later.
There was a problem hiding this comment.
This will technically change how gax artifacts get published on maven (they are getting parents which they used to not have).
Maybe it is ok, but we should be careful here. Can it cause any breakages and/or dependency conflicts for existing users of this? Also, I'm not sure if changing a parent can be considered a breaking change for maven atrifact or not.
There was a problem hiding this comment.
I don't think it's a breaking change. Besides, almost everything else in the Java SDK has it as the parent.
| // ---------- | ||
|
|
||
| task sourcesJar(type: Jar, dependsOn: classes) { | ||
| duplicatesStrategy = DuplicatesStrategy.EXCLUDE |
There was a problem hiding this comment.
Oh, interesting. Were we having duplicate entries? Which files? Or, was it that you just noticed a deprecation warning and found a way to resolve it?
There was a problem hiding this comment.
I get it on the gax/src/main/resources/dependencies.properties and only when running ./gradlew build publishToMavenLocal. It looks like the file created by build overlaps with sourcesJar. If there is a better way to handle it, please let me know.
There was a problem hiding this comment.
Hmm... I think this is because now gax/src/main/resources/dependencies.properties is checked in as source. So I guess what's happening is that, because a final version is generated at .gax/build/resources/main/dependencies.properties, now you have two dependencies.properties files to include
I think DuplicatesStrategy.EXCLUDE could be a problem, because it doesn't deterministically guarantee which file will win in the end. However, for a source JAR, I actually start to think there may be no reason to add this properties file? Not sure if it's the standard practice to add this kind of resource files into a source JAR. OTOH, since the file is part of the source set (it's under src/main), it also makes sense to include it, perhaps the one before processing with templating.
Let me try to find a way to include the original source file.
There was a problem hiding this comment.
Actually, it is correct that the error is due to the new gax/src/main/resources/dependencies.properties, but this is not because we have a processed file with the same filename under gax/build/.
task sourcesJar(type: Jar, dependsOn: classes) {
archiveClassifier = 'sources'
from sourceSets.main.allSource, sourceSets.test.allSource, sourceSets.main.resources.srcDirs
exclude('**/*Test.java')
}So the sources JAR is composed of main.allSource, test.allSource, and main.resources. (BTW, we could just say sourceSets.main.resources instead of sourceSets.main.resources.srcDirs.)
The thing is, allSource already includes resources. The default is a list [java, resources] as documented. So, it's redundant to specify main.resources again. Indeed, if I change it to
from sourceSets.main.allSource, sourceSets.test.allSource
I still see dependencies.properties in build/libs/gax-2.7.1-SNAPSHOT-sources.jar after running ./gradlew :gax:sourcesJar. OTOH, if I change it to from sourceSets.main.allJava, sourceSets.test.allSource, I don't see the properties file in the -sources.jar.
To sum, don't set duplicatesStrategy, but set from sourceSets.main.allSource, sourceSets.test.allSource (remove main.resources).
There was a problem hiding this comment.
Thanks for the investigation. This clears things up. As a side note, I'm not sure why we are including test sources at all, yet exclude all files ending in *Test.java.
There was a problem hiding this comment.
Hmm... good point. My guess is that, this repo is also generating *-testlib.jar files that I think contain some test utility classes (whose filename doesn't end with *Test.java). Maybe per the Maven Central requirements or convention, because we are publishing -testlib.jar files, we also need to include source files.
There was a problem hiding this comment.
The change looks fine to me, but please make sure that:
- Change of the parent (in terms of maven artifacts) is ok and non-breaking.
- Please verify that
mvn installworks and then using the newly installed version (x.x.x-SNAPSHOT) directly in any of the existing gapic clients (I would recommend java-language as it is a simple one) still works. - For
dependencies.propertiesfile, please note it is also accessed in java code (https://github.com/googleapis/gax-java/blob/main/gax/src/main/java/com/google/api/gax/core/GaxProperties.java#L69), so it ineeds to be cleaned up too (may be not that simple, as it is needed to get gax library version when it is not packaged in a jar and is executed from sources or bazel contex). - The root
pom.xmlhas all transitive dependencies listed (such that bazel integration still can get all the dependencies and their versions).
|
|
||
| <parent> | ||
| <groupId>com.google.cloud</groupId> | ||
| <artifactId>google-cloud-shared-config</artifactId> |
There was a problem hiding this comment.
This will technically change how gax artifacts get published on maven (they are getting parents which they used to not have).
Maybe it is ok, but we should be careful here. Can it cause any breakages and/or dependency conflicts for existing users of this? Also, I'm not sure if changing a parent can be considered a breaking change for maven atrifact or not.
@vam-google, I think you told me that there is an easier way to integrate Maven with Bazel. |
@vam-google I created an issue googleapis/gapic-generator-java#1318 to track the various steps in the migration to Maven.
Note that the
Can you provide some pointers to help understand the "bazel integration"? |
We still need to keep this mind, since we are going to remove |
|
Looks like both the Gradle dependency |
|
@vam-google @chanseokoh Are you guys comfortable with merging this in? Remember, this is by no means a full replacement for Gradle yet. There are more steps to come. |
|
Kudos, SonarCloud Quality Gate passed! |
|
Merge-on-green attempted to merge your PR for 6 hours, but it was not mergeable because either one of your required status checks failed, one of your required reviews was not approved, or there is a do not merge label. Learn more about your required status checks here: https://help.github.com/en/github/administering-a-repository/enabling-required-status-checks. You can remove and reapply the label to re-run the bot. |
| pull_request: | ||
| name: ci | ||
| jobs: | ||
| maven-units: |
There was a problem hiding this comment.
If you pull the bazel build part out into a sepaarate workflow file, you should be able to use GitHub Matrix feature and save some code duplication.
matrix:
script: [build.sh, maven-build.sh]There was a problem hiding this comment.
Good point. However, the gradle build will eventually be replaced by maven build though, so not sure if it's worth it.
There was a problem hiding this comment.
It's up to you. I guess removing Gradle would be easy in this setup too.
…and maven folder from META-INF folder in the maven built jar. Change the phase of format plugin from verify to validate to match the gradle behavior.
|
Kudos, SonarCloud Quality Gate passed! |
|
LGTM! Thanks for taking this PR across the finish line. |
vam-google
left a comment
There was a problem hiding this comment.
Overall it looks good, but there is a big concern about dependencies consistency across different build systems and if we have any strategy for that.
| <dependency> | ||
| <groupId>com.google.api</groupId> | ||
| <artifactId>api-common</artifactId> | ||
| <version>2.1.5</version> |
There was a problem hiding this comment.
This makes inconsistent which versions are used for gradle+bazel and which for maven. I understand that this is a good first step, but for this to work properly, we need some mechanism for a single source of truth for those version numbers between different build systems (now it is dependencies.properties).
There was a problem hiding this comment.
This is an interim state. The plan is for the Gradle build to go away. We can keep the versions in sync with Bazel manually. Ultimately, we need to figure out if we can just rely on a single build system. Is the Bazel build used for self-service? I'm not sure why we absolutely need it.
There was a problem hiding this comment.
I agree with Mike as well that eventually we want to be on a single build system, and I checked gapic-generator-java and googleapis that the bazel stuff in gax-java are only used for loading dependencies, which I think can be replaced completely by bazel targets in gapic-generator-java. My vision is that the pom.xml in the GAPIC generator mono repo will be the source of truth for dependencies, and I don't think we can get rid of dependencies.properties completely before we move gax-java to the mono repo.
In short, this is the plan:
- Add maven build(This PR).
- Replicate all gradle features(CI, release etc.) in maven and remove gradle build.
- Release with Maven dependencies. Before each gax-java release, we may have to manually sync
dependency.propertiesto keep things in sync for the time being. - Move
gax-javato the GAPIC mono repo so that it shares dependency management withgapic-generator-java. - Do some changes accordingly in the mono repo so that the client library generation depends on the root pom.xml for loading dependencies(This part is not well designed yet but I believe it can be done).
We are probably not going to change the bazel surface in gapic-generator-java(like java_gapic_library), so that all the client libraries and self service can still be generated seamlessly, but we will change how the dependencies are loaded.
There was a problem hiding this comment.
@meltsufin Every single automatically generated PR that you currently getting from owlbot is created using bazel build (and that relies on gax dependencies.properties). It is also used for self-service, that is correct.
And it is also very useful for development, though it may look useless on release step. For any gapic-gen/gax development work it s extremely useful. For example, with the REST transport work, I can simply plug in gax and gapic-generator in build and generate, compile and run all unit tests for all APIs in both transport (27,000 tests in one run on one maching by simply replacing http_archive to local_repository). It is also very easy to do and repeat it after every change in the generator (and due to caching, the run is also fast). I literally have no idea how else I would test and fix this whole thing on googleapis scale without this bazel build.
I'm afraid that we are on a path of fixing problems in release workflow by creating severe problems in development workflow. The reason why the autogenerated PRs produce working and compilable code and Java, for example, does not suffer from the same problems as Python releases suffer (broken code being generated), is precisely due to gax and gapic-generator being tightly integrated into the bazel build.
There was a problem hiding this comment.
We fully intend to keep dependencies.properties up to date and we have no plans to break the Bazel build as part of the migration to Maven. If we are actually breaking any of the existing workflows, please let us know. However, this PR is not doing that.
There was a problem hiding this comment.
I can simply plug in gax and gapic-generator in build and generate, compile and run all unit tests for all APIs in both transport
This is very interesting, can you please share the script you are using? I can make sure we are not breaking the script or create a similar experience with maven.
The reason why the autogenerated PRs produce working and compilable code and Java, for example, does not suffer from the same problems as Python releases suffer (broken code being generated), is precisely due to gax and gapic-generator being tightly integrated into the bazel build.
Can you please elaborate the example? How bazel build can help prevent generating broken code? I thought it's mostly the code logic(like AST stuff) in the generator itself not the build system.
vam-google
left a comment
There was a problem hiding this comment.
LGTM, but we need a good strategy for dependencies management and supporting both maven and bazel builds.








The goal of adding Maven is to align with the rest of the client library repositories that use Maven. This should enable us to take advantage of more automation tools that have been designed and tested against Maven-based repositories. This should also simplify integration with Bazel and eliminate the need for
/dependencies.properties.[blakeli] Please note that this PR is the first step towards migrating to maven, the purpose is to add a maven build in parallel of gradle/bazel. There will be a lot of follow up PRs to replicate all the features of gradle/bazel and eventually replace gradle.