You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beam.apache.org by sc...@apache.org on 2018/12/11 19:00:57 UTC

[beam] branch master updated: [BEAM-6178] Adding beam-sdks-java-bom, adding exportJavadoc flag for applyJavaNature (#7197)

This is an automated email from the ASF dual-hosted git repository.

scott pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git


The following commit(s) were added to refs/heads/master by this push:
     new bfd1be9  [BEAM-6178] Adding beam-sdks-java-bom, adding exportJavadoc flag for applyJavaNature (#7197)
bfd1be9 is described below

commit bfd1be9ae22d1ae7e732f590c448e9e5ed2894b9
Author: Garrett Jones <ga...@users.noreply.github.com>
AuthorDate: Tue Dec 11 11:00:50 2018 -0800

    [BEAM-6178] Adding beam-sdks-java-bom, adding exportJavadoc flag for applyJavaNature (#7197)
---
 .../org/apache/beam/gradle/BeamModulePlugin.groovy |  89 ++++++++-------
 examples/java/build.gradle                         |   2 +-
 runners/extensions-java/metrics/build.gradle       |   2 +-
 runners/flink/job-server/build.gradle              |   1 +
 .../examples-streaming/build.gradle                |   2 +-
 .../examples/build.gradle                          |   2 +-
 .../google-cloud-dataflow-java/worker/build.gradle |  24 ++--
 .../worker/legacy-worker/build.gradle              |   1 +
 runners/reference/job-server/build.gradle          |   1 +
 runners/samza/build.gradle                         |   2 +-
 sdks/java/bom/build.gradle                         | 122 +++++++++++++++++++++
 sdks/java/bom/pom.xml.template                     |  83 ++++++++++++++
 sdks/java/build-tools/build.gradle                 |   2 +-
 sdks/java/extensions/euphoria/build.gradle         |   2 +-
 sdks/java/extensions/kryo/build.gradle             |   7 +-
 sdks/java/extensions/sql/jdbc/build.gradle         |   7 +-
 sdks/java/io/common/build.gradle                   |   2 +-
 sdks/java/io/file-based-io-tests/build.gradle      |   2 +-
 sdks/java/io/kudu/build.gradle                     |   2 +-
 sdks/java/io/rabbitmq/build.gradle                 |   2 +-
 sdks/java/io/synthetic/build.gradle                |   2 +-
 sdks/java/javadoc/build.gradle                     |  70 ++++--------
 sdks/java/maven-archetypes/examples/build.gradle   |   2 +-
 sdks/java/maven-archetypes/starter/build.gradle    |   2 +-
 sdks/java/testing/load-tests/build.gradle          |   2 +-
 sdks/java/testing/nexmark/build.gradle             |   2 +-
 sdks/java/testing/test-utils/build.gradle          |   2 +-
 settings.gradle                                    |   2 +
 vendor/sdks-java-extensions-protobuf/build.gradle  |   7 +-
 29 files changed, 326 insertions(+), 122 deletions(-)

diff --git a/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy b/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy
index 329a6ed..acfffc9 100644
--- a/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy
+++ b/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy
@@ -123,6 +123,9 @@ class BeamModulePlugin implements Plugin<Project> {
 
     /** Controls whether this project is published to Maven. */
     boolean publish = true
+
+    /** Controls whether javadoc is exported for this project. */
+    boolean exportJavadoc = true
   }
 
   /** A class defining the set of configurable properties accepted by applyPortabilityNature. */
@@ -489,6 +492,47 @@ class BeamModulePlugin implements Plugin<Project> {
       relocate "com.google.thirdparty", project.getJavaRelocatedPath("com.google.thirdparty")
     }
 
+    project.ext.repositories = {
+      maven {
+        name "testPublicationLocal"
+        url "file://${project.rootProject.projectDir}/testPublication/"
+      }
+      maven {
+        url(project.properties['distMgmtSnapshotsUrl'] ?: isRelease(project)
+                ? 'https://repository.apache.org/service/local/staging/deploy/maven2'
+                : 'https://repository.apache.org/content/repositories/snapshots')
+
+        // We attempt to find and load credentials from ~/.m2/settings.xml file that a user
+        // has configured with the Apache release and snapshot staging credentials.
+        // <settings>
+        //   <servers>
+        //     <server>
+        //       <id>apache.releases.https</id>
+        //       <username>USER_TOKEN</username>
+        //       <password>PASS_TOKEN</password>
+        //     </server>
+        //     <server>
+        //       <id>apache.snapshots.https</id>
+        //       <username>USER_TOKEN</username>
+        //       <password>PASS_TOKEN</password>
+        //     </server>
+        //   </servers>
+        // </settings>
+        def settingsXml = new File(System.getProperty('user.home'), '.m2/settings.xml')
+        if (settingsXml.exists()) {
+          def serverId = (project.properties['distMgmtServerId'] ?: isRelease(project)
+                  ? 'apache.releases.https' : 'apache.snapshots.https')
+          def m2SettingCreds = new XmlSlurper().parse(settingsXml).servers.server.find { server -> serverId.equals(server.id.text()) }
+          if (m2SettingCreds) {
+            credentials {
+              username m2SettingCreds.username.text()
+              password m2SettingCreds.password.text()
+            }
+          }
+        }
+      }
+    }
+
     // Configures a project with a default set of plugins that should apply to all Java projects.
     //
     // Users should invoke this method using Groovy map syntax. For example:
@@ -789,6 +833,9 @@ class BeamModulePlugin implements Plugin<Project> {
         project.tasks.check.dependsOn project.tasks.validateShadedJarDoesntLeakNonProjectClasses
       }
 
+      project.ext.includeInJavaBom = configuration.publish
+      project.ext.exportJavadoc = configuration.exportJavadoc
+
       if ((isRelease(project) || project.hasProperty('publishing')) &&
       configuration.publish) {
         project.apply plugin: "maven-publish"
@@ -855,46 +902,7 @@ artifactId=${project.name}
         project.artifacts.archives project.javadocJar
 
         project.publishing {
-          repositories {
-            maven {
-              name "testPublicationLocal"
-              url "file://${project.rootProject.projectDir}/testPublication/"
-            }
-            maven {
-              url(project.properties['distMgmtSnapshotsUrl'] ?: isRelease(project)
-                      ? 'https://repository.apache.org/service/local/staging/deploy/maven2'
-                      : 'https://repository.apache.org/content/repositories/snapshots')
-
-              // We attempt to find and load credentials from ~/.m2/settings.xml file that a user
-              // has configured with the Apache release and snapshot staging credentials.
-              // <settings>
-              //   <servers>
-              //     <server>
-              //       <id>apache.releases.https</id>
-              //       <username>USER_TOKEN</username>
-              //       <password>PASS_TOKEN</password>
-              //     </server>
-              //     <server>
-              //       <id>apache.snapshots.https</id>
-              //       <username>USER_TOKEN</username>
-              //       <password>PASS_TOKEN</password>
-              //     </server>
-              //   </servers>
-              // </settings>
-              def settingsXml = new File(System.getProperty('user.home'), '.m2/settings.xml')
-              if (settingsXml.exists()) {
-                def serverId = (project.properties['distMgmtServerId'] ?: isRelease(project)
-                        ? 'apache.releases.https' : 'apache.snapshots.https')
-                def m2SettingCreds = new XmlSlurper().parse(settingsXml).servers.server.find { server -> serverId.equals(server.id.text()) }
-                if (m2SettingCreds) {
-                  credentials {
-                    username m2SettingCreds.username.text()
-                    password m2SettingCreds.password.text()
-                  }
-                }
-              }
-            }
-          }
+          repositories = project.ext.repositories
 
           publications {
             mavenJava(MavenPublication) {
@@ -1368,6 +1376,7 @@ artifactId=${project.name}
       PortabilityNatureConfiguration configuration = it ? it as PortabilityNatureConfiguration : new PortabilityNatureConfiguration()
 
       project.ext.applyJavaNature(
+              exportJavadoc: false,
               enableFindbugs: false,
               shadowJarValidationExcludes: it.shadowJarValidationExcludes,
               shadowClosure: GrpcVendoring.shadowClosure() << {
diff --git a/examples/java/build.gradle b/examples/java/build.gradle
index 4d98ba6..7b7fe3e 100644
--- a/examples/java/build.gradle
+++ b/examples/java/build.gradle
@@ -19,7 +19,7 @@
 import groovy.json.JsonOutput
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 provideIntegrationTestingDependencies()
 enableJavaPerformanceTesting()
 
diff --git a/runners/extensions-java/metrics/build.gradle b/runners/extensions-java/metrics/build.gradle
index 605f17b..cc5026b 100644
--- a/runners/extensions-java/metrics/build.gradle
+++ b/runners/extensions-java/metrics/build.gradle
@@ -17,7 +17,7 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 
 description = "Apache Beam :: Runners :: Extensions Java :: Metrics"
 ext.summary = "Beam Runners Extensions Metrics provides implementations of runners core metrics APIs."
diff --git a/runners/flink/job-server/build.gradle b/runners/flink/job-server/build.gradle
index 96ee3c0..08a6e2e 100644
--- a/runners/flink/job-server/build.gradle
+++ b/runners/flink/job-server/build.gradle
@@ -19,6 +19,7 @@ import groovy.json.JsonOutput
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
 applyJavaNature(
+  exportJavadoc: false,
   validateShadowJar: false,
   shadowClosure: {
     append "reference.conf"
diff --git a/runners/google-cloud-dataflow-java/examples-streaming/build.gradle b/runners/google-cloud-dataflow-java/examples-streaming/build.gradle
index f52ec1d..fca2a38 100644
--- a/runners/google-cloud-dataflow-java/examples-streaming/build.gradle
+++ b/runners/google-cloud-dataflow-java/examples-streaming/build.gradle
@@ -19,7 +19,7 @@
 import groovy.json.JsonOutput
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature(publish: false)
+applyJavaNature(publish: false, exportJavadoc: false)
 // Evaluate the given project before this one, to allow referencing
 // its sourceSets.test.output directly.
 evaluationDependsOn(":beam-examples-java")
diff --git a/runners/google-cloud-dataflow-java/examples/build.gradle b/runners/google-cloud-dataflow-java/examples/build.gradle
index e1e8bf8..5c7d15b 100644
--- a/runners/google-cloud-dataflow-java/examples/build.gradle
+++ b/runners/google-cloud-dataflow-java/examples/build.gradle
@@ -19,7 +19,7 @@
 import groovy.json.JsonOutput
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature(publish: false)
+applyJavaNature(publish: false, exportJavadoc: false)
 // Evaluate the given project before this one, to allow referencing
 // its sourceSets.test.output directly.
 evaluationDependsOn(":beam-examples-java")
diff --git a/runners/google-cloud-dataflow-java/worker/build.gradle b/runners/google-cloud-dataflow-java/worker/build.gradle
index 70b587a..555fe29 100644
--- a/runners/google-cloud-dataflow-java/worker/build.gradle
+++ b/runners/google-cloud-dataflow-java/worker/build.gradle
@@ -26,17 +26,23 @@ def DATAFLOW_VERSION = "dataflow.version"
 // Get full dependency of 'com.google.apis:google-api-services-dataflow'
 def google_api_services_dataflow = project.hasProperty(DATAFLOW_VERSION) ? "com.google.apis:google-api-services-dataflow:" + getProperty(DATAFLOW_VERSION) : library.java.google_api_services_dataflow
 
-applyJavaNature(publish: false, enableFindbugs: false /* TODO(BEAM-5658): enable findbugs */, validateShadowJar: false, shadowClosure: {
-  // In the case of the Fn API worker jar we are creating an application so we rely on
-  // the shadow plugin to include all transitive dependencies to create an uber jar.
+applyJavaNature(
+  publish: false,
+  exportJavadoc: false,
+  enableFindbugs: false /* TODO(BEAM-5658): enable findbugs */,
+  validateShadowJar: false,
+  shadowClosure: {
+    // In the case of the Fn API worker jar we are creating an application so we rely on
+    // the shadow plugin to include all transitive dependencies to create an uber jar.
 
-  // Include original source files extracted under
-  // '$buildDir/original_sources_to_package' to jar
-  from "$buildDir/original_sources_to_package"
+    // Include original source files extracted under
+    // '$buildDir/original_sources_to_package' to jar
+    from "$buildDir/original_sources_to_package"
 
-  exclude "META-INF/LICENSE.txt"
-  exclude "about.html"
-})
+    exclude "META-INF/LICENSE.txt"
+    exclude "about.html"
+  },
+)
 
 /******************************************************************************/
 // Configure the worker root project
diff --git a/runners/google-cloud-dataflow-java/worker/legacy-worker/build.gradle b/runners/google-cloud-dataflow-java/worker/legacy-worker/build.gradle
index 7551758..0746c74 100644
--- a/runners/google-cloud-dataflow-java/worker/legacy-worker/build.gradle
+++ b/runners/google-cloud-dataflow-java/worker/legacy-worker/build.gradle
@@ -80,6 +80,7 @@ def excluded_dependencies = [
 
 applyJavaNature(
         publish: false,
+        exportJavadoc: false,
         enableFindbugs: false /* TODO(BEAM-5658): enable findbugs */,
         shadowJarValidationExcludes: [
             "org/apache/beam/runners/dataflow/worker/**",
diff --git a/runners/reference/job-server/build.gradle b/runners/reference/job-server/build.gradle
index 919573d..5c2cd56 100644
--- a/runners/reference/job-server/build.gradle
+++ b/runners/reference/job-server/build.gradle
@@ -19,6 +19,7 @@ import groovy.json.JsonOutput
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
 applyJavaNature(
+  exportJavadoc: false,
   validateShadowJar: false,
   shadowClosure: {
   }
diff --git a/runners/samza/build.gradle b/runners/samza/build.gradle
index 3f9147a..7687c88 100644
--- a/runners/samza/build.gradle
+++ b/runners/samza/build.gradle
@@ -19,7 +19,7 @@
 import groovy.json.JsonOutput
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 
 description = "Apache Beam :: Runners :: Samza"
 
diff --git a/sdks/java/bom/build.gradle b/sdks/java/bom/build.gradle
new file mode 100644
index 0000000..b0375c4
--- /dev/null
+++ b/sdks/java/bom/build.gradle
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * License); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// beam-sdks-java-bom generates a BOM (Bill of Materials) in the form of
+// a pom.xml file, which enables users to easily import multiple modules
+// from Beam at the same version. See
+// https://github.com/GoogleCloudPlatform/cloud-opensource-java/blob/master/library-best-practices/JLBP-15.md
+// for more details on BOMs.
+
+apply plugin: org.apache.beam.gradle.BeamModulePlugin
+
+apply plugin: "java"
+apply plugin: "maven-publish"
+
+def isRelease(Project project) {
+  return project.hasProperty('isRelease')
+}
+
+ext {
+  mavenJavaDir = "$project.buildDir/publications/mavenJava"
+  mavenJavaBomOutputFile = file(mavenJavaDir + "/pom-default.xml")
+}
+
+for (p in rootProject.subprojects) {
+  if (!p.name.equals(project.name)) {
+    evaluationDependsOn(':' + p.name)
+  }
+}
+
+def bomModuleNames = new ArrayList<>()
+for (p in rootProject.subprojects) {
+  def subproject = project(':' + p.name)
+  if (subproject.ext.properties.containsKey('includeInJavaBom') &&
+      subproject.ext.properties.includeInJavaBom) {
+    bomModuleNames.add(subproject.name)
+  }
+}
+
+// Copy our pom.xml to the location where a generated POM would go
+task copyPom(type: Copy) {
+  from 'pom.xml.template'
+  into mavenJavaDir
+  rename 'pom.xml.template', 'pom-default.xml'
+  expand(version: project.version, modules: bomModuleNames)
+}
+
+assemble.dependsOn copyPom
+
+// We want to use our own pom.xml instead of the generated one, so we disable
+// the pom.xml generation and have the publish tasks depend on `copyPom` instead.
+tasks.whenTaskAdded { task ->
+  if (task.name == 'generatePomFileForMavenJavaPublication') {
+    task.enabled = false
+  } else if (task.name == 'publishMavenJavaPublicationToMavenLocal') {
+    task.dependsOn copyPom
+  } else if (task.name == 'publishMavenJavaPublicationToMavenRepository') {
+    task.dependsOn copyPom
+  }
+}
+
+jar.enabled = false
+
+// Remove the default jar archive which is added by the 'java' plugin.
+configurations.archives.artifacts.with { archives ->
+  def artifacts = []
+  archives.each {
+    if (it.file =~ 'jar') {
+      // We can't just call `archives.remove(it)` here because it triggers
+      // a `ConcurrentModificationException`, so we add matching artifacts
+      // to another list, then remove those elements outside of this iteration.
+      artifacts.add(it)
+    }
+  }
+  artifacts.each {
+    archives.remove(it)
+  }
+}
+
+artifacts {
+  archives(mavenJavaBomOutputFile) {
+    builtBy copyPom
+  }
+}
+
+afterEvaluate {
+  // We can't use the `publishing` section from applyJavaNature because
+  // we don't want all the Java artifacts, and we want to use our own pom.xml
+  // instead of the generated one.
+  publishing {
+    publications {
+      mavenJava(MavenPublication) {
+        version = project.version
+        artifact mavenJavaBomOutputFile
+      }
+    }
+    repositories project.ext.repositories
+  }
+
+  // Only sign artifacts if we are performing a release
+  if (isRelease(project) && !project.hasProperty('noSigning')) {
+    apply plugin: "signing"
+    signing {
+      useGpgCmd()
+      sign publishing.publications
+    }
+  }
+}
diff --git a/sdks/java/bom/pom.xml.template b/sdks/java/bom/pom.xml.template
new file mode 100644
index 0000000..7cade1a
--- /dev/null
+++ b/sdks/java/bom/pom.xml.template
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+      http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.beam</groupId>
+  <artifactId>beam-sdks-java-bom</artifactId>
+  <version>${version}</version>
+  <packaging>pom</packaging>
+  <url>http://beam.apache.org</url>
+  <inceptionYear>2016</inceptionYear>
+  <licenses>
+    <license>
+      <name>Apache License, Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+  <developers>
+    <developer>
+      <name>The Apache Beam Team</name>
+      <email>dev@beam.apache.org</email>
+      <url>http://beam.apache.org</url>
+      <organization>Apache Software Foundation</organization>
+      <organizationUrl>http://www.apache.org</organizationUrl>
+    </developer>
+  </developers>
+  <mailingLists>
+    <mailingList>
+      <name>Beam Dev</name>
+      <subscribe>dev-subscribe@beam.apache.org</subscribe>
+      <unsubscribe>dev-unsubscribe@beam.apache.org</unsubscribe>
+      <post>dev@beam.apache.org</post>
+      <archive>http://www.mail-archive.com/dev%beam.apache.org</archive>
+    </mailingList>
+    <mailingList>
+      <name>Beam User</name>
+      <subscribe>user-subscribe@beam.apache.org</subscribe>
+      <unsubscribe>user-unsubscribe@beam.apache.org</unsubscribe>
+      <post>user@beam.apache.org</post>
+      <archive>http://www.mail-archive.com/user%beam.apache.org</archive>
+    </mailingList>
+    <mailingList>
+      <name>Beam Commits</name>
+      <subscribe>commits-subscribe@beam.apache.org</subscribe>
+      <unsubscribe>commits-unsubscribe@beam.apache.org</unsubscribe>
+      <post>commits@beam.apache.org</post>
+      <archive>http://www.mail-archive.com/commits%beam.apache.org</archive>
+    </mailingList>
+  </mailingLists>
+  <scm>
+    <connection>scm:git:https://gitbox.apache.org/repos/asf/beam.git</connection>
+    <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/beam.git</developerConnection>
+    <url>https://gitbox.apache.org/repos/asf?p=beam.git;a=summary</url>
+  </scm>
+  <issueManagement>
+    <system>jira</system>
+    <url>https://issues.apache.org/jira/browse/BEAM</url>
+  </issueManagement>
+  <dependencyManagement>
+    <dependencies>
+    <% modules.each { moduleName -> %>
+      <dependency>
+        <groupId>org.apache.beam</groupId>
+        <artifactId>${moduleName}</artifactId>
+        <version>${version}</version>
+      </dependency>
+    <% } %>
+    </dependencies>
+  </dependencyManagement>
+</project>
diff --git a/sdks/java/build-tools/build.gradle b/sdks/java/build-tools/build.gradle
index 4f56560..d6fa86b 100644
--- a/sdks/java/build-tools/build.gradle
+++ b/sdks/java/build-tools/build.gradle
@@ -17,6 +17,6 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 
 description = "Apache Beam :: SDKs :: Java :: Build Tools"
diff --git a/sdks/java/extensions/euphoria/build.gradle b/sdks/java/extensions/euphoria/build.gradle
index e6ad573..6f04d87 100644
--- a/sdks/java/extensions/euphoria/build.gradle
+++ b/sdks/java/extensions/euphoria/build.gradle
@@ -17,7 +17,7 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 
 description = "Apache Beam :: SDKs :: Java :: Extensions :: Euphoria Java 8 DSL"
 
diff --git a/sdks/java/extensions/kryo/build.gradle b/sdks/java/extensions/kryo/build.gradle
index 6995551..305eb57 100644
--- a/sdks/java/extensions/kryo/build.gradle
+++ b/sdks/java/extensions/kryo/build.gradle
@@ -22,14 +22,17 @@ ext {
     kryoVersion = '4.0.2'
 }
 
-applyJavaNature(shadowClosure: DEFAULT_SHADOW_CLOSURE << {
+applyJavaNature(
+    exportJavadoc: false,
+    shadowClosure: DEFAULT_SHADOW_CLOSURE << {
     dependencies {
         include(dependency('com.esotericsoftware:.*'))
         include(dependency('org.ow2.asm:asm'))
     }
     relocate 'com.esotericsoftware', getJavaRelocatedPath('com.esotericsoftware')
     relocate 'org.objectweb', getJavaRelocatedPath('org.objectweb')
-})
+    }
+)
 
 description = 'Apache Beam :: SDKs :: Java :: Extensions :: Kryo'
 
diff --git a/sdks/java/extensions/sql/jdbc/build.gradle b/sdks/java/extensions/sql/jdbc/build.gradle
index d0a2379..0bc2257 100644
--- a/sdks/java/extensions/sql/jdbc/build.gradle
+++ b/sdks/java/extensions/sql/jdbc/build.gradle
@@ -19,7 +19,12 @@ import groovy.json.JsonOutput
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature(testShadowJar: true, validateShadowJar: false, shadowClosure: {})
+applyJavaNature(
+  exportJavadoc: false,
+  testShadowJar: true,
+  validateShadowJar: false,
+  shadowClosure: {}
+)
 
 configurations {
   integrationTest
diff --git a/sdks/java/io/common/build.gradle b/sdks/java/io/common/build.gradle
index 0dbb790..a5629fe 100644
--- a/sdks/java/io/common/build.gradle
+++ b/sdks/java/io/common/build.gradle
@@ -17,7 +17,7 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 
 description = "Apache Beam :: SDKs :: Java :: IO :: Common"
 ext.summary = "Code used by all Beam IOs"
diff --git a/sdks/java/io/file-based-io-tests/build.gradle b/sdks/java/io/file-based-io-tests/build.gradle
index 2626783..c22b6c8 100644
--- a/sdks/java/io/file-based-io-tests/build.gradle
+++ b/sdks/java/io/file-based-io-tests/build.gradle
@@ -17,7 +17,7 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 provideIntegrationTestingDependencies()
 enableJavaPerformanceTesting()
 
diff --git a/sdks/java/io/kudu/build.gradle b/sdks/java/io/kudu/build.gradle
index 5457ec7..e543e8f 100644
--- a/sdks/java/io/kudu/build.gradle
+++ b/sdks/java/io/kudu/build.gradle
@@ -17,7 +17,7 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 provideIntegrationTestingDependencies()
 enableJavaPerformanceTesting()
 
diff --git a/sdks/java/io/rabbitmq/build.gradle b/sdks/java/io/rabbitmq/build.gradle
index bef18f9..8962463 100644
--- a/sdks/java/io/rabbitmq/build.gradle
+++ b/sdks/java/io/rabbitmq/build.gradle
@@ -17,7 +17,7 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 
 description = "Apache Beam :: SDKs :: Java :: IO :: RabbitMQ"
 ext.summary = "IO to read and write to a RabbitMQ broker."
diff --git a/sdks/java/io/synthetic/build.gradle b/sdks/java/io/synthetic/build.gradle
index 900f61d..f147fab 100644
--- a/sdks/java/io/synthetic/build.gradle
+++ b/sdks/java/io/synthetic/build.gradle
@@ -17,7 +17,7 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 
 description = "Apache Beam :: SDKs :: Java :: IO :: Synthetic"
 ext.summary = "Generators of Synthetic IO for Testing."
diff --git a/sdks/java/javadoc/build.gradle b/sdks/java/javadoc/build.gradle
index e80f263..87cb318 100644
--- a/sdks/java/javadoc/build.gradle
+++ b/sdks/java/javadoc/build.gradle
@@ -26,65 +26,33 @@
 description = "Apache Beam :: SDKs :: Java :: Aggregated Javadoc"
 apply plugin: 'java'
 
-def exportedJavadocProjects = [
-  ':beam-runners-apex',
-  ':beam-runners-core-construction-java',
-  ':beam-runners-core-java',
-  ':beam-runners-java-fn-execution',
-  ':beam-runners-local-java-core',
-  ':beam-runners-direct-java',
-  ':beam-runners-reference-java',
-  ':beam-runners-flink_2.11',
-  ':beam-runners-google-cloud-dataflow-java',
-  ':beam-runners-spark',
-  ':beam-runners-gearpump',
-  ':beam-sdks-java-core',
-  ':beam-sdks-java-fn-execution',
-  ':beam-sdks-java-extensions-google-cloud-platform-core',
-  ':beam-sdks-java-extensions-join-library',
-  ':beam-sdks-java-extensions-json-jackson',
-  ':beam-sdks-java-extensions-protobuf',
-  ':beam-sdks-java-extensions-sketching',
-  ':beam-sdks-java-extensions-sorter',
-  ':beam-sdks-java-extensions-sql',
-  ':beam-sdks-java-harness',
-  ':beam-sdks-java-io-amazon-web-services',
-  ':beam-sdks-java-io-amqp',
-  ':beam-sdks-java-io-cassandra',
-  ':beam-sdks-java-io-elasticsearch',
-  ':beam-sdks-java-io-elasticsearch-tests-2',
-  ':beam-sdks-java-io-elasticsearch-tests-5',
-  ':beam-sdks-java-io-elasticsearch-tests-6',
-  ':beam-sdks-java-io-elasticsearch-tests-common',
-  ':beam-sdks-java-io-google-cloud-platform',
-  ':beam-sdks-java-io-hadoop-common',
-  ':beam-sdks-java-io-hadoop-file-system',
-  ':beam-sdks-java-io-hadoop-format',
-  ':beam-sdks-java-io-hadoop-input-format',
-  ':beam-sdks-java-io-hbase',
-  ':beam-sdks-java-io-hcatalog',
-  ':beam-sdks-java-io-jdbc',
-  ':beam-sdks-java-io-jms',
-  ':beam-sdks-java-io-kafka',
-  ':beam-sdks-java-io-kinesis',
-  ':beam-sdks-java-io-mongodb',
-  ':beam-sdks-java-io-mqtt',
-  ':beam-sdks-java-io-parquet',
-  ':beam-sdks-java-io-redis',
-  ':beam-sdks-java-io-solr',
-  ':beam-sdks-java-io-tika',
-  ':beam-sdks-java-io-xml',
-]
+for (p in rootProject.subprojects) {
+  if (!p.name.equals(project.name) && !p.name.equals('beam-sdks-java-bom')) {
+    evaluationDependsOn(':' + p.name)
+  }
+}
 
-for (String exportedJavadocProject : exportedJavadocProjects) {
-  evaluationDependsOn(exportedJavadocProject)
+ext.getExportedJavadocProjects = {
+  def exportedJavadocProjects = new ArrayList<>();
+  for (p in rootProject.subprojects) {
+    if (!p.name.equals(project.name) && !p.name.equals('beam-sdks-java-bom')) {
+      def subproject = project(':' + p.name)
+      if (subproject.ext.properties.containsKey('exportJavadoc') &&
+          subproject.ext.properties.exportJavadoc) {
+        exportedJavadocProjects.add(':' + p.name)
+      }
+    }
+  }
+  return exportedJavadocProjects
 }
 
 task allJavadoc() {
+  def exportedJavadocProjects = getExportedJavadocProjects()
   dependsOn exportedJavadocProjects.collect { "$it:javadoc" }
 }
 
 task aggregateJavadoc(type: Javadoc) {
+  def exportedJavadocProjects = getExportedJavadocProjects()
   source exportedJavadocProjects.collect { project(it).sourceSets.main.allJava }
   classpath = files(exportedJavadocProjects.collect { project(it).sourceSets.main.compileClasspath })
   destinationDir = file("${buildDir}/docs/javadoc")
diff --git a/sdks/java/maven-archetypes/examples/build.gradle b/sdks/java/maven-archetypes/examples/build.gradle
index b16fb33..2958101 100644
--- a/sdks/java/maven-archetypes/examples/build.gradle
+++ b/sdks/java/maven-archetypes/examples/build.gradle
@@ -17,7 +17,7 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 
 description = "Apache Beam :: SDKs :: Java :: Maven Archetypes :: Examples"
 ext.summary = """A Maven Archetype to create a project containing all the
diff --git a/sdks/java/maven-archetypes/starter/build.gradle b/sdks/java/maven-archetypes/starter/build.gradle
index da533b1..34231a2 100644
--- a/sdks/java/maven-archetypes/starter/build.gradle
+++ b/sdks/java/maven-archetypes/starter/build.gradle
@@ -17,7 +17,7 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 
 description = "Apache Beam :: SDKs :: Java :: Maven Archetypes :: Starter"
 ext.summary = """A Maven archetype to create a simple starter pipeline to
diff --git a/sdks/java/testing/load-tests/build.gradle b/sdks/java/testing/load-tests/build.gradle
index c611747..e9ec206 100644
--- a/sdks/java/testing/load-tests/build.gradle
+++ b/sdks/java/testing/load-tests/build.gradle
@@ -17,7 +17,7 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 
 description = "Apache Beam :: SDKs :: Java :: Load Tests"
 
diff --git a/sdks/java/testing/nexmark/build.gradle b/sdks/java/testing/nexmark/build.gradle
index 16d144e..3b19f7e 100644
--- a/sdks/java/testing/nexmark/build.gradle
+++ b/sdks/java/testing/nexmark/build.gradle
@@ -17,7 +17,7 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 
 description = "Apache Beam :: SDKs :: Java :: Nexmark"
 
diff --git a/sdks/java/testing/test-utils/build.gradle b/sdks/java/testing/test-utils/build.gradle
index 380b31d..bb874a4 100644
--- a/sdks/java/testing/test-utils/build.gradle
+++ b/sdks/java/testing/test-utils/build.gradle
@@ -17,7 +17,7 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature()
+applyJavaNature(exportJavadoc: false)
 
 description = "Apache Beam :: SDKs :: Java :: Test Utils"
 
diff --git a/settings.gradle b/settings.gradle
index f294291..9dc2348 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -206,3 +206,5 @@ include "beam-runners-google-cloud-dataflow-java-windmill"
 project(":beam-runners-google-cloud-dataflow-java-windmill").dir = file("runners/google-cloud-dataflow-java/worker/windmill")
 include "beam-test-infra-metrics"
 project(":beam-test-infra-metrics").dir = file(".test-infra/metrics")
+include "beam-sdks-java-bom"
+project(":beam-sdks-java-bom").dir = file("sdks/java/bom")
diff --git a/vendor/sdks-java-extensions-protobuf/build.gradle b/vendor/sdks-java-extensions-protobuf/build.gradle
index fd771ad..f09dc60 100644
--- a/vendor/sdks-java-extensions-protobuf/build.gradle
+++ b/vendor/sdks-java-extensions-protobuf/build.gradle
@@ -17,7 +17,9 @@
  */
 
 apply plugin: org.apache.beam.gradle.BeamModulePlugin
-applyJavaNature(shadowClosure: DEFAULT_SHADOW_CLOSURE << {
+applyJavaNature(
+    exportJavadoc: false,
+    shadowClosure: DEFAULT_SHADOW_CLOSURE << {
     dependencies {
         include(dependency('com.google.guava:guava:20.0'))
         include(dependency('com.google.protobuf:protobuf-java:3.5.1'))
@@ -33,7 +35,8 @@ applyJavaNature(shadowClosure: DEFAULT_SHADOW_CLOSURE << {
     relocate "com.google.thirdparty", "org.apache.beam.vendor.grpc.v1_13_1.com.google.thirdparty"
 
     relocate "com.google.protobuf", "org.apache.beam.vendor.grpc.v1_13_1.com.google.protobuf"
-})
+    }
+)
 
 description = "Apache Beam :: Vendored Dependencies :: SDKs :: Java :: Extensions :: Protobuf"
 ext.summary = "Add support to Apache Beam for Vendored Google Protobuf."