shanghaishanghai

WebAssembly: A Safer Path for Integrating Native Code in Java

In the realm of software development, the need to execute native code within a managed runtime environment like the Java Virtual Machine (JVM) is often unavoidable. This is particularly true when tasks such as encryption, compression, database operations, or network communication require the efficiency of languages like C. A prime example is SQLite, the most widely used database development library in JVM applications, as stated by its developers. However, as SQLite is written in C, the question arises: how does it function within a JVM application? The conventional solution, dynamic linking, has been a staple for decades across programming languages, but it comes with its own set of challenges when applied to the JVM.

In this article, we will delve into the potential pitfalls of integrating native extensions in the JVM and the challenges faced when migrating code libraries to different programming languages. Furthermore, we will explore how WebAssembly (Wasm) can be embedded into applications, offering a way to regain the security and portability of the JVM without the need for a complete rewrite of native extensions.

The Issues with Dynamic Linking

Dynamic linking works by loading the required native library (in this case, using a simplified Java Native Access (JNA) example):

java
interface LibSqlite extends Library {
// Load libsqlite3.dylib on a Mac
LibSqlite INSTANCE = Native.load(sqlite3, LibSqlite.class);
int sqlite3_open(String filename, PointerByReference db);
// ... Other function definitions
}

Effectively, this reads SQLite’s native code from the disk and attaches it to the JVM’s native code. A handle to a native function is obtained, and it is executed:

java
int result = LibSqlite.INSTANCE.sqlite3_open(chinook.sqlite, ptr);

The JNA automatically maps Java types to C types and vice versa. When the sqlite3_open function is called, the CPU jumps to the native code, stepping outside the JVM’s safety and performance guarantees.

Runtime: Escaping the JVM’s Umbrella

This leap outside the JVM’s boundaries exposes applications to potential security and performance issues. The JVM can no longer handle memory faults, segmentation faults, or observability problems. Native code has access to the entire memory space and enjoys the same privileges and capabilities as the JVM process. This opens the door to severe issues when vulnerabilities or malicious code are present. As memory safety gains prominence in software development, governments are encouraging the adoption of memory-safe languages. While advocating for new projects to use such languages is reasonable, expecting extensive migration of existing C and C++ code libraries is unrealistic and potentially burdensome.

Deployment: Multiple Target Platforms

Another challenge with dynamic linking is the loss of the JVM’s cross-platform code delivery advantage. Libraries or applications can no longer be simply distributed as JAR files. Native code must be compiled for each target platform, or users must manage, secure, and link the code themselves, introducing complexity and potential risks due to misconfigurations or suspicious sources.

Alternatives: Porting to the JVM

To address these issues, one solution is to port or compile native code to the JVM, retaining runtime safety and performance while simplifying code distribution. However, this requires significant rewrites and ongoing maintenance, which can be resource-intensive and may lead to落后 native implementations. The SQLJet project, for instance, is a JVM-based port of SQLite that seems to have been discontinued.

The Third Way: WebAssembly

A third option presents itself, offering the best of both worlds: the convenience without compromise. SQLite, for example, provides a WebAssembly build, enabling its execution within an application using a Wasm runtime. Similar to JVM bytecode, Wasm is a bytecode format that can run virtually anywhere, including in browsers. It is also becoming a popular compilation target for many programming languages.

With Wasm, developers can leverage existing native code while benefiting from the JVM’s security and platform independence. This approach avoids the need for extensive rewrites and ensures that applications remain up-to-date with native implementations.

In conclusion, WebAssembly emerges as a promising solution for safely integrating native code within the JVM environment. By harnessing the power of Wasm, developers can maintain the performance advantages of native code while preserving the benefits of the JVM. As the technology continues to evolve and gain wider adoption, it may become the go-to solution for addressing the challenges of native code integration in Java applications.

【source】https://mp.weixin.qq.com/s/11QXs-m0hUGHGXHkrairZw

Views: 1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注