2016-03-23 10 views
2

ich zwei Managed Beans haben, die beide eine @ApplicationScope Anmerkung:JSF ist die Schaffung von zwei Instanzen eines ApplicationScoped Bohne

Storage.java:

@ManagedBean(eager = true) 
@ApplicationScoped 
public class Storage { 

    private static final Logger LOGGER = LoggerFactory.getLogger(Storage.class); 

    private List<Sheet> sheets = new ArrayList<Sheet>(); 

    public List<Sheet> getSheets() { 
     return sheets; 
    } 

    public Sheet load(String id) { 
     // ... 
    } 

    public void storeSheet(Sheet sheet) { 
     sheets.add(sheet); 
     LOGGER.trace(""+this.hashCode()+" Stored sheet: "+sheet); 
    } 

    public void delete(Sheet s) { 
     sheets.remove(s); 
     LOGGER.trace(""+this.hashCode()+" Removed sheet: "+s); 
    } 

} 

StorageInitializer.java:

@ManagedBean(eager = true) 
@ApplicationScoped 
public class StorageInitializer { 

    @ManagedProperty(value = "#{storage}") 
    private Storage storage; 

    @PostConstruct 
    public void init() { 
     int nofSheets = 10; 
     int min = 20; 
     int max = 200; 
     for (int i=0; i<nofSheets; i++) { 
      storage.storeSheet(new Sheet(
        "Sheet "+i, 
        ThreadLocalRandom.current().nextInt(min, max), 
        ThreadLocalRandom.current().nextInt(min, max))); 
     } 
    } 

    public void setStorage(Storage storage) { 
     this.storage = storage; 
    } 

} 

Wenn die Anwendung gestartet wird, sollte StorageInitializer 10 Instanzen in den Speicher schreiben. Andere Beans mit @RequestScoped greifen auf das Geschäft zu und machen die Blätter sichtbar. Sie alle haben eine

@ManagedProperty(value = "#{storage}") 
    private Storage storage; 

Zugriff auf die Storage Bean.

Durch Protokollieren des Hash kann ich sehen, dass ich manchmal zwei Instanzen der Storage Bean. Der erste wird von StorageInitializer initialisiert. Der zweite wird von den Beans @RequestScoped verwendet und ist leer.

Für mich sieht das wie ein Race Condition oder Timing Problem aus. Wenn ich einen Unterbrechungspunkt in StorageInitializer.ini() einstelle, funktioniert alles ok.

Irgendwelche Ideen?

+0

Von welchem ​​Paket haben Sie '@ ApplicationScoped' Annotation importiert? – BalusC

+0

javax.faces.bean.ApplicationScoped – BetaRide

+0

In beiden Fällen? Vorausgesetzt, alle diese Klassen befinden sich in WAR (und daher nicht in EAR), ist der Klassenpfad für die Laufzeit höchstwahrscheinlich mit mehreren verschiedenen versionierten JSF-Bibliotheken belastet. Überprüfen und säubern Sie es. – BalusC

Antwort

0

Ich hatte das gleiche Problem mit zwei @ApplicationScoped Beans mit "Eager = True". Die duplizierte Bean befand sich in einer @ManagedProperty in der anderen @ApplicationScoped-Bean. Ich löste das Problem, indem ich in der Bean, die die @ManagedProperty besaß, den Wert von eager auf false änderte. In meinem Fall war der eifrige Wert nicht unbedingt notwendig.

+0

Welche JSF-Version verwenden Sie? Versucht das Neueste? – Kukeltje

Verwandte Themen