EJC Architecture: Integrating Electron, Java, and C/C++ for Scalable Desktop Quality Inspection Applications
This article presents the EJC (Electron‑Java‑C/C++) architecture adopted by ZhiZhuan’s quality‑inspection platform, detailing its layered design, communication modules, JNI/JNA integration, performance comparisons, and real‑world implementation for cross‑platform desktop tools, illustrating how the approach enhances extensibility, maintainability, and scalability.
Background
ZhiZhuan’s quality‑inspection system originally used Qt‑based desktop applications written in C/C++. As business grew, the monolithic C/C++ codebase became hard to extend and maintain, prompting a redesign of the desktop stack.
The team decided to leverage existing front‑end expertise and a mature Java backend, proposing a new three‑layer architecture called EJC (Electron, Java, C/C++).
EJC Architecture Overview
The EJC architecture separates concerns into three layers:
Electron – the view/user layer built with web technologies.
Java – the application layer handling business logic, communication, and data persistence.
C/C++ – the foundational layer providing low‑level device SDKs.
This separation allows C/C++ developers to focus on core capabilities, while front‑end engineers work in Electron and Java developers design the overall workflow.
Electron (View Layer)
Electron combines Chromium and Node.js to produce cross‑platform desktop apps for Windows, macOS, and Linux. Its advantages include:
Modern web standards without browser compatibility concerns.
Automatic and hot updates, similar to hybrid mobile apps.
Stable, crash‑resistant runtime.
Rich APIs that, together with native C/C++ modules, enable seamless hardware‑software integration.
Java (Application Layer)
The Java layer provides several key modules:
Communication module (HTTP, WebSocket).
Native bridge (JNI/JNA) for invoking C/C++ SDKs.
SQLite‑based persistence.
Event‑driven architecture using Spring.
Business logic, monitoring, configuration management, and scheduling strategies.
C/C++ (Foundation Layer)
This layer implements the core SDKs that interact with Windows, iOS, Android, cameras, robotic arms, and other hardware.
Front‑End Communication Module
The Java layer supports multiple communication patterns with the Electron front‑end:
HTTP Short Polling
Periodically sends requests to fetch data; suitable for low‑frequency updates such as configuration pulls.
HTTP Long Polling
Keeps a request open until new data is available, reducing network overhead compared to short polling.
Server‑Sent Events (SSE)
Uses a persistent HTTP connection to push server‑originated events to the client; lightweight and requires no extra infrastructure.
Better performance than short polling.
More reliable than long polling.
Less heavyweight than WebSocket.
WebSocket
A full‑duplex TCP‑based protocol for real‑time, bidirectional communication, used in latency‑critical scenarios such as live status updates during privacy‑cleaning operations.
Bottom‑Layer Communication (JNI / JNA)
Java calls native code via two mechanisms:
JNI (Java Native Interface)
Standard Java API that requires explicit native method declarations and header generation.
public class JniDemo {
/**
* Get iOS device name
* @param udid Device UDID
* @return Device name
*/
public native String getDeviceNameByUDID(String udid);
}Typical workflow:
Compile the Java class and generate a header with javac -h outputDir JniDemo.java (or the legacy javah ).
Implement the native method in C/C++ and compile it into a shared library.
#include
#ifndef _Included_JniDemo
#define _Included_JniDemo
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jstring JNICALL Java_JniDemo_getDeviceNameByUDID(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endifJava loads the library and invokes the method:
public class JniDemo {
public native String getDeviceNameByUDID(String udid);
public static void main(String[] args) {
System.loadLibrary("jniDemo");
JniDemo obj = new JniDemo();
String result = obj.getDeviceNameByUDID("00008110-001518392EE3801E");
System.out.println("Result is " + result);
}
}JNA (Java Native Access)
JNA simplifies native calls by automatically mapping Java types to C types, eliminating the need to write JNI glue code.
#pragma once
#include "pch.h"
#ifndef JNADemoAPI
#define JNADemoAPI __declspec(dllexport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
JNADemoAPI const char* getDeviceNameByUDID(const char* udid);
#ifdef __cplusplus
}
#endifJava interface definition:
public interface JnaDemo extends Library {
/**
* Get device name from native library
* @param udid Device UDID
* @return Device name
*/
String getDeviceNameByUDID(String udid);
}Loading and invoking:
public class JnaDemoTest {
public static void main(String[] args) {
JnaDemo jnaDemo = Native.load("JnaDemo", JnaDemo.class);
String result = jnaDemo.getDeviceNameByUDID("00008110-001518392EE3801E");
System.out.println("Result is " + result);
}
}A performance comparison on an 8‑core, 16 GB machine showed JNI to be significantly faster than JNA for repeated calls.
JNI
JNA
Advantages
Higher efficiency; C/C++ flexibility.
Higher developer productivity; no native code needed.
Disadvantages
More boilerplate; requires header generation.
Cannot directly use C++‑only libraries; needs C wrapper.
Real‑World Deployment
The EJC architecture has been deployed in multiple ZhiZhuan quality‑inspection desktop tools, most notably the Windows notebook inspection application.
Project Background
Increasing inspection volume exposed limitations of the legacy Qt solution: high maintenance cost, low feature coverage, and poor cross‑platform support.
Implementation
The new system follows the EJC stack, using Electron for UI, Java for business logic, and C/C++ SDKs for hardware interaction (WMI, WinAPI, DLLs).
Workflow
Electron launches and starts the Java backend asynchronously.
Java schedules data collection tasks, invokes native modules via JNI/JNA, aggregates results, and pushes them to the UI through SSE.
Additional assistance modules (e.g., fingerprint checks) follow a similar request‑response pattern.
Benefits
Improved extensibility, easier maintenance, cross‑platform capability (Windows & macOS), and more reliable real‑time updates.
Conclusion
The article shares the design and practical experience of the EJC architecture within ZhiZhuan’s quality‑inspection platform, demonstrating how combining Electron, Java, and C/C++ can solve scalability and maintainability challenges in desktop applications.
Zhuanzhuan Tech
A platform for Zhuanzhuan R&D and industry peers to learn and exchange technology, regularly sharing frontline experience and cutting‑edge topics. We welcome practical discussions and sharing; contact waterystone with any questions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.