Load JNI from a static context instead of in every entry point.

This is what all other classes that depend on JNI do, and it's a less fragile
mechanism to ensure that JNI is present.  As a side-effect, we can remove
some Java->native indirections that existed throughout the code by directly
declaring the public entry points as native.

PiperOrigin-RevId: 335062603
diff --git a/src/main/java/com/google/devtools/build/lib/windows/jni/WindowsFileOperations.java b/src/main/java/com/google/devtools/build/lib/windows/jni/WindowsFileOperations.java
index 163d20b..d652657 100644
--- a/src/main/java/com/google/devtools/build/lib/windows/jni/WindowsFileOperations.java
+++ b/src/main/java/com/google/devtools/build/lib/windows/jni/WindowsFileOperations.java
@@ -39,6 +39,10 @@
   // - http://stackoverflow.com/questions/23041983
   // - http://stackoverflow.com/questions/14482421
 
+  static {
+    JniLoader.loadJni();
+  }
+
   private WindowsFileOperations() {
     // Prevent construction
   }
@@ -123,7 +127,6 @@
 
   /** Determines whether `path` is a junction point or directory symlink. */
   public static boolean isSymlinkOrJunction(String path) throws IOException {
-    JniLoader.loadJni();
     boolean[] result = new boolean[] {false};
     String[] error = new String[] {null};
     switch (nativeIsSymlinkOrJunction(asLongPath(path), result, error)) {
@@ -153,7 +156,6 @@
    * @throws IOException if the `path` is not found or some other I/O error occurs
    */
   public static String getLongPath(String path) throws IOException {
-    JniLoader.loadJni();
     String[] result = new String[] {null};
     String[] error = new String[] {null};
     if (nativeGetLongPath(asLongPath(path), result, error)) {
@@ -191,7 +193,6 @@
    * @throws IOException if some error occurs
    */
   public static void createJunction(String name, String target) throws IOException {
-    JniLoader.loadJni();
     String[] error = new String[] {null};
     switch (nativeCreateJunction(asLongPath(name), asLongPath(target), error)) {
       case CREATE_JUNCTION_SUCCESS:
@@ -220,7 +221,6 @@
   }
 
   public static void createSymlink(String name, String target) throws IOException {
-    JniLoader.loadJni();
     String[] error = new String[] {null};
     switch (nativeCreateSymlink(asLongPath(name), asLongPath(target), error)) {
       case CREATE_SYMLINK_SUCCESS:
@@ -237,7 +237,6 @@
   }
 
   public static ReadSymlinkOrJunctionResult readSymlinkOrJunction(String name) {
-    JniLoader.loadJni();
     String[] target = new String[] {null};
     String[] error = new String[] {null};
     switch (nativeReadSymlinkOrJunction(asLongPath(name), target, error)) {
@@ -267,7 +266,6 @@
   }
 
   public static boolean deletePath(String path) throws IOException {
-    JniLoader.loadJni();
     String[] error = new String[] {null};
     int result = nativeDeletePath(asLongPath(path), error);
     switch (result) {
diff --git a/src/main/java/com/google/devtools/build/lib/windows/jni/WindowsProcesses.java b/src/main/java/com/google/devtools/build/lib/windows/jni/WindowsProcesses.java
index 90bb2d8..1acce15 100644
--- a/src/main/java/com/google/devtools/build/lib/windows/jni/WindowsProcesses.java
+++ b/src/main/java/com/google/devtools/build/lib/windows/jni/WindowsProcesses.java
@@ -20,6 +20,10 @@
 public class WindowsProcesses {
   public static final long INVALID = -1;
 
+  static {
+    JniLoader.loadJni();
+  }
+
   private WindowsProcesses() {
     // Prevent construction
   }
@@ -34,35 +38,16 @@
    *     "foo app.exe")
    * @param argvRest the rest of the command line, i.e. argv[1:] (needs to be quoted Windows style)
    * @param env the environment of the new process. null means inherit that of the Bazel server
-   * @param cwd the working directory of the new process. if null, the same as that of the current
-   *     process
-   * @param stdoutFile the file the stdout should be redirected to. if null, nativeReadStdout will
+   * @param cwd the working directory of the new process. If null, the same as that of the current
+   *     process.
+   * @param stdoutFile the file the stdout should be redirected to. If null, {@link #getStdout} will
    *     work.
-   * @param stderrFile the file the stdout should be redirected to. if null, nativeReadStderr will
+   * @param stderrFile the file the stdout should be redirected to. If null, {@link #getStderr} will
    *     work.
    * @param redirectErrorStream whether we merge the process's standard error and standard output.
    * @return the opaque identifier of the created process
    */
-  public static long createProcess(
-      String argv0,
-      String argvRest,
-      byte[] env,
-      String cwd,
-      String stdoutFile,
-      String stderrFile,
-      boolean redirectErrorStream) {
-    JniLoader.loadJni();
-    return nativeCreateProcess(
-        argv0, argvRest, env, cwd, stdoutFile, stderrFile, redirectErrorStream);
-  }
-
-  public static long createProcess(
-      String argv0, String argvRest, byte[] env, String cwd, String stdoutFile, String stderrFile) {
-    JniLoader.loadJni();
-    return nativeCreateProcess(argv0, argvRest, env, cwd, stdoutFile, stderrFile, false);
-  }
-
-  private static native long nativeCreateProcess(
+  public static native long createProcess(
       String argv0,
       String argvRest,
       byte[] env,
@@ -71,6 +56,11 @@
       String stderrFile,
       boolean redirectErrorStream);
 
+  public static long createProcess(
+      String argv0, String argvRest, byte[] env, String cwd, String stdoutFile, String stderrFile) {
+    return createProcess(argv0, argvRest, env, cwd, stdoutFile, stderrFile, false);
+  }
+
   /**
    * Writes data from the given array to the stdin of the specified process.
    *
@@ -78,43 +68,23 @@
    *
    * @return the number of bytes written
    */
-  public static int writeStdin(long process, byte[] bytes, int offset, int length) {
-    JniLoader.loadJni();
-    return nativeWriteStdin(process, bytes, offset, length);
-  }
-
-  private static native int nativeWriteStdin(long process, byte[] bytes, int offset, int length);
+  public static native int writeStdin(long process, byte[] bytes, int offset, int length);
 
   /** Returns an opaque identifier of stdout stream for the process. */
-  public static long getStdout(long process) {
-    JniLoader.loadJni();
-    return nativeGetStdout(process);
-  }
-
-  private static native long nativeGetStdout(long process);
+  public static native long getStdout(long process);
 
   /** Returns an opaque identifier of stderr stream for the process. */
-  public static long getStderr(long process) {
-    JniLoader.loadJni();
-    return nativeGetStderr(process);
-  }
-
-  private static native long nativeGetStderr(long process);
+  public static native long getStderr(long process);
 
   /**
    * Reads data from the stream into the given array. {@code stream} should come from {@link
-   * #nativeGetStdout(long)} or {@link #nativeGetStderr(long)}.
+   * #getStdout(long)} or {@link #getStderr(long)}.
    *
    * <p>Blocks until either some data was read or the process is terminated.
    *
    * @return the number of bytes read, 0 on EOF, or -1 if there was an error.
    */
-  public static int readStream(long stream, byte[] bytes, int offset, int length) {
-    JniLoader.loadJni();
-    return nativeReadStream(stream, bytes, offset, length);
-  }
-
-  private static native int nativeReadStream(long stream, byte[] bytes, int offset, int length);
+  public static native int readStream(long stream, byte[] bytes, int offset, int length);
 
   /**
    * Waits until the given process terminates. If timeout is non-negative, it indicates the number
@@ -125,39 +95,19 @@
    * <li>1: Timeout
    * <li>2: Something went wrong
    */
-  public static int waitFor(long process, long timeout) {
-    JniLoader.loadJni();
-    return nativeWaitFor(process, timeout);
-  }
-
-  private static native int nativeWaitFor(long process, long timeout);
+  public static native int waitFor(long process, long timeout);
 
   /**
    * Returns the exit code of the process. Throws {@code IllegalStateException} if something goes
    * wrong.
    */
-  public static int getExitCode(long process) {
-    JniLoader.loadJni();
-    return nativeGetExitCode(process);
-  }
-
-  private static native int nativeGetExitCode(long process);
+  public static native int getExitCode(long process);
 
   /** Returns the process ID of the given process or -1 if there was an error. */
-  public static int getProcessPid(long process) {
-    JniLoader.loadJni();
-    return nativeGetProcessPid(process);
-  }
-
-  private static native int nativeGetProcessPid(long process);
+  public static native int getProcessPid(long process);
 
   /** Terminates the given process. Returns true if the termination was successful. */
-  public static boolean terminate(long process) {
-    JniLoader.loadJni();
-    return nativeTerminate(process);
-  }
-
-  private static native boolean nativeTerminate(long process);
+  public static native boolean terminate(long process);
 
   /**
    * Releases the native data structures associated with the process.
@@ -165,25 +115,14 @@
    * <p>Calling any other method on the same process after this call will result in the JVM crashing
    * or worse.
    */
-  public static void deleteProcess(long process) {
-    JniLoader.loadJni();
-    nativeDeleteProcess(process);
-  }
-
-  private static native void nativeDeleteProcess(long process);
+  public static native void deleteProcess(long process);
 
   /**
    * Closes the stream
    *
-   * @param stream should come from {@link #nativeGetStdout(long)} or {@link
-   *     #nativeGetStderr(long)}.
+   * @param stream should come from {@link #getStdout(long)} or {@link #getStderr(long)}.
    */
-  public static void closeStream(long stream) {
-    JniLoader.loadJni();
-    nativeCloseStream(stream);
-  }
-
-  private static native void nativeCloseStream(long stream);
+  public static native void closeStream(long stream);
 
   /**
    * Returns a string representation of the last error caused by any call on the given process or
@@ -194,25 +133,10 @@
    * <p>After this call returns, subsequent calls will return the empty string if there was no
    * failed operation in between.
    */
-  public static String processGetLastError(long process) {
-    JniLoader.loadJni();
-    return nativeProcessGetLastError(process);
-  }
+  public static native String processGetLastError(long process);
 
-  private static native String nativeProcessGetLastError(long process);
+  public static native String streamGetLastError(long process);
 
-  public static String streamGetLastError(long process) {
-    JniLoader.loadJni();
-    return nativeStreamGetLastError(process);
-  }
-
-  private static native String nativeStreamGetLastError(long process);
-
-  /** returns the PID of the current process. */
-  public static int getpid() {
-    JniLoader.loadJni();
-    return nativeGetpid();
-  }
-
-  private static native int nativeGetpid();
+  /** Returns the PID of the current process. */
+  public static native int getpid();
 }
diff --git a/src/main/native/windows/processes-jni.cc b/src/main/native/windows/processes-jni.cc
index fbda6c5..00d068d 100644
--- a/src/main/native/windows/processes-jni.cc
+++ b/src/main/native/windows/processes-jni.cc
@@ -41,7 +41,7 @@
 }
 
 extern "C" JNIEXPORT jint JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeGetpid(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_getpid(
     JNIEnv* env, jclass clazz) {
   return GetCurrentProcessId();
 }
@@ -396,7 +396,7 @@
 static jlong PtrAsJlong(void* p) { return reinterpret_cast<jlong>(p); }
 
 extern "C" JNIEXPORT jlong JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeCreateProcess(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_createProcess(
     JNIEnv* env, jclass clazz, jstring java_argv0, jstring java_argv_rest,
     jbyteArray java_env, jstring java_cwd, jstring java_stdout_redirect,
     jstring java_stderr_redirect, jboolean redirectErrorStream) {
@@ -413,7 +413,7 @@
 }
 
 extern "C" JNIEXPORT jint JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeWriteStdin(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_writeStdin(
     JNIEnv* env, jclass clazz, jlong process_long, jbyteArray java_bytes,
     jint offset, jint length) {
   NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
@@ -421,21 +421,21 @@
 }
 
 extern "C" JNIEXPORT jlong JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeGetStdout(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_getStdout(
     JNIEnv* env, jclass clazz, jlong process_long) {
   NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
   return PtrAsJlong(process->GetStdoutStream());
 }
 
 extern "C" JNIEXPORT jlong JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeGetStderr(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_getStderr(
     JNIEnv* env, jclass clazz, jlong process_long) {
   NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
   return PtrAsJlong(process->GetStderrStream());
 }
 
 extern "C" JNIEXPORT jint JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeReadStream(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_readStream(
     JNIEnv* env, jclass clazz, jlong stream_long, jbyteArray java_bytes,
     jint offset, jint length) {
   NativeOutputStream* stream =
@@ -444,7 +444,7 @@
 }
 
 extern "C" JNIEXPORT jint JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeGetExitCode(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_getExitCode(
     JNIEnv* env, jclass clazz, jlong process_long) {
   NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
   return static_cast<jint>(process->GetExitCode());
@@ -455,7 +455,7 @@
 // 1: Timeout
 // 2: Wait returned with an error
 extern "C" JNIEXPORT jint JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeWaitFor(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_waitFor(
     JNIEnv* env, jclass clazz, jlong process_long, jlong java_timeout) {
   NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
   int res = process->WaitFor(static_cast<int64_t>(java_timeout));
@@ -464,27 +464,27 @@
 }
 
 extern "C" JNIEXPORT jint JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeGetProcessPid(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_getProcessPid(
     JNIEnv* env, jclass clazz, jlong process_long) {
   NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
   return static_cast<jint>(process->GetPid());
 }
 
 extern "C" JNIEXPORT jboolean JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeTerminate(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_terminate(
     JNIEnv* env, jclass clazz, jlong process_long) {
   NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
   return process->Terminate() ? JNI_TRUE : JNI_FALSE;
 }
 
 extern "C" JNIEXPORT void JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeDeleteProcess(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_deleteProcess(
     JNIEnv* env, jclass clazz, jlong process_long) {
   delete reinterpret_cast<NativeProcess*>(process_long);
 }
 
 extern "C" JNIEXPORT void JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeCloseStream(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_closeStream(
     JNIEnv* env, jclass clazz, jlong stream_long) {
   NativeOutputStream* stream =
       reinterpret_cast<NativeOutputStream*>(stream_long);
@@ -492,14 +492,14 @@
 }
 
 extern "C" JNIEXPORT jstring JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeProcessGetLastError(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_processGetLastError(
     JNIEnv* env, jclass clazz, jlong process_long) {
   NativeProcess* process = reinterpret_cast<NativeProcess*>(process_long);
   return process->GetLastErrorAsString(env);
 }
 
 extern "C" JNIEXPORT jstring JNICALL
-Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_nativeStreamGetLastError(
+Java_com_google_devtools_build_lib_windows_jni_WindowsProcesses_streamGetLastError(
     JNIEnv* env, jclass clazz, jlong stream_long) {
   NativeOutputStream* stream =
       reinterpret_cast<NativeOutputStream*>(stream_long);