Why can't I open a JBoss vfs:/ URL?

房东的猫 提交于 2019-12-04 00:47:57

The issue JBVFS-147 Cannot read from vfs: protocol URL is still unresolved, maybe you want to vote and watch this issue.

skiphoppy

Previous answer still yields a stream that can't be read from.

I found that I can get a physical File that the VirtualFile refers to, but the returned result refers to a directory named contents/ , within a directory that contains the actual file I'm looking for. So:

 import org.jboss.vfs.*;

  String filename = ...;
  URLConnection conn = new URL("vfs:/...").openConnection();
  VirtualFile vf = (VirtualFile)conn.getContent();
  File contentsFile = vf.getPhysicalFile();
  File dir = contentsFile.getParentFile();
  File physicalFile = new File(dir, filename);
  InputStream is = new FileInputStream(physicalFile);

What a mess. I still don't understand my original question, which is why would JBoss hand me a URL that can't be read from? But at least I can move on, for now.

I've discovered that the getContent() method will give me a VirtualFile, which perhaps I can use. Still doesn't explain why I can't just do an openStream() on a vfs:/ URL.

import org.jboss.vfs.*;

URLConnection conn = new URL("vfs:/...").openConnection();
VirtualFile vf = (VirtualFile)conn.getContent();
InputStream is = vf.openStream();

I have investigated the behaviour in WildFly11.

In particular, only calling

getPhysicalFile();

has the side effect of actually creating physical files, and only those it seems you can read. In order to create all the files in a virtual directory I did:

      // Reflection as we cannot afford a dependency to WildFly11
      Object virtualFile = url.openConnection().getContent();
      Class virtualFileClass = virtualFile.getClass();         

      Method getChildrenRecursivelyMethod = virtualFileClass.getMethod("getChildrenRecursively");
      Method getPhysicalFileMethod = virtualFileClass.getMethod("getPhysicalFile");

      List virtualFiles = (List) getChildrenRecursivelyMethod.invoke(virtualFile);
      for (Object child : virtualFiles){
        File physical = (File) getPhysicalFileMethod.invoke(child); // side effect: create real-world files
      }
      File rootDir = (File) getPhysicalFileMethod.invoke(virtualFile);

Now I can list the root directory and access its files, in the physical world.

That getContent() approach for virtual files does not work either. I tested it, using reflection to avoid a dependency to JBoss/Wildfly which you probably don't want in a Servlet.

// Reflection as we cannot afford a dependency to WildFly11
Object virtualFile = url.openConnection().getContent();
Class virtualFileClass = virtualFile.getClass();
DevModeInitializer.log(virtualFileClass.getCanonicalName());
Method openStreamMethod = virtualFileClass.getMethod("openStream");
InputStream inputStream = (InputStream) openStreamMethod.invoke(virtualFile);

Reading from that Stream also yields only "-1", that is, it is empty.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!