JBoss wildfly 8.x Поставщик "vfs" не установлен при использовании путей Java jio

Я пытаюсь экспортировать мое весеннее приложение из 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 в этой строке исключений у меня есть:

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

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

3 ответа

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

Обновить

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

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

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

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

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

<deployment>

    <dependencies>

        <system export="true">

            <paths>

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

            </paths>

        </system>

    </dependencies>

</deployment>

Другие вопросы по тегам