Java 9加载JavaFX FXML视图时触发Zip END header not found异常求助
Hey there, let's break down the ZipException: zip END header not found error you're hitting when launching your JavaFX app via Java 9.0.4 WebStart—especially since it works flawlessly on Java 8. The error points to a corrupted or prematurely cleaned-up cached JAR file, and the suppressed NoSuchFileException confirms the temp cache file is unreadable or missing. Here's how to fix this:
Possible Root Causes
- Java 9's WebStart cache handling differs from Java 8, leading to unexpected cleanup or corruption of temporary JAR files.
- Cross-version compilation (JDK 8 build, JRE 9 runtime) introduces resource loading conflicts, especially with Java 9's module system altering how
getResource()behaves. - FXML resource paths aren't being resolved correctly in Java 9's modular environment.
Step-by-Step Fixes
1. Clear WebStart Cache Completely
First, eliminate corrupted cache files as the culprit:
- Run this command in Command Prompt to uninstall all cached WebStart apps:
javaws -uninstall - Manually delete temp and cache directories:
- Delete all
jar_cache*.tmpfiles inC:\Users\user\AppData\Local\Temp - Clear the WebStart cache folder:
C:\Users\user\AppData\LocalLow\Sun\Java\Deployment\cache
- Delete all
2. Adjust FXML Resource Loading for Java 9 Modules
Java 9's module system changes how resources are loaded. Modify your FXMLViewLoader to use the context classloader instead of relying solely on getClass().getResource():
public final class FXMLViewLoader { private FXMLLoader loader; public FXMLViewLoader(String fxmlName) { super(); initialize(fxmlName); } private void initialize(String fxmlName) { final URL resource = getResourceURL(fxmlName); this.loader = new FXMLLoader(resource); try { this.loader.load(); } catch(Exception e) { e.printStackTrace(); } } protected URL getResourceURL(String fxmlName) { // Use context classloader for modular compatibility ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); URL resource = classLoader.getResource(fxmlName); // Fallback to class-specific resource lookup for Java 8 compatibility if (resource == null) { resource = this.getClass().getResource(fxmlName); } // Debug: Verify the resource URL is valid System.out.println("Loaded FXML resource: " + resource); return resource; } public Parent getView() { return this.loader.getRoot(); } }
- Double-check that your FXML files are correctly packaged in the JAR (confirm the path
/fxmlView/warningPopup.fxmlmatches your JAR's internal folder structure).
3. Update JNLP Configuration for Java 9
Add JVM arguments to your JNLP file to address caching and module loading:
<j2se version="9.0.4+" java-vm-args="--add-modules javafx.controls,javafx.fxml -Dsun.net.cache.disable=true"/>
--add-modulesensures JavaFX modules are explicitly loaded (required in Java 9's modular system)-Dsun.net.cache.disable=truedisables WebStart's JAR caching to avoid corrupted temp files
4. Recompile with JDK 9 (If Feasible)
While your app works on Java 8, compiling with JDK 9 can generate bytecode more compatible with JRE 9's runtime. Try rebuilding your app using JDK 9 and test again with WebStart.
Debugging Tips
- Enable verbose WebStart logging to see detailed JAR loading errors:
javaws -verbose your-application.jnlp - Check the printed resource URL from the modified
getResourceURLmethod to confirm the FXML file is being found correctly.
内容的提问来源于stack exchange,提问作者GANESH INGNAM

