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);