java 为什么我无法打开 JBoss vfs:/ URL?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4899371/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't I open a JBoss vfs:/ URL?
提问by skiphoppy
We are upgrading our application from JBoss 4 to JBoss 6.
我们正在将我们的应用程序从 JBoss 4 升级到 JBoss 6。
A couple of pieces of our application get delivered to the client in an unusual way: jars are looked up inside of our application and sent to the client from a servlet, where the client extracts them in order to run certain support functions.
我们的应用程序的几个部分以一种不寻常的方式交付给客户端:在我们的应用程序内部查找 jars 并从 servlet 发送到客户端,客户端在那里提取它们以运行某些支持功能。
In JBoss 4 we would look these jars up with the classloader and find a jar:// URL which would be used to read the jar and send its contents to the client.
在 JBoss 4 中,我们将使用类加载器查找这些 jar,并找到一个 jar:// URL,该 URL 将用于读取 jar 并将其内容发送到客户端。
In JBoss 6 when we perform the lookup we get a vfs:/ URL. I understand that this is from the org.jboss.vfs package. Unfortunately when I call openStream() on this URL and read from the stream, I immediately get an EOF (read() returns -1).
在 JBoss 6 中,当我们执行查找时,我们会得到一个 vfs:/ URL。我知道这是来自 org.jboss.vfs 包。不幸的是,当我在这个 URL 上调用 openStream() 并从流中读取时,我立即得到一个 EOF(read() 返回 -1)。
What gives? Why can't I read the resource this URL refers to?
是什么赋予了?为什么我无法读取此 URL 所指的资源?
I've tried trying to access the underlying VFS packages to open the file through the JBoss VFS API, but most of the API appears to be private, and I couldn't find a routine to translate from a vfs:/ URL to a VFS VirtualFile object, so I couldn't get anywhere.
我尝试访问底层 VFS 包以通过 JBoss VFS API 打开文件,但大多数 API 似乎是私有的,而且我找不到从 vfs:/ URL 转换为 VFS 的例程VirtualFile 对象,所以我无处可去。
I can try to find the file on disk within JBoss, but that approach sounds very failure prone on upgrade.
我可以尝试在 JBoss 中找到磁盘上的文件,但这种方法在升级时听起来很容易失败。
Our old approach was to use Java Web Start to distribute the jars to the client and then look them up within Java Web Start's cache to extract them. But that broke on every minor upgrade of Java because the layout of the cache changed.
我们的旧方法是使用 Java Web Start 将 jar 分发到客户端,然后在 Java Web Start 的缓存中查找它们以提取它们。但这在 Java 的每一次小升级中都会中断,因为缓存的布局发生了变化。
采纳答案by stacker
The issue JBVFS-147 Cannot read from vfs: protocol URLis still unresolved, maybe you want to vote and watch this issue.
问题JBVFS-147 无法从 vfs 读取:协议 URL仍未解决,也许您想投票并观看此问题。
回答by 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:
我发现我可以获取 VirtualFile 引用的物理文件,但返回的结果引用了一个名为 contents/ 的目录,该目录包含我正在查找的实际文件。所以:
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.
真是一团糟。我仍然不明白我原来的问题,这就是为什么 JBoss 会给我一个无法读取的 URL?但至少现在我可以继续前进。
回答by skiphoppy
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.
我发现 getContent() 方法会给我一个 VirtualFile,也许我可以使用它。仍然没有解释为什么我不能在 vfs:/ URL 上执行 openStream()。
import org.jboss.vfs.*;
URLConnection conn = new URL("vfs:/...").openConnection();
VirtualFile vf = (VirtualFile)conn.getContent();
InputStream is = vf.openStream();
回答by Enver Haase
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.
虚拟文件的 getContent() 方法也不起作用。我对其进行了测试,使用反射来避免对 JBoss/Wildfly 的依赖,而您可能不希望在 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.
从该流中读取也仅产生“-1”,即它是空的。
回答by Enver Haase
I have investigated the behaviour in WildFly11.
我已经调查了 WildFly11 中的行为。
In particular, only calling
特别是,只调用
getPhysicalFile();
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.
现在我可以在物理世界中列出根目录并访问其文件。