12

我们正在将我们的应用程序从 JBoss 4 升级到 JBoss 6。

我们的应用程序的几个部分以一种不寻常的方式交付给客户端:在我们的应用程序内部查找 jars 并从 servlet 发送给客户端,客户端提取它们以运行某些支持功能。

在 JBoss 4 中,我们将使用类加载器查找这些 jar,并找到一个 jar:// URL,该 URL 将用于读取 jar 并将其内容发送到客户端。

在 JBoss 6 中,当我们执行查找时,我们会得到一个 vfs:/ URL。我知道这是来自 org.jboss.vfs 包。不幸的是,当我在这个 URL 上调用 openStream() 并从流中读取时,我立即得到一个 EOF(read() 返回 -1)。

是什么赋予了?为什么我无法读取此 URL 引用的资源?

我尝试访问底层 VFS 包以通过 JBoss VFS API 打开文件,但大多数 API 似乎是私有的,我找不到从 vfs:/ URL 转换为 VFS 的例程VirtualFile 对象,所以我无处可去。

我可以尝试在 JBoss 中找到磁盘上的文件,但这种方法在升级时听起来很容易失败。

我们的旧方法是使用 Java Web Start 将 jar 分发到客户端,然后在 Java Web Start 的缓存中查找它们以提取它们。但是由于缓存的布局发生了变化,这在 Java 的每一次小升级中都被打破了。

4

5 回答 5

9

以前的答案仍然会产生一个无法读取的流。

我发现我可以获得 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);

真是一团糟。我仍然不明白我原来的问题,这就是为什么 JBoss 会给我一个无法读取的 URL?但至少我现在可以继续前进。

于 2011-02-04T16:33:00.893 回答
4

问题JBVFS-147 Cannot read from vfs: protocol URL is still unresolved, 也许你想投票看看这个问题。

于 2011-02-04T18:56:51.547 回答
4

我发现 getContent() 方法会给我一个 VirtualFile,也许我可以使用它。仍然没有解释为什么我不能只在 vfs:/ URL 上执行 openStream() 。

import org.jboss.vfs.*;

URLConnection conn = new URL("vfs:/...").openConnection();
VirtualFile vf = (VirtualFile)conn.getContent();
InputStream is = vf.openStream();
于 2011-02-04T15:25:39.510 回答
0

我已经调查了 WildFly11 中的行为。

特别是,只调用

获取物理文件();

具有实际创建物理文件的副作用,并且只有那些您似乎可以阅读的文件。为了在虚拟目录中创建所有文件,我做了:

      // 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);

现在我可以在物理世界中列出根目录并访问其文件。

于 2019-09-11T19:09:12.033 回答
0

虚拟文件的 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);

从该 Stream 读取也只产生“-1”,即它是空的。

于 2019-09-11T18:23:19.137 回答