[SDFAB-1196] Build ONOS with Bazel 6.0.0 pre-release

This was a quite big jump (3.7.2 -> 6.x.x) and we had
to face the deprecation of several components.

- javabase/host_javabase -> java_language_version and
java_runtime_version

- java_toolchain/host_java_toolchain -> java_language_version
and java_runtime_version

- Turnedoff "ReturnValueIgnored" related to ErrorProne

- Moved to bazelisk v1.11.0

- patched again the grpc code due to the deprecation of host_javabase
as java_toolcahin contains already this information.

- resource_jars are also handled as resources because java constructs
do not accept them anymore.

- Use the OSGIWrapper to fix the path of the resource_hars and untar them.
Additionally clean up the code and enable/disable logging through a param.

- Fix absolute_javabase in the Dockerfile by providing the absolute
path of the local jvm through local_java_repository. The latter is
appended to the WORKSPACE file on demand inside the Dockerfile.

Change-Id: I96e06fe52b3b49a1a34f01443eec583a95347323
diff --git a/.bazelrc b/.bazelrc
index 0d3b799..2b9ed65 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -1,20 +1,16 @@
 # By default, we build and run ONOS using the Bazel-provided remote JDK. The
 # specific JDK version is defined in tools/build/jdk/BUILD.
 #
-# If you prefer to use your locally installed JDK, replace the --javabase and
-# --host_javabase arguments with the following lines. ABSOLUTE_JAVABASE should
-# point to the "JAVA_HOME" of your JDK.
+# If you prefer to use your locally installed JDK use local_java_repositoy
+# in the WORKSPACE file.
 #
-# build --javabase=@bazel_tools//tools/jdk:absolute_javabase
-# build --host_javabase=@bazel_tools//tools/jdk:absolute_javabase
-# build --define=ABSOLUTE_JAVABASE=<path/to/jdk>
-# build --define=RUN_WITH_ABSOLUTE_JAVABASE=true
+# https://bazel.build/docs/bazel-and-java
 
-build --javabase=@org_onosproject_onos//tools/build/jdk:default_jdk
-build --host_javabase=@org_onosproject_onos//tools/build/jdk:default_jdk
-
-build --java_toolchain=@org_onosproject_onos//tools/build/jdk:default_toolchain
-build --host_java_toolchain=@org_onosproject_onos//tools/build/jdk:default_toolchain
+# Builds using remotejdk_11, executes using remotejdk_11 or local_jdk
+build --java_language_version=11
+build --java_runtime_version=remotejdk_11
+build --tool_java_language_version=11
+build --tool_java_runtime_version=remotejdk_11
 
 build --host_force_python=PY2
 
@@ -22,7 +18,7 @@
 build --experimental_strict_action_env
 
 # For external/io_grpc_grpc_java/core/src/main/java/io/grpc/internal/RetriableStream.java
-build --javacopt="-Xep:GuardedBy:WARN -Xep:ComparableType:WARN"
+build --javacopt="-Xep:GuardedBy:WARN -Xep:ComparableType:WARN -Xep:ReturnValueIgnored:OFF"
 
 # intellij-bazel plugin needs this
 build --incompatible_new_actions_api=false
diff --git a/.bazelversion b/.bazelversion
index 47b6be3..91e1ea4 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-3.7.2
\ No newline at end of file
+6.0.0-pre.20220421.3
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index f4fb784..129e7cf 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,3 +1,19 @@
+# Copyright 2015-present Open Networking Foundation
+#
+# Licensed 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.
+
+# With this dockerfile you can build a ONOS Docker container
+
 ARG JOBS=2
 ARG PROFILE=default
 ARG TAG=11.0.8-11.41.23
@@ -21,7 +37,7 @@
 
 # Install Bazelisk, which will download the version of bazel specified in
 # .bazelversion
-RUN curl -L -o bazelisk https://github.com/bazelbuild/bazelisk/releases/download/v1.5.0/bazelisk-linux-amd64
+RUN curl -L -o bazelisk https://github.com/bazelbuild/bazelisk/releases/download/v1.11.0/bazelisk-linux-amd64
 RUN chmod +x bazelisk && mv bazelisk /usr/bin
 
 # Build-stage environment variables
@@ -36,16 +52,15 @@
 # Build ONOS using the JDK pre-installed in the base image, instead of the
 # Bazel-provided remote one. By doing wo we make sure to build with the most
 # updated JDK, including bug and security fixes, independently of the Bazel
-# version.
+# version. NOTE that WORKSPACE-docker file defines dockerjdk
 ARG JOBS
 ARG JAVA_PATH
 ARG PROFILE
-RUN bazelisk build onos \
+RUN cat WORKSPACE-docker >> WORKSPACE && bazelisk build onos \
     --jobs ${JOBS} \
     --verbose_failures \
-    --javabase=@bazel_tools//tools/jdk:absolute_javabase \
-    --host_javabase=@bazel_tools//tools/jdk:absolute_javabase \
-    --define=ABSOLUTE_JAVABASE=${JAVA_PATH} \
+    --java_runtime_version=dockerjdk_11 \
+    --tool_java_runtime_version=dockerjdk_11 \
     --define profile=${PROFILE}
 
 # We extract the tar in the build environment to avoid having to put the tar in
diff --git a/WORKSPACE-docker b/WORKSPACE-docker
new file mode 100644
index 0000000..1b2b0d7
--- /dev/null
+++ b/WORKSPACE-docker
@@ -0,0 +1,16 @@
+
+# Appended by the Dockerfiles to help bazel finding the local path of
+# the Azul jvm. When we build docker images we use the jvm available
+# in the base image to compile ONOS. In order to do that we have to
+# provide the absolute path by using the local_java_repository.
+
+# local_java_repository for docker based builds
+load("@bazel_tools//tools/jdk:local_java_repository.bzl", "local_java_repository")
+
+ABSOLUTE_JAVABASE = "/usr/lib/jvm/zulu11-ca-amd64"
+
+local_java_repository(
+  name = "dockerjdk",
+  version = "11",
+  java_home = ABSOLUTE_JAVABASE,
+)
diff --git a/tools/build/bazel/grpc_workspace.bzl b/tools/build/bazel/grpc_workspace.bzl
index f2f3dfc..1a680da 100644
--- a/tools/build/bazel/grpc_workspace.bzl
+++ b/tools/build/bazel/grpc_workspace.bzl
@@ -1,7 +1,7 @@
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
 
 GRPC_JAVA_VERSION = "1.22.1"
-GRPC_SHA = "e6915ea60ab8a6e17de86bd94a8db320b0115cc214db19bef8f2ba4af2dab430"
+GRPC_SHA = "073395219d611c21a460d21dfe5cb77550030d6396b400f796e568b5175c2ec0"
 
 GAPIS_COMMIT = "37cc0e5acae50ee91f00827a7010c3b07dfa5311"
 GAPIS_SHA = "17d023f48ea290f25edaf25a967973b5a42ce6d71b1570862f302d95aa8b9f77"
@@ -10,9 +10,9 @@
     # grpc-java fork that fixes the OSGi split brain problem.
     http_archive(
         name = "io_grpc_grpc_java",
-        urls = ["https://github.com/opennetworkinglab/grpc-java/archive/v%s-patched.zip" % GRPC_JAVA_VERSION],
+        urls = ["https://github.com/opennetworkinglab/grpc-java/archive/v%s-fix-host_javabase.zip" % GRPC_JAVA_VERSION],
         sha256 = GRPC_SHA,
-        strip_prefix = "grpc-java-%s-patched" % GRPC_JAVA_VERSION,
+        strip_prefix = "grpc-java-%s-fix-host_javabase" % GRPC_JAVA_VERSION,
     )
 
     # Google APIs protos (status.proto, etc.)
diff --git a/tools/build/bazel/osgi_java_library.bzl b/tools/build/bazel/osgi_java_library.bzl
index 491444f..0236db4 100644
--- a/tools/build/bazel/osgi_java_library.bzl
+++ b/tools/build/bazel/osgi_java_library.bzl
@@ -124,6 +124,8 @@
         bundle_classpath,
         karaf_commands,
         fragment_host,
+        # enable/disable osgi-wrap logging
+        "false",
     ]
 
     ctx.actions.run(
@@ -507,7 +509,7 @@
         native.java_library(
             name = name + "-native",
             srcs = native_srcs,
-            resource_jars = resource_jars + [name + "_cfgdef_jar"],
+            resources = resource_jars + [name + "_cfgdef_jar"],
             deps = deps,
             visibility = visibility,
             javacopts = javacopts,
@@ -516,13 +518,14 @@
         native.java_library(
             name = name + "-native",
             srcs = native_srcs,
-            resource_jars = [name + "_cfgdef_jar"],
-            resources = native_resources,
+            resources = native_resources + [name + "_cfgdef_jar"],
             deps = deps,
             visibility = visibility,
             javacopts = javacopts,
         )
 
+    # NOTE that the additional resource_jars are modified by
+    # osgi-wrap because java_library does not decompress them.
     karaf_command_packages_string = ",".join(karaf_command_packages)
     _bnd(
         name = name,
diff --git a/tools/build/bazel/topo_BUILD b/tools/build/bazel/topo_BUILD
index 9a42836..a3418b2 100644
--- a/tools/build/bazel/topo_BUILD
+++ b/tools/build/bazel/topo_BUILD
@@ -16,6 +16,6 @@
     name = "topo_device_proto_sed",
     srcs = [":device/device.proto"],
     outs = ["new/device/device.proto"],
-    cmd = "sed -e 's:import \"gogoproto.*;::g;s: ..gogoproto\..*:;:g;s:import \"%s:import \":g;s:^syntax = \"proto3\";:&\\\n  option java_package = \"org.onosproject.uonos\";:g' $(location :device/device.proto) >> \"$@\""
+    cmd = "sed -e 's:import \"gogoproto.*;::g;s: ..gogoproto\\..*:;:g;s:import \"%s:import \":g;s:^syntax = \"proto3\";:&\\\n  option java_package = \"org.onosproject.uonos\";:g' $(location :device/device.proto) >> \"$@\""
         % IMPORT_PREFIX,
 )
diff --git a/tools/build/jdk/BUILD b/tools/build/jdk/BUILD
index 0055031..c99f398 100644
--- a/tools/build/jdk/BUILD
+++ b/tools/build/jdk/BUILD
@@ -1,24 +1,3 @@
-# This is where we define the JDK used to build ONOS, as well as the language
-# source and target values passed to javac. The :default_toolchain and
-# :default_jdk are expected to be passed as arguments when invoking bazel build
-# (see onos/.bazelrc)
-
-load("//tools/build/bazel:variables.bzl", "DEFAULT_JAVA_VERSION")
-load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "default_java_toolchain")
-
-default_java_toolchain(
-    name = "default_toolchain",
-    source_version = DEFAULT_JAVA_VERSION,
-    target_version = DEFAULT_JAVA_VERSION,
-    visibility = ["//visibility:public"],
-)
-
-alias(
-    name = "default_jdk",
-    actual = "@bazel_tools//tools/jdk:remote_jdk11",
-    visibility = ["//visibility:public"],
-)
-
 # We use the following rule to package the same JDK used for building and make
 # it available for external scripts as their JAVA_HOME, such as for `bazel run
 # onos-local`.
diff --git a/tools/dev/Dockerfile-yourkit b/tools/dev/Dockerfile-yourkit
index d54460e..176c3b3 100644
--- a/tools/dev/Dockerfile-yourkit
+++ b/tools/dev/Dockerfile-yourkit
@@ -41,7 +41,7 @@
 
 # Install Bazelisk, which will download the version of bazel specified in
 # .bazelversion
-RUN curl -L -o bazelisk https://github.com/bazelbuild/bazelisk/releases/download/v1.5.0/bazelisk-linux-amd64
+RUN curl -L -o bazelisk https://github.com/bazelbuild/bazelisk/releases/download/v1.11.0/bazelisk-linux-amd64
 RUN chmod +x bazelisk && mv bazelisk /usr/bin
 
 # Build-stage environment variables
@@ -56,16 +56,15 @@
 # Build ONOS using the JDK pre-installed in the base image, instead of the
 # Bazel-provided remote one. By doing wo we make sure to build with the most
 # updated JDK, including bug and security fixes, independently of the Bazel
-# version.
+# version. NOTE that WORKSPACE-docker file defines dockerjdk
 ARG JOBS
 ARG JAVA_PATH
 ARG PROFILE
-RUN bazelisk build onos \
+RUN cat WORKSPACE-docker >> WORKSPACE && bazelisk build onos \
     --jobs ${JOBS} \
     --verbose_failures \
-    --javabase=@bazel_tools//tools/jdk:absolute_javabase \
-    --host_javabase=@bazel_tools//tools/jdk:absolute_javabase \
-    --define=ABSOLUTE_JAVABASE=${JAVA_PATH} \
+    --java_runtime_version=dockerjdk_11 \
+    --tool_java_runtime_version=dockerjdk_11 \
     --define profile=${PROFILE}
 
 # We extract the tar in the build environment to avoid having to put the tar in
diff --git a/utils/osgiwrap/src/main/java/org/onlab/osgiwrap/OSGiWrapper.java b/utils/osgiwrap/src/main/java/org/onlab/osgiwrap/OSGiWrapper.java
index 2bdc2b3..aaba624 100644
--- a/utils/osgiwrap/src/main/java/org/onlab/osgiwrap/OSGiWrapper.java
+++ b/utils/osgiwrap/src/main/java/org/onlab/osgiwrap/OSGiWrapper.java
@@ -26,13 +26,12 @@
 import com.google.common.base.Joiner;
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import com.google.common.io.ByteStreams;
-import org.apache.felix.scrplugin.bnd.SCRDescriptorBndPlugin;
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.nio.file.FileVisitResult;
 import java.nio.file.FileVisitor;
@@ -48,6 +47,7 @@
 import java.util.Set;
 import java.util.jar.JarEntry;
 import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
 
 import static com.google.common.io.Files.createParentDirs;
@@ -55,9 +55,14 @@
 import static java.nio.file.Files.walkFileTree;
 
 /**
- * BND-based wrapper to convert Buck JARs to OSGi-compatible JARs.
+ * BND-based wrapper to convert Buck/Bazel JARs to OSGi-compatible JARs.
  */
 public class OSGiWrapper {
+    // Resources that need to be modified in the original jar
+    private static final String _CFGDEF_JAR = "_cfgdef.jar";
+    private static final String MODEL_SRCJAR = "model.srcjar";
+    private static final String SCHEMA_JAR = "schema.jar";
+
     private static final String NONE = "NONE";
 
     private String inputJar;
@@ -87,10 +92,11 @@
     private String karafCommands;
 
     private String fragmentHost;
+    private boolean debug;
 
     // FIXME should consider using Commons CLI, etc.
     public static void main(String[] args) {
-        if (args.length < 17) {
+        if (args.length < 18) {
             System.err.println("Not enough args");
             System.exit(1);
         }
@@ -112,7 +118,8 @@
         String bundleClasspath = args[14];
         String karafCommands = args[15];
         String fragmentHost = args[16];
-        String desc = Joiner.on(' ').join(Arrays.copyOfRange(args, 17, args.length));
+        String debug = args[17];
+        String desc = Joiner.on(' ').join(Arrays.copyOfRange(args, 18, args.length));
 
         OSGiWrapper wrapper = new OSGiWrapper(jar, output, cp,
                 name, group,
@@ -126,7 +133,8 @@
                 destdir,
                 bundleClasspath,
                 karafCommands,
-                fragmentHost);
+                fragmentHost,
+                debug);
         wrapper.log(wrapper + "\n");
         if (!wrapper.execute()) {
             System.err.printf("Error generating %s\n", name);
@@ -152,7 +160,8 @@
                        String destdir,
                        String bundleClasspath,
                        String karafCommands,
-                       String fragmentHost) {
+                       String fragmentHost,
+                       String debug) {
         this.inputJar = inputJar;
         this.classpath = Lists.newArrayList(classpath.split(":"));
         if (!this.classpath.contains(inputJar)) {
@@ -186,6 +195,7 @@
         this.karafCommands = karafCommands;
 
         this.fragmentHost = fragmentHost;
+        this.debug = Boolean.parseBoolean(debug);
     }
 
     private void setProperties(Analyzer analyzer) {
@@ -228,8 +238,8 @@
     public boolean execute() {
         Analyzer analyzer = new Builder();
         try {
-            // Extract the input jar contents into the specified output directory
-            expandJar(inputJar, new File(destdir));
+            // Sanitize the input jar content
+            inputJar = modifyJar(inputJar);
 
             Jar jar = new Jar(new File(inputJar));  // where our data is
             analyzer.setJar(jar);                   // give bnd the contents
@@ -246,15 +256,6 @@
             // Analyze the target JAR first
             analyzer.analyze();
 
-            //// Scan the JAR for Felix SCR annotations and generate XML files
-            //Map<String, String> properties = Maps.newHashMap();
-            //// destdir hack
-            //properties.put("destdir", destdir);
-            //SCRDescriptorBndPlugin scrDescriptorBndPlugin = new SCRDescriptorBndPlugin();
-            //scrDescriptorBndPlugin.setProperties(properties);
-            //scrDescriptorBndPlugin.setReporter(analyzer);
-            //scrDescriptorBndPlugin.analyzeJar(analyzer);
-
             if (includeResources != null) {
                 doIncludeResources(analyzer);
             }
@@ -287,26 +288,66 @@
         }
     }
 
-    // Expands the specified jar file into the given directory
-    private void expandJar(String inputJar, File intoDir) throws IOException {
-        try (JarInputStream jis = new JarInputStream(new FileInputStream(inputJar))) {
+    // Extract the jar and melds its content with the jar produced by Bazel
+    private void addJarToJar(JarEntry entryJar, JarInputStream jis, JarOutputStream jos) throws IOException {
+        File file = new File(new File(destdir), entryJar.getName());
+        byte[] data = ByteStreams.toByteArray(jis);
+        createParentDirs(file);
+        write(data, file);
+        // Entry jar input stream which points to the inner jar resources (cfgdef, model,...)
+        try (JarInputStream innerJis = new JarInputStream(new FileInputStream(file))) {
             JarEntry entry;
-            while ((entry = jis.getNextJarEntry()) != null) {
+            byte[] byteBuff = new byte[1024];
+            while ((entry = innerJis.getNextJarEntry()) != null) {
                 if (!entry.isDirectory()) {
-                    byte[] data = ByteStreams.toByteArray(jis);
-                    jis.closeEntry();
                     if (!entry.getName().contains("..")) {
-                        File file = new File(intoDir, entry.getName());
-                        createParentDirs(file);
-                        write(data, file);
+                        jos.putNextEntry(entry);
+                        for (int bytesRead; (bytesRead = innerJis.read(byteBuff)) != -1; ) {
+                            jos.write(byteBuff, 0, bytesRead);
+                        }
                     } else {
-                        throw new IOException("Corrupt jar file");
+                        throw new IOException("Jar " + entryJar + " is corrupted");
                     }
                 }
+                innerJis.closeEntry();
             }
         }
     }
 
+    // Modify the specified jar to fix the resource_jars loaded by Bazel.
+    // Starting from Bazel 5, resource_jars are no longer supported and
+    // we have to load them as resources. This means that we expand them
+    // and we set the right path in OSGi-compatible JAR.
+    private String modifyJar(String inputJar) throws IOException {
+        // libonos-xxx input and libonos-xxx-new which is the sanitized final jar
+        try (JarInputStream jis = new JarInputStream(new FileInputStream(inputJar));
+             JarOutputStream jos = new JarOutputStream(new FileOutputStream(inputJar + "new"))) {
+            JarEntry entry;
+            byte[] byteBuff = new byte[1024];
+            while ((entry = jis.getNextJarEntry()) != null) {
+                if (!entry.isDirectory()) {
+                    if (!entry.getName().contains("..")) {
+                        // We add the content but we don't write them again in the new jar
+                        if (entry.getName().contains(bundleName + OSGiWrapper._CFGDEF_JAR) ||
+                                entry.getName().contains(SCHEMA_JAR) ||
+                                entry.getName().contains(MODEL_SRCJAR)) {
+                            addJarToJar(entry, jis, jos);
+                        } else {
+                            jos.putNextEntry(entry);
+                            for (int bytesRead; (bytesRead = jis.read(byteBuff)) != -1; ) {
+                                jos.write(byteBuff, 0, bytesRead);
+                            }
+                        }
+                    } else {
+                        throw new IOException("Jar " + inputJar + " is corrupted");
+                    }
+                }
+                jis.closeEntry();
+            }
+        }
+        return inputJar + "new";
+    }
+
     private boolean isWab() {
         return !Objects.equals(webContext, NONE);
     }
@@ -399,10 +440,10 @@
         }
     }
 
-    private boolean addFileToJar(Jar jar, String destination, String sourceAbsPath) throws IOException {
+    private void addFileToJar(Jar jar, String destination, String sourceAbsPath) throws IOException {
         if (includedResources.contains(sourceAbsPath)) {
             log("Skipping already included resource: %s\n", sourceAbsPath);
-            return false;
+            return;
         }
         File file = new File(sourceAbsPath);
         if (!file.isFile()) {
@@ -412,16 +453,17 @@
         Resource resource = new FileResource(file);
         if (jar.getResource(destination) != null) {
             warn("Skipping duplicate resource: %s\n", destination);
-            return false;
+            return;
         }
         jar.putResource(destination, resource);
         includedResources.add(sourceAbsPath);
         log("Adding resource: %s\n", destination);
-        return true;
     }
 
     private void log(String format, Object... objects) {
-        //System.err.printf(format, objects);
+        if (debug) {
+            System.out.printf(format, objects);
+        }
     }
 
     private void warn(String format, Object... objects) {