Resolve VirtualFile for entry of archive file reported by custom fileTypeDetector?


I have a custom fileTypeDetector that determines the file type of files matching an otherwise unregistered file extension dynamically.  Some of these files are reported as the archive file type because they are in fact zip files.  Overall this works very well, and IntelliJ adapts itself accordingly.  Now I'm trying to use VirtualFileManager.findFileByUrl() to get the VirtualFile of an entry in one of these files based on a jar URL.  This is returning null because of ArchiveFileSystem.isCorrectFileType() which is resolving the file type based purely on extension instead of using my fileTypeDetector.

Is there any way to work around this and get a proper VirtualFile for the entry just as if it were in a .zip or .jar file?  Basically I'm trying to allow reference navigation to these archive entries.  This works great when the reference target is an entry of an archive file with an extension concretely associated with an archive file type, but it doesn't work when the file type association is dynamic.

Thanks in advance for any leads!


Hi Scott,

that was an optimization (the method is called most often on loading project libraries, and when there are many of them the method becomes pretty hot). I can make it work, but would like to ask first - have you considered registering your own filesystem? You can use an own protocol then instead of jar.


Thanks for the reply, Roman.  Yes, I did look at creating a custom file system.  Because the file type is determined on-the-fly by my file type detector, it would really need to be a pass-through file system that delegates to the correct real file system based on the determined file type.  My thought was that that would not work very well, but I can definitely dig into that option before asking you to make any changes, especially if those changes are a material optimization for "normal" behavior.  I still think it's a bit weird that the file type detector notion isn't respected consistently, but I also understand that I'm most likely in the extreme minority on my use case!

Let me take another look at a custom file system and I'll let you know if I hit any issues that would keep me from going down that path.

Best regard,



In fact, the fix I'm thinking about will not affect the optimization in the common case:

protected boolean isCorrectFileType(@NotNull VirtualFile local) {
  FileTypeRegistry registry = FileTypeRegistry.getInstance();
  return registry.getFileTypeByFileName(local.getName()) == FileTypes.ARCHIVE ||
registry.getFileTypeByFile(local) == FileTypes.ARCHIVE;

Only non-traditionally named archives would make it to the (slower) full check.


Please sign in to leave a comment.