JarFileSystem.getInstance().getJarRootForLocalFile() returns null in test

已回答

I have a test for my plugin, based on LightJavaCodeInsightFixtureTestCase.

I set it up using 

PsiFile[] psiFiles = myFixture.configureByFiles("module/src/main/java/TestObject.java", "pom.xml");
myFixture.copyFileToProject("ext/libs/1.1.1/jars/content-file-1.1.1.jar");

And later on I search for the Jar file (It's in the library list for the real project, but in the test - it looks like it is not in the library list) like that:

VirtualFile extFolder = FilenameIndex.getVirtualFilesByName(project, "ext", GlobalSearchScope.projectScope(project)).stream().findAny().orElse(null);
VirtualFile fileJarContent = extFolder.findFileByRelativePath("libs/1.1.1/jars/content-file-1.1.1.jar");
VirtualFile jarRootForLocalFile = JarFileSystem.getInstance().getJarRootForLocalFile(fileJarContent);

When plugin runs in the real IDE - jarRootForLocalFile is resolved and I can later use the function:

jarRootForLocalFile.findFileByRelativePath("data/content.xml");

However in the plugin test - it is not resolved and returns null.

How to let JarFileSystem aware of this file and enforce it to resolve the file as JAR file, parsing it's content?

0

In light tests, TempFileSystem is used. Something along these lines should make it work:

VF vf =  ApplicationManager.getApplication().isUnitTestMode() ?
TempFileSystem.getInstance().findFileByPath(path) : [regular way]

0

I can find the VirtualFile. It's method .exists() returns true.

But I need to get access to this file as Jar file, with all the content.

The problem is that

VirtualFile jarRootForLocalFile = JarFileSystem.getInstance().getJarRootForLocalFile(fileJarContent);

returns jarRootForLocalFile==null for the existing virtual file

0

Please try VfsUtilCore.findRelativeFile("path/file.xml", jarRoot) instead of findFileByRelativePath()

0

Tried. Still null.

Here is an example project I created : https://github.com/Gorbush/intellij-plugin-jar-read-in-test

What I have noticed is that the problem arise when we trying to resolve the JAR file in the Temp filesystem.

This will work - as it uses full real filesystem path:

//// Get content from Jar using VirtualFile
File realJarFile = new File("test-root/lib/commons-lang3-3.10.jar");
VirtualFile jarRootForLocalFile = VfsImplUtil.findFileByPath(JarFileSystem.getInstance(), realJarFile.getAbsolutePath()+"!/");

But if I try to resolve JAR using the relative VF received from TempFileSystem - it returns null.

vfJarFile = TempFileSystem.getInstance().findFileByPath("///src").findFileByRelativePath(JAR_PATH);
JarFileSystem.getInstance().getJarRootForLocalFile(vfJarFile);

Or attempt to resolve the content using the TempFileSystem itself:

VfsImplUtil.findFileByPath(TempFileSystem.getInstance(), realJarFile.getAbsolutePath()+"!/");

 

 

 

 

0

I think that issue is here.

We retrieve the path of the file using temp file system. But then - trying to resolve it using JarFileSystem. This will not work - as JarFileSystem is not aware of the TempFileSystem root and virtual files created for the project simulation of the Test.

0

BTW 

VfsUtilCore.findRelativeFile

knows on how to work with prefixes file:/// , jar:file:/  and knows about .jar!  marker, however it's not aware of the temp:// filesystem.

0

Unfortunately it will not work in TempFS. Please try changing your test to "heavy" test to use real filesystem.

0

请先登录再写评论。