Undertow是否可以与JSF一起使用?

时间:2018-07-07 13:16:30

标签: jsf mojarra undertow

我正在尝试使用Mojarra启动Undertow,但是发生异常。 如何解决此错误并与JSF一起使用?

Here is similar question,但此解决方案不影响我的解决方案。

HelloWorldServer.java(引用Undertow Servlet):

public class HelloWorldServer {

    public static void main(String[] args) throws ServletException {
        DeploymentInfo servletBuilder = Servlets.deployment()
                .setClassLoader(HelloWorldServer.class.getClassLoader())
                .setContextPath("/myapp")
                .setDeploymentName("test.war")
                .addServlets(Servlets.servlet("FacesServlet", FacesServlet.class)
                        .addMapping("*.xhtml")
                        .setLoadOnStartup(1));

        DeploymentManager manager = Servlets.defaultContainer().addDeployment(servletBuilder);
        manager.deploy();
        PathHandler path = Handlers.path(Handlers.redirect("/myapp"))
                .addPrefixPath("/myapp", manager.start());

        Undertow server = Undertow.builder()
                .addHttpListener(8080, "localhost")
                .setHandler(path)
                .build();
        server.start();
    }
}

pom.xml

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <maven.compiler.source>1.8</maven.compiler.source>
  <maven.compiler.target>1.8</maven.compiler.target>
  <undertow.version>2.0.9.Final</undertow.version>
</properties>

<dependencies>
  <dependency>
    <groupId>io.undertow</groupId>
    <artifactId>undertow-core</artifactId>
    <version>${undertow.version}</version>
  </dependency>
  <dependency>
    <groupId>io.undertow</groupId>
    <artifactId>undertow-servlet</artifactId>
    <version>${undertow.version}</version>
  </dependency>
  <dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.faces</artifactId>
    <version>2.3.5</version>
  </dependency>
</dependencies>

例外:

Jul 07, 2018 9:57:50 PM javax.faces.FactoryFinderInstance copyInjectionProviderFromFacesContext
SEVERE: Unable to obtain InjectionProvider from init time FacesContext. Does this container implement the Mojarra Injection SPI?
Jul 07, 2018 9:57:50 PM javax.faces.FactoryFinderInstance logNoFactory
SEVERE: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory. Attempting to find backup.
[WARNING] 
java.lang.IllegalStateException: Could not find backup for factory javax.faces.context.FacesContextFactory. 
    at javax.faces.FactoryFinderInstance.notNullFactory (FactoryFinderInstance.java:548)
    at javax.faces.FactoryFinderInstance.getFactory (FactoryFinderInstance.java:231)
    at javax.faces.FactoryFinder.getFactory (FactoryFinder.java:303)
    at javax.faces.webapp.FacesServlet.acquireFacesContextFactory (FacesServlet.java:524)
    at javax.faces.webapp.FacesServlet.init (FacesServlet.java:364)
    at io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed (LifecyleInterceptorInvocation.java:117)
    at io.undertow.servlet.core.ManagedServlet$DefaultInstanceStrategy.start (ManagedServlet.java:300)
    at io.undertow.servlet.core.ManagedServlet.createServlet (ManagedServlet.java:140)
    at io.undertow.servlet.core.DeploymentManagerImpl$2.call (DeploymentManagerImpl.java:584)
    at io.undertow.servlet.core.DeploymentManagerImpl$2.call (DeploymentManagerImpl.java:555)
    at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call (ServletRequestContextThreadSetupAction.java:42)
    at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call (ContextClassLoaderSetupAction.java:43)
    at io.undertow.servlet.core.DeploymentManagerImpl.start (DeploymentManagerImpl.java:597)
    at com.github.yukihane.java.undertow.HelloWorldServer.main (HelloWorldServer.java:27)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:564)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:282)
    at java.lang.Thread.run (Thread.java:844)

2 个答案:

答案 0 :(得分:0)

请勿使用Mojarra 2.4.0 ,这是该发布之时尚未发布的时间。从Oracle到Eclipse的过渡必须放进去。

http://balusc.omnifaces.org/2018/04/do-not-use-orgglassfish-mojarra-240.html

因此,请使用最新的2.3.x版本(撰写本文时为2.3.5)

答案 1 :(得分:0)

1。

实现与FacesInitializer#onStartup相同,因此main方法类似于:

DeploymentInfo servletBuilder = Servlets.deployment()
        .setClassLoader(HelloWorldServer.class.getClassLoader())
        .setContextPath("/myapp")
        .setDeploymentName("test.war")
        .addServlets(Servlets.servlet("FacesServlet", FacesServlet.class)
                .addMappings("/faces/*", "*.jsf", "*.faces", "*.xhtml")
                .setLoadOnStartup(1))
        .addServletContextAttribute(RIConstants.FACES_INITIALIZER_MAPPINGS_ADDED, Boolean.TRUE)
        .addListener(new ListenerInfo(com.sun.faces.config.ConfigureListener.class))
        .setResourceManager(new ClassPathResourceManager(HelloWorldServer.class.getClassLoader(), "static"));
2。

受管Bean由AnnotationScanTaskDelegatingAnnotationProvider扫描,这是默认的AnnotationProvider实现。 因为DelegatingAnnotationProvider不扫描根类路径(而仅扫描/WEB-INF/classes(?)),所以我需要实现自定义AnnotationProvider

MyAnnotationProvider.java

package com.github.yukihane.java.undertow.service;

public class MyAnnotationProvider extends DelegatingAnnotationProvider {

    public MyAnnotationProvider(ServletContext sc) {
        super(sc);
    }

    @Override
    public Map<Class<? extends Annotation>, Set<Class<?>>> getAnnotatedClasses(Set<URI> urls) {
        Map<Class<? extends Annotation>, Set<Class<?>>> parentRes = super.getAnnotatedClasses(urls);

        // simplified implementation, without annotations scan
        Map<Class<? extends Annotation>, Set<Class<?>>> ret = new HashMap<>(parentRes);

        Set<Class<?>> parentSet = ret.get(ManagedBean.class);
        Set<Class<?>> set = (parentSet == null) ? new HashSet<>() : new HashSet<>(parentSet);
        set.add(Hello.class);
        ret.put(ManagedBean.class, set);

        return ret;
    }

}

META-INF/services/com.sun.faces.spi.annotationprovider(引用AnnotationProviderFactory):

com.github.yukihane.java.undertow.service.MyAnnotationProvider

以下是完整的资料来源: https://github.com/yukihane/hello-undertow-mojarra