JBoss wildfly 8.x Provider “vfs” not installed whe

2019-02-17 14:43发布

问题:

I'm trying to export my spring application from glassfish 4 to JBoss wildfly 8.x or 9 alpha, but when my application starts in some part of my code throws the 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

in my class BaseEntityInitializer in that exception line i have:

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

where path its a package path like com.something.model, so why in my glassfish 4 server this works perfectly and what i need for use it in wildfly? i don't know what is missing in wildfly or if i need to include some library.

回答1:

It happens to work by chance in GlassFish. Nowhere in the ClassLoader contract (or JavaEE platform specification) is it specified what kind of URL you get back. In the GlassFish ClasLoder it probably happens to be a jar:// or file:// URL with which there happens to be a FileSystemProvider (jar:// only by accident BTW). In WildFly this happens to be a JBoss VFS URL. There are various hacks that you can apply to make it work for now but they all can't hide the fact that you're relying on not portable behavior. You're better off using something like URL#openStream() instead with is portable and should therefore work everywhere.

Update

What you can try to do is doing more at compile time. Options include:

  • Do the transformation with Javassist at compile time. This also reduces the chances of conflicts with the Javassist shipping with WildFly.
  • Gather the information about the resources at compile time and store it in a file at a well known location. You can have the same file name in multiple JARs as ClassLoader#getResources(String) can return multiple results.

If you provide more specific informations about the problem you're trying to solve I may be able to give more specific answers.



回答2:

This is my solution how to iterate over files/directories in Wildfly:

List<String> 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());
}


回答3:

add the following jboss-deployment-structure.xml

<deployment>

    <dependencies>

        <system export="true">

            <paths>

                <path name="com/sun/nio/zipfs" />

            </paths>

        </system>

    </dependencies>

</deployment>