如何用Java将外部exe嵌入Jar,实现安全执行获取输出后自动销毁?
Absolutely, this is a solvable problem—here’s a practical, secure approach that meets all your constraints:
Core Strategy
The key is to embed the EXE as a resource in your JAR/EXE, dynamically extract it to a secure, user-restricted temporary location at runtime, execute it, capture output, and ensure it’s deleted when your tool exits.
Step-by-Step Implementation
1. Embed the EXE as a Java Resource
- Place your target EXE file in your project’s
src/main/resourcesdirectory (if using Maven/Gradle). When you build your JAR, this file will be packaged inside it, inaccessible to end users unless they explicitly unpack the JAR (which we’ll mitigate with security measures later). - To access the embedded resource at runtime, use
ClassLoader.getResourceAsStream()—this lets you read the EXE as an input stream without writing it to disk prematurely.
2. Deploy to a Secure Temporary Location
You can’t just dump the EXE in the system’s default temp folder (it’s too visible). Instead:
- Create a private temporary directory using
Files.createTempDirectory()with a random prefix (e.g.,mytool_secure_temp_). - Restrict permissions on this directory so only the current user can read/write/execute files inside it. On Windows, this means setting ACLs to block other users; on Unix-like systems, use
chmod 700via code. - Generate a random filename for the EXE (e.g., using
UUID.randomUUID().toString() + ".exe") to avoid easy detection.
3. Execute the EXE & Capture Output
Use ProcessBuilder to launch the EXE and capture its output safely:
- Enable
redirectErrorStream(true)to merge stdout and stderr, making it easier to read all output in one place. - Use
BufferedReaderto read the process’s input stream, and wait for the process to finish withprocess.waitFor()to avoid zombie processes.
4. Ensure Cleanup on Exit
To guarantee the EXE is deleted even if the user closes your tool normally:
- Add a shutdown hook with
Runtime.getRuntime().addShutdownHook(). This thread will run when the JVM exits, letting you delete the EXE file and its parent temporary directory. - Note: Shutdown hooks won’t run if the process is force-killed (e.g., via Task Manager on Windows), but system temp folders are typically cleaned up automatically after a period of inactivity.
Example Code Snippet
Here’s a condensed version of the logic to illustrate:
import java.io.*; import java.nio.file.*; import java.util.UUID; import java.util.stream.Collectors; public class ExeRunner { public static void main(String[] args) throws Exception { // 1. Read embedded EXE resource InputStream exeStream = ExeRunner.class.getClassLoader().getResourceAsStream("my_hidden.exe"); if (exeStream == null) { throw new RuntimeException("Embedded EXE not found in resources"); } // 2. Create secure temp directory Path tempDir = Files.createTempDirectory("mytool_secure_"); // Restrict permissions (adjust for your OS) tempDir.toFile().setReadable(false, false); tempDir.toFile().setWritable(false, false); tempDir.toFile().setExecutable(false, false); // Generate random EXE filename String randomExeName = UUID.randomUUID().toString() + ".exe"; Path exePath = tempDir.resolve(randomExeName); // Write EXE to temp location Files.copy(exeStream, exePath, StandardCopyOption.REPLACE_EXISTING); exePath.toFile().setExecutable(true); // Grant execute permission // 3. Execute EXE and capture output ProcessBuilder pb = new ProcessBuilder(exePath.toString()); pb.redirectErrorStream(true); Process process = pb.start(); String output = new BufferedReader(new InputStreamReader(process.getInputStream())) .lines().collect(Collectors.joining("\n")); int exitCode = process.waitFor(); System.out.println("EXE Output:\n" + output); System.out.println("Exit Code: " + exitCode); // 4. Add shutdown hook for cleanup Runtime.getRuntime().addShutdownHook(new Thread(() -> { try { // Delete EXE first, then temp directory Files.deleteIfExists(exePath); Files.deleteIfExists(tempDir); } catch (IOException e) { // Log error instead of crashing exit e.printStackTrace(); } })); } }
Packaging as an EXE (If Needed)
If you want to distribute your tool as a native EXE instead of a JAR:
- Use tools like JPackage (built into Java 16+) or Launch4j. These tools will package your JAR and its embedded resources into a single native EXE.
- JPackage lets you set permissions on the generated EXE and ensures the embedded resources are only accessible via your tool’s runtime logic, not directly by end users.
Critical Security Notes
- Lock down permissions: Always restrict access to the temporary directory and EXE file—this prevents other users on the same system from accessing the EXE.
- Avoid hardcoded paths: Never use fixed paths for temporary files; always generate random names and directories.
- Clean up promptly: Delete the EXE as soon as it finishes executing if possible (not just on shutdown), but wait until the process has exited completely to avoid file locks.
内容的提问来源于stack exchange,提问作者Priya

