5

In a CDI Passivation Capable bean, is it possible to have non-passivation capable dependencies be re-injected rather than passivated?

Consider this code:

@SessionScoped
public class UserData implements Serializable {
  @Inject
  private Logger log;
  private String data;
}


@ApplicationScoped
public class LoggerFactory {
  @Produces
  public Logger getLogger(){
  ...
  }
}

public class Logger {
...
}

So Logger is not Serializable, but I really don't care. When UserData is deserialized, is it possible to have the producer for Logger called again somehow?

EDIT

The original discussion started here:

http://www.cdi-spec.org/news/2015/07/03/CDI-2_0-EDR1-released/#comment-2119769909

Hoping the CDI Expert group comes up with a better way than @Instance

Jonathan S. Fisher
  • 8,189
  • 6
  • 46
  • 84
  • A lot of reasons... What if you're injecting an EJB? Does it have to be serializable as well? What about SFL4J? Logger does not extend Serializable. – Jonathan S. Fisher Jul 06 '15 at 18:59
  • CDI and EJB generate and inject serializable proxies delegating further to the currently available (and auto-created) instance on a per-thread basis. Or did you face a `NotSerializableException`? – BalusC Jul 06 '15 at 19:00
  • CDI complains at boot time that some of the injected dependencies are not passivation capable. Which seems ridiculous since it's creating proxies for them! – Jonathan S. Fisher Jul 06 '15 at 20:49
  • Never faced those with Weld. – BalusC Jul 06 '15 at 20:53
  • :( What version of weld are you running? I'm using TomEE which is OWB and I think CDI 1.0 – Jonathan S. Fisher Jul 06 '15 at 20:54
  • EJB has a @PostActivate method annotation that does the trick. Isn't there a CID equivalent? – bruno Jul 25 '18 at 11:52
  • @BalusC, that's why: Some beans initialize non-serializable fields base on data on @Injected fields, and this is done in the `@PostConstruct` method. We want to do that post-activation. – bruno Jul 25 '18 at 11:55

1 Answers1

2

Checking the spec, you have your answer. Logger is not serializable, so the bean of type Logger is not passivation capable. The container doesn't provide the trick you are requesting.

The solution would be to write something like that:

@SessionScoped
public class UserData implements Serializable {
  @Inject
  private Instance<Logger> logInstance;
  private String data;

  public Logger getLog() {
   return logInstance.get();
  }
}

Ans use getLog() instead of log in your code.

Antoine Sabot-Durand
  • 4,875
  • 17
  • 33