@@ -35,6 +35,19 @@ public class FileSystemWatcherManager {
3535
3636 private static final int WatchKindAny = 7 ;
3737
38+ /**
39+ * JAR/ZIP entry separator used in paths like "/path/to/lib.jar!/com/example/Class.class"
40+ */
41+ private static final String JAR_SEPARATOR = "!/" ;
42+
43+ /**
44+ * Archive URI schemes that should be skipped to avoid ZipFileSystemProvider
45+ * triggering toRealPath() which causes EDT freezes on Windows.
46+ */
47+ private static final Set <String > ARCHIVE_SCHEMES = Set .of (
48+ "jar" , "zip" , "war" , "ear"
49+ );
50+
3851 /**
3952 * Archive file extensions that should be skipped to avoid ZipFileSystemProvider
4053 * triggering toRealPath() which causes EDT freezes on Windows.
@@ -256,11 +269,24 @@ public boolean hasFilePatternsFor(int kind) {
256269 * which calls toRealPath() -> FindFirstFile0 on Windows, causing EDT freezes.
257270 */
258271 private static boolean isArchiveFile (@ NotNull URI uri ) {
272+ // First check: URI scheme (jar:, zip:, etc.)
273+ String scheme = uri .getScheme ();
274+ if (scheme != null && ARCHIVE_SCHEMES .contains (scheme .toLowerCase ())) {
275+ return true ;
276+ }
277+
278+ // Second check: path contains JAR entry separator
259279 String path = uri .getPath ();
260280 if (path == null ) {
261281 return false ;
262282 }
263283
284+ // Paths containing JAR_SEPARATOR are JAR/ZIP entry paths (e.g., /path/to/lib.jar!/com/example/Class.class)
285+ if (path .contains (JAR_SEPARATOR )) {
286+ return true ;
287+ }
288+
289+ // Third check: file extension
264290 // Extract the extension (including the dot)
265291 int lastDot = path .lastIndexOf ('.' );
266292 if (lastDot == -1 || lastDot == path .length () - 1 ) {
0 commit comments