我们正在将我们的应用程序从JBoss 4升级到JBoss 6。
我们的一些应用程序以一种不寻常的方式传递给客户端:在我们的应用程序内部查找jar并从servlet发送到客户端,客户端在其中提取它们以运行某些支持功能。
在JBoss 4中,我们将使用类加载器查看这些罐子,并找到一个jar:// URL,用于读取jar并将其内容发送到客户端。
在JBoss 6中,当我们执行查找时,我们得到一个vfs:/ URL。我知道这是来自org.jboss.vfs包。不幸的是,当我在这个URL上调用openStream()并从流中读取时,我立即得到一个EOF(read()返回-1)。
是什么给出的?为什么我不能读取此URL引用的资源?
我尝试通过JBoss VFS API尝试访问底层VFS包以打开文件,但是大多数API似乎是私有的,我找不到从vfs:/ URL翻译的例程到VFS VirtualFile对象,所以我无法到达任何地方。
我可以尝试在JBoss中的磁盘上找到该文件,但这种方法在升级时听起来非常容易失败。
我们的旧方法是使用Java Web Start将jar分发到客户端,然后在Java Web Start的缓存中查找它们以提取它们。但是,由于缓存的布局发生了变化,因此Java的每次轻微升级都会破坏。
答案 0 :(得分:10)
以前的回答仍会产生无法读取的流。
我发现我可以获得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?但至少我现在可以继续前进。
答案 1 :(得分: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();
答案 2 :(得分:4)
问题JBVFS-147 Cannot read from vfs: protocol URL仍未解决,也许您想投票并观看此问题。
答案 3 :(得分:0)
用于虚拟文件的getContent()方法也不起作用。 我进行了测试,使用反射避免了可能不需要Servlet的对JBoss / Wildfly的依赖。
const dictArr = ["lock", "combo"];
function checkInDic(val){
var len = 0;
dictArr.forEach(element => {
if(val.includes(element)){
len += element.length;
}else{
return false;
}
});
if(len == val.length){
return true;
}else{
return false;
}
}
从该Stream读取还只产生“ -1”,即为空。
答案 4 :(得分:0)
我已经研究了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);
现在,我可以列出物理环境中的根目录并访问其文件。