为什么我无法打开 JBoss vfs:/ URL?

发布于 2024-10-16 01:33:00 字数 670 浏览 5 评论 0原文

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

应用程序的几个部分以一种不寻常的方式交付给客户端:在应用程序内部查找 jar 并从 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 的每次小升级,这种情况就会崩溃,因为缓存的布局发生了变化。

We are upgrading our application from JBoss 4 to 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.

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.

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).

What gives? Why can't I read the resource this URL refers to?

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.

I can try to find the file on disk within JBoss, but that approach sounds very failure prone on upgrade.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

最偏执的依靠 2024-10-23 01:33:00

之前的答案仍然会产生无法读取的流。

我发现我可以获得 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?但至少现在我可以继续前进。

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.

烧了回忆取暖 2024-10-23 01:33:00

问题 JBVFS-147 Cannot read from vfs: protocol URL 仍未解决,也许您想要投票并关注此问题。

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

往昔成烟 2024-10-23 01:33:00

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

import org.jboss.vfs.*;

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

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();
苍景流年 2024-10-23 01:33:00

我调查了 WildFly11 中的行为。

特别是,仅调用

getPhysicalFile();

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

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

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

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.

℡Ms空城旧梦 2024-10-23 01:33:00

虚拟文件的 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”,即它是空的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文