使用java nio Paths时未安装JBoss wildfly 8.x Provider“vfs”

我正在尝试将我的spring应用程序从glassfish 4导出到JBoss wildfly 8.x或9 alpha,但是当我的应用程序在我的代码的某些部分启动时抛出exception:

Caused by: java.lang.RuntimeException: java.nio.file.FileSystemNotFoundException: Provider "vfs" not installed at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:218) at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:87) at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.start(UndertowDeploymentService.java:72) at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948) [jboss-msc-1.2.2.Final.jar:1.2.2.Final] at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881) [jboss-msc-1.2.2.Final.jar:1.2.2.Final] ... 3 more Caused by: java.nio.file.FileSystemNotFoundException: Provider "vfs" not installed at java.nio.file.Paths.get(Paths.java:147) [rt.jar:1.7.0_72] at com.springmvcangular.backend.utils.entity.BaseEntityInitializer.extendsEntities(BaseEntityInitializer.java:123) at com.springmvcangular.backend.utils.entity.BaseEntityInitializer.initializeBaseEntities(BaseEntityInitializer.java:88) at com.springmvcangular.backend.config.ApplicationInitializer.onStartup(ApplicationInitializer.java:60) at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175) at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:178) ... 7 more 

在我的类BaseEntityInitializer中,该exception行我有:

 packagepath = Paths.get(this.getClass().getClassLoader() .getResource(path.replace('.', '/')).toURI()); 

其中path是一个像com.something.model这样的包路径,为什么在我的glassfish 4服务器中这个工作完美,我需要在wildfly中使用它? 我不知道wildfly中缺少什么,或者我是否需要包含一些库。

它碰巧在GlassFish中偶然发挥作用。 ClassLoader合同(或JavaEE平台规范)中没有指定您获取的URL类型。 在GlassFish ClasLoder中,它可能恰好是一个jar://file:// URL恰好是一个FileSystemProvider( jar://只是偶然BTW)。 在WildFly中,这恰好是一个JBoss VFS URL。 你现在可以使用各种黑客来使其工作,但它们都无法掩盖你依赖于不可移植的行为这一事实。 你最好使用像URL#openStream()这样的东西而不是可移植的,因此应该可以在任何地方使用。

更新

您可以尝试做的是在编译时执行更多操作。 选项包括:

  • 在编译时使用Javassist进行转换。 这也减少了使用WildFly与Javassist发货冲突的可能性。
  • 在编译时收集有关资源的信息,并将其存储在一个众所周知的位置的文件中。 您可以在多个JAR中具有相同的文件名,因为ClassLoader#getResources(String)可以返回多个结果。

如果您提供有关您尝试解决的问题的更具体的信息,我可以提供更具体的答案。

这是我在Wildfly中迭代文件/目录的解决方案:

 List fileNames = new LinkedList<>(); URL resourceUrl = getClass().getResource("/your/path"); VirtualJarInputStream virtualJarInputStream = (VirtualJarInputStream) resourceUrl.openStream(); JarEntry next = null; while ((next = virtualJarInputStream.getNextJarEntry()) != null) { fileNames.add(next.getName()); } 

添加以下jboss-deployment-structure.xml