2016-07-20 20 views
0

Dies ist der Code, den ich habe:Warum funktioniert @PostConstruct nicht mit der Implementierung von Jetty + Apache MyFaces?

pom.xml

<dependency> 
    <groupId>javax.faces</groupId> 
    <artifactId>javax.faces-api</artifactId> 
    <version>2.2</version> 
</dependency> 
<dependency> 
    <groupId>com.sun.faces</groupId> 
    <artifactId>jsf-impl</artifactId> 
    <version>2.2.13</version> 
</dependency> 
<build> 
    <finalName>darbe</finalName> 
    <plugins> 
     <plugin> 
      <groupId>org.eclipse.jetty</groupId> 
      <artifactId>jetty-maven-plugin</artifactId> 
      <version>9.2.1.v20140609</version> 
      <configuration> 
       <scanIntervalSeconds>2</scanIntervalSeconds> 
       <webApp> 
        <contextPath>/</contextPath> 
       </webApp> 
      </configuration> 
     </plugin> 
    </plugins> 
</build> 

web.xml

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
          http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
     version="3.1"> 

    <servlet> 
     <servlet-name>FacesServlet</servlet-name> 
     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>FacesServlet</servlet-name> 
     <url-pattern>*.xhtml</url-pattern> 
    </servlet-mapping> 

    <welcome-file-list> 
     <welcome-file>foo.xhtml</welcome-file> 
    </welcome-file-list> 

</web-app> 

foo.xhtml

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://xmlns.jcp.org/jsf/html"> 
<h:head> 
    <title>Foo</title> 
</h:head> 
<h:body> 
    <h:outputText value="#{foo.bar}"/> 
</h:body> 
</html> 

und schließlich Foo.java

package biz.tugay; 

import javax.annotation.PostConstruct; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.SessionScoped; 

@ManagedBean 
@SessionScoped 
public class Foo { 

    private String bar; 

    @PostConstruct 
    public void init() { 
     bar = "Hello World"; 
    } 

    public String getBar() { 
     return bar; 
    } 

    public void setBar(String bar) { 
     this.bar = bar; 
    } 
} 

Also hier verwende ich die Oracle JSF-Implementierung. Und wenn ich dieses Projekt erstelle und es entweder auf Tomcat ausstelle oder das Jetty-Plugin (mvn jetty: start) benutze, sehe ich den Text Hallo Welt ganz gut in meinem Browser.

Allerdings, wenn ich die Abhängigkeiten ändern, wie unten zu sehen:

<dependency> 
    <groupId>org.apache.myfaces.core</groupId> 
    <artifactId>myfaces-api</artifactId> 
    <version>2.2.10</version> 
</dependency> 
<dependency> 
    <groupId>org.apache.myfaces.core</groupId> 
    <artifactId>myfaces-impl</artifactId> 
    <version>2.2.10</version> 
</dependency> 

ich nur Hallo Welt sehen, wenn ich den Krieg Datei mit Maven bauen und es zu Tomcat einsetzen. Wenn ich die Anwendung mit mvn jetty: start starte, wird @PostConstruct niemals aufgerufen, daher wird foo.bar null sein.

Was geht hier vor? Wie wird eine Annotation im javax.annotation-Paket gefunden, die auf der Basis der JSF-Implementierung, die ich gewählt habe, und/oder dem Container, in dem ich die WAR-Datei laufe, verarbeitet/nicht verarbeitet wurde?

Antwort

1

Die Antwort ist, dass myfaces standardmäßig mit integrierter Unterstützung für @ PostConstruct/@ PreDestroy mit Tomcat ausgeliefert wird und diese standardmäßig aktiviert.

Wenn Sie auf Ihre Log-Spur aussehen, wenn sie mit dem Steg Maven Plugin laufen Sie werden sehen:

21 Jul, Jahr 2016 09.49.42 org.apache.myfaces.config.annotation.DefaultLifecycleProviderFactory getLifecycleProvider INFO: Verwenden von LifecycleProvider org.apache.myfaces.config.annotation.Tomcat7AnnotationLifecycleProvider

So myfaces hat festgestellt, dass Tomcat LifeCycleProvider in seine impl Glas gebacken, und verwendet es standardmäßig.

Die Lösung besteht darin, MyFaces ausdrücklich zu informieren, einen anderen LifeCycleProvider zu verwenden. Ich habe den org.apache.myfaces.config.annotation.NoInjectionAnnotationLifecycleProvider (im impl jar) verwendet und es scheint zu funktionieren, aber vielleicht lohnt es sich, in den myfaces-Listen nach weiteren Informationen zu fragen. Um den LifeCycleProvider einzurichten, fügen Sie diesen zu Ihrer web.xml hinzu:

  <context-param> 
      <param-name> 
       org.apache.myfaces.config.annotation.LifecycleProvider 
      </param-name> 
      <param-value> 
       org.apache.myfaces.config.annotation.NoInjectionAnnotationLifecycleProvider 
      </param-value> 
      </context-param>