Wie eine nicht serialisierbaren Klasse (wie java.util.ResourceBundle) mit Weld injizieren
-
25-09-2019 - |
Frage
Ich möchte ein Hersteller schaffen, die es ermöglicht, eine java.util.ResourceBundle in jeder Klasse zu injizieren, um auf einfache Weise erhalten lokalisierte Strings. Mein Resource-Produzent sieht wie folgt aus:
public class ResourceBundleProducer {
@Inject
public Locale locale;
@Inject
public FacesContext facesContext;
@Produces
public ResourceBundle getResourceBundle() {
return ResourceBundle.getBundle("/messages", locale )
}
}
Die Injektion von Locale und Faces Werken (nahm die entsprechenden Produzenten aus der Naht 3 Alpha-Quelle). Aber leider ist nicht Serializable Resource und kann daher nicht auf diese Weise hergestellt werden. Ich erhalte die folgenden Fehler von Weld beim Versuch, eine JSF-Seite zuzugreifen, die eine Bean aufruft, die meine Resource verwendet:
Caused by: org.jboss.weld.IllegalProductException: WELD-000054 Producers cannot produce non-serializable instances for injection into non-transient fields of passivating beans\\n\\nProducer\: org.jboss.weld.bean-/D:/Program Files (x86)/GlassFish-Tools-Bundle-For-Eclipse-1.2/glassfishv3/glassfish/domains/teachernews/applications/teachernews/-ProducerMethod-services.producers.ResourceBundleProducer.getResourceBundle()\\nInjection Point\: field web.PersonHome.bundle
Gibt es Möglichkeiten, um meine ResourceBundleResolver zur Arbeit zu kommen? Oder gibt es andere Mechanismen, die eine ähnliche Funktionalität zu bekommen? Vielen Dank im Voraus!
EDIT:
Okay, ich werde einige meiner kaum verdienten Punkte ausgegeben;) Wird auch eine gute Lösung für dieses Problem an!
Ich habe ein anderes Beispiel, bei dem einen Produzenten Schaffung von Arbeit nicht: a FlashProducer. Eine Faces-Flash kann auch nicht erzeugt werden, da kein Flash serializable ist.
Lösung
Nun, zunächst einmal Resource ist nicht Serializable . Siehe hier . Und Die Botschaft ist klar
kann nicht produzieren Nicht-serializable Instanzen für die Injektion in nicht-transienten Felder von Passivieren Bohnen
Passivieren Bohnen ??? Ich denke web.PersonHome ist entweder eine Stateful Session Bean oder eine @ConversationScoped Bohne. Habe ich recht ??? Wenn ja, sollten Sie markieren Sie Ihre Bündel Eigenschaft als transiente
private transient @Inject ResourceBundle bundle;
Andere Tipps
Gemäß dem Kommentarthread in der akzeptierten Antwort von Arthur. Ich folgte diesen Blog sowie dieses eine Passivierung / Aktivierung Experiment durchzuführen. Das Experiment erwies sich als MrD Kommentar, dass die transiente Eigenschaft NULL bei Aktivierung sein wird. Somit kann mit nicht-serializable Mitglied Eigenschaften einer Passivierung der Lage Bohne (nämlich sessionscoped, conversationscoped und Stateful Session Beans) beschäftigen, schlage ich die folgende Lösung:
private ResourceBundle bundle;
@PostConstruct
@PostActivate
public void getResourceBundle() {
bundle = ResourceBundle.getBundle("/messages", locale );
}
Diese Lösung stellt sicher, dass die nicht-serializable Eigenschaft Mitglieder neu initialisiert werden jedes Mal, es den Bereitschaftszustand eintritt.
Eine letzte Ausgabe Adresse
Eine letzte Ausgabe-Adresse ist die Injektion eines SLF4J Logger, die war nicht serialisierbaren vor slf4j 1.5.3 und