在WildFly上从纯Clojure web应用程序提供静态内容(非不变)-VFS错误是什么?

在WildFly上从纯Clojure web应用程序提供静态内容(非不变)-VFS错误是什么?,clojure,wildfly,Clojure,Wildfly,我被要求在WildFly上尝试部署一个通常部署在Tomcat上的Clojure web应用程序,以及一个在CLJ+CLJS中完成的不同web应用程序(这有一个不同的问题,即响应403个错误,但这是下一次的问题)。部署实际上不是一个问题,但后来发生的是。。。至少可以说,令人困惑。虽然最初在Tomcat上的纯Clojure web应用程序确实成功地部署在Wildfly上,但实际上没有任何静态内容是可访问的 检查undertow服务器日志时发现重复错误,以下是其中一个错误的堆栈跟踪: 2016-01-

我被要求在WildFly上尝试部署一个通常部署在Tomcat上的Clojure web应用程序,以及一个在CLJ+CLJS中完成的不同web应用程序(这有一个不同的问题,即响应403个错误,但这是下一次的问题)。部署实际上不是一个问题,但后来发生的是。。。至少可以说,令人困惑。虽然最初在Tomcat上的纯Clojure web应用程序确实成功地部署在Wildfly上,但实际上没有任何静态内容是可访问的

检查undertow服务器日志时发现重复错误,以下是其中一个错误的堆栈跟踪:

2016-01-26 16:57:49,069 ERROR [io.undertow.request] (default task-2) UT005023: Exception handling request to /admin-rrs-sm/js/asset-scripts.js: java.lang.IllegalArgumentException: No method in multimethod 'resource-data' for dispatch value: :vfs
at clojure.lang.MultiFn.getFn(MultiFn.java:156)
at clojure.lang.MultiFn.invoke(MultiFn.java:229)
at ring.util.response$url_response.invoke(response.clj:269)
at ring.util.response$resource_response.doInvoke(response.clj:287)
at clojure.lang.RestFn.invoke(RestFn.java:410)
at compojure.route$resources$fn__4743.invoke(route.clj:37)
at compojure.core$make_route$fn__4621.invoke(core.clj:130)
at compojure.core$wrap_route_middleware$fn__4617.invoke(core.clj:118)
at compojure.core$if_route$fn__4589.invoke(core.clj:41)
at compojure.core$if_method$fn__4581.invoke(core.clj:27)
at compojure.core$routing$fn__4628.invoke(core.clj:144)
at clojure.core$some.invoke(core.clj:2570)
at compojure.core$routing.doInvoke(core.clj:144)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invoke(core.clj:632)
at compojure.core$routes$fn__4632.invoke(core.clj:149)
at cemerick.friend$handler_request.invoke(friend.clj:222)
at cemerick.friend$authenticate_STAR_.invoke(friend.clj:249)
at cemerick.friend$authenticate$fn__2970.invoke(friend.clj:260)
at ring.middleware.flash$wrap_flash$fn__8494.invoke(flash.clj:35)
at ring.middleware.session$wrap_session$fn__6540.invoke(session.clj:102)
at ring.middleware.keyword_params$wrap_keyword_params$fn__8307.invoke(keyword_params.clj:35)
at ring.middleware.nested_params$wrap_nested_params$fn__8357.invoke(nested_params.clj:84)
at ring.middleware.multipart_params$wrap_multipart_params$fn__8400.invoke(multipart_params.clj:117)
at ring.middleware.params$wrap_params$fn__8273.invoke(params.clj:64)
at ring.middleware.cookies$wrap_cookies$fn__6419.invoke(cookies.clj:161)
at ring.middleware.absolute_redirects$wrap_absolute_redirects$fn__8606.invoke(absolute_redirects.clj:36)
at ring.middleware.content_type$wrap_content_type$fn__8563.invoke(content_type.clj:30)
at ring.middleware.default_charset$wrap_default_charset$fn__8583.invoke(default_charset.clj:26)
at ring.middleware.not_modified$wrap_not_modified$fn__8544.invoke(not_modified.clj:52)
at ring.middleware.x_headers$wrap_xss_protection$fn__8472.invoke(x_headers.clj:71)
at ring.middleware.x_headers$wrap_frame_options$fn__8460.invoke(x_headers.clj:38)
at ring.middleware.x_headers$wrap_content_type_options$fn__8466.invoke(x_headers.clj:53)
at ring.middleware.session$wrap_session$fn__6540.invoke(session.clj:102)
at hiccup.middleware$wrap_base_url$fn__6037.invoke(middleware.clj:12)
at ring.middleware.keyword_params$wrap_keyword_params$fn__8307.invoke(keyword_params.clj:35)
at ring.middleware.nested_params$wrap_nested_params$fn__8357.invoke(nested_params.clj:84)
at ring.middleware.params$wrap_params$fn__8273.invoke(params.clj:64)
at ring.middleware.multipart_params$wrap_multipart_params$fn__8400.invoke(multipart_params.clj:117)
at compojure.core$routing$fn__4628.invoke(core.clj:144)
at clojure.core$some.invoke(core.clj:2570)
at compojure.core$routing.doInvoke(core.clj:144)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invoke(core.clj:632)
at compojure.core$routes$fn__4632.invoke(core.clj:149)
at clojure.lang.Var.invoke(Var.java:379)
at reporter.listener$_contextInitialized$fn__11.invoke(listener.clj:1)
at ring.util.servlet$make_service_method$fn__9032.invoke(servlet.clj:129)
at reporter.servlet$_service.invoke(servlet.clj:1)
at reporter.servlet.service(Unknown Source)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:86)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:72)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:282)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:261)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:80)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:172)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:199)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:774)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
虽然您可以实际浏览页面,但实际上没有加载任何CSS或JS,这破坏了应用程序的大部分功能。我已经尝试了很多方法来解决这个问题。例如,我在
standalone.xml
中添加了一些额外的内容,以便尝试将静态资源指向不同的位置,如下所示:

                <host name="default-host" alias="localhost">
                <location name="/" handler="welcome-content"/>
                <location name="/images" handler="images"/>
                <location name="/js" handler="scripts"/>
                <location name="/css" handler="css"/>
                <filter-ref name="server-header"/>
                <filter-ref name="x-powered-by-header"/>
            </host>
        </server>

        <handlers>
            <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
            <file name="images" path="${jboss.home.dir}/images"/>
            <file name="scripts" path="${jboss.home.dir}/js"/>
            <file name="css" path="${jboss.home.dir}/css"/>
        </handlers>

但是,没有用


“VFS”背后的含义是什么?是否存在我不知道的虚拟文件系统问题

Clojurians Slack社区,特别是immutant,在这方面帮助了我。事实证明,在Wildfly中使用
wrap resource
Ring
版本
1.3.2
开始,会导致应用程序提供一个空文件。这个问题被记录在@tcrawley的地方,他是负责解决这个问题的好心人,他指给我把它包括在我自己的应用程序中,我发现了这个应用程序

由于我的应用程序当然没有
immutant
try-resolve
,因此您还需要在应用程序的某个地方包含
try-resolve
。你也需要包括在内


这些处理程序看起来与您指向文件系统目录的处理程序不一样。
VFS
是用作部署内部视图的虚拟文件系统。这是一个WAR部署吗?是的,这是一个WAR部署我的问题是我试图提供WAR文件中已经存在的静态内容;因为这最初是用于Tomcat部署的。我不太确定它可能是什么。那个错误信息相当隐晦。我不确定那
:vfs
指的是什么。它可能是JBoss VFS,但我不知道错误消息来自何处。你知道这是不是戒指上的一个bug吗?”因为我们进入了1.5版,这仍然是事实。还是包装资源的工作方式?还是野蝇有些奇怪?
(when (try-resolve 'ring.util.response/resource-data)
  (eval
    '(defmethod ring.util.response/resource-data :vfs
       [url]
       (let [conn (.openConnection url)
             vfile (.getContent conn)]
         (when-not (.isDirectory vfile)
           {:content (.getInputStream conn)
            :content-length (.getContentLength conn)
            :last-modified (-> vfile
                             .getPhysicalFile
                             ring.util.io/last-modified-date)})))))
(defn require-resolve
  "Requires and resolves the given namespace-qualified symbol."
  [sym]
  (require (symbol (namespace sym)))
  (resolve sym))

(defn try-resolve
  "Tries to require and resolve the given namespace-qualified symbol, returning nil if not found."
  [sym]
  (try
    (require-resolve sym)
    (catch java.io.FileNotFoundException _)
    (catch RuntimeException _)))