JBoss wildfly 8.x Провайдер "vfs" не установлен при использовании java nio Paths

Я пытаюсь экспортировать приложение spring из glassfish 4 в JBoss wildfly 8.x или 9 alpha, но когда мое приложение запускается в какой-то части моего кода, выдается исключение:

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 в этой строке исключения i:

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

где path его путь к пакету, например com.something.model, так почему на моем сервере Glassfish 4 это работает отлично и что мне нужно для его использования в wildfly? я не знаю, чего не хватает в wildfly или мне нужно включить некоторую библиотеку.

Ответ 1

Это происходит случайно в GlassFish. Нигде в контракте ClassLoader (или в спецификации платформы Java EE) не указано, какой тип URL вы получите. В GlassFish ClasLoder это, вероятно, URL-адрес jar:// или file:// для которого существует FileSystemProvider (jar:// только случайно BTW). В WildFly URL является URL JBoss VFS. Есть несколько хаков, которые вы можете применить, чтобы заставить его работать на данный момент, но все они не могут скрыть тот факт, что вы полагаетесь на непереносимое поведение. Вместо этого лучше использовать что-то вроде URL#openStream() которое переносимо и поэтому должно работать везде.

Обновить

То, что вы можете попытаться сделать, это сделать больше во время компиляции. Варианты включают в себя:

  • Сделайте преобразование с Javassist во время компиляции. Это также уменьшает вероятность конфликтов с Javassist, отправляющими с WildFly.
  • Соберите информацию о ресурсах во время компиляции и сохраните ее в файле в хорошо известном месте. Вы можете иметь одинаковое имя файла в нескольких JAR- ClassLoader#getResources(String) как ClassLoader#getResources(String) может возвращать несколько результатов.

Если вы предоставите более конкретную информацию о проблеме, которую вы пытаетесь решить, я смогу дать более конкретные ответы.

Ответ 2

Это мое решение, как перебирать файлы/каталоги в 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

добавьте следующий jboss-deployment-structure.xml

<deployment>

    <dependencies>

        <system export="true">

            <paths>

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

            </paths>

        </system>

    </dependencies>

</deployment>

Ответ 4

    import org.jboss.vfs.VirtualFile; // https://mvnrepository.com/artifact/org.jboss/jboss-vfs

    URLConnection connection = Objects.requireNonNull(getClass().getClassLoader().getResource("/template/cyber")).openConnection();
    VirtualFile virtualFile = (VirtualFile) connection.getContent();
    Stream<Path> walk = Files.walk(Paths.get(virtualFile.getPhysicalFile().toURI()));
    List<String> result = walk.filter(Files::isRegularFile).map(Path::toString).collect(Collectors.toList());