Comment injecter une classe non sérialisable (comme java.util.ResourceBundle) avec soudure
-
25-09-2019 - |
Question
Je veux créer un producteur qui permet d'injecter un java.util.ResourceBundle dans une classe afin de se localiser facilement des chaînes. Mon ResourceBundle-producteur ressemble à ceci:
public class ResourceBundleProducer {
@Inject
public Locale locale;
@Inject
public FacesContext facesContext;
@Produces
public ResourceBundle getResourceBundle() {
return ResourceBundle.getBundle("/messages", locale )
}
}
L'injection de Locale et FacesContext fonctionne (a pris les producteurs de la Seam 3 Alpha source correspondant). Mais malheureusement, ResourceBundle n'est pas Serializable et ne peut donc pas être produit de cette façon. Je reçois l'erreur suivante de soudage lorsque vous essayez d'accéder à une page JSF qui appelle un haricot qui utilise mon ResourceBundle:
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
Y a-t-il des moyens pour mon ResourceBundleResolver de travailler? Ou sont-il d'autres mécanismes pour obtenir une fonctionnalité similaire? Merci d'avance!
EDIT:
D'accord, je vais passé une partie de mes points gagnés à peine;) Également accepter une bonne solution à ce problème!
Je suis un autre exemple où la création d'un producteur ne fonctionne pas: un FlashProducer. Un FacesContext-Flash aussi ne peut pas être produit parce que Flash n'est pas sérialisable.
La solution
Eh bien, tout d'abord ResourceBundle n'est pas Serializable . Voir . Et le message est clair
ne peut pas produire des cas non sérialisables pour injection dans non transitoire champs de haricots passiver
haricots passivants ??? Je pense web.PersonHome Soit une session Stateful Bean ou un haricot @ConversationScoped. Ai-je raison ??? Si oui, vous devriez marquer votre propriété de paquet comme transitoire
private transient @Inject ResourceBundle bundle;
Autres conseils
par le fil des commentaires dans la réponse acceptée d'Arthur. Je suivais ce blog ainsi que celui-ci pour réaliser une expérience passivation / activation. L'expérience a prouvé commentaire MrD que la propriété transitoire sera NULL lors de l'activation. Ainsi, pour faire face à des propriétés non membres sérialisables d'un haricot passivation capable (à savoir, sessionscoped, conversationscoped et des haricots de session stateful), je vous propose la solution suivante:
private ResourceBundle bundle;
@PostConstruct
@PostActivate
public void getResourceBundle() {
bundle = ResourceBundle.getBundle("/messages", locale );
}
Cette solution fait en sorte que les membres de la propriété non-sérialisables sont réinitialisés à chaque fois qu'il entre dans l'état PRÊT.
Une dernière question à aborder
Un dernier problème à traiter est l'injection d'un enregistreur SLF4J qui était non-serializable avant slf4j 1.5.3, et