Weld
  1. Weld
  2. WELD-1076

Deal with non-serializable dependent instances of a passivation capable bean

    Details

    • Affects:
      Release Notes
    • Similar Issues:
      Show 10 results 

      Description

      Since https://github.com/jboss/cdi/pull/47 it is legal for a normal-scoped component to have a non-passivation capable dependency, e.g:

      @SessionScoped
      public class Foo implements Serializable {
       
         @Inject
         public Foo(Bar bar) {
         }
      }
       
      public class Bar {
      }
      

      Although the Bar instance reference is not retained by the Foo instance, the Bar instance is still technically a dependent instance of Foo and therefore the container needs to keep a reference to it in order to eventually destroy it properly.

      This is a problem because dependent instances of a bean are currently supposed to be serialized together with the normal-scoped instance but the Bar instance is not serializable.

      We may work around by making use of the following part of the spec:

      Finally, the container is permitted to destroy any @Dependent scoped contextual instance at any time if the instance is no
      longer referenced by the application (excluding weak, soft and phantom references)."

      and destroy every non-serializable dependent bean instance of a normal-scoped bean when the creational context for the normal-scoped bean instance is serialized.

      This is not 100% equivalent to "the instance is no longer referenced by the application" however covers all the sensible cases including:

      • Foo no longer holds a reference to Bar, therefore we can safely destroy Bar
      • Foo holds a reference to Bar - does not matter if we destroy Bar prematurely or not since serialization of Bar is going to fail anyway
      • Foo holds a reference to Bar in a transient field and is therefore either going to "forget" the reference no serialization (therefore we can destroy it) or is able to recreate the Bar instance itself on deserialization

        Gliffy Diagrams

          Issue Links

            Activity

            Jozef Hartinger created issue -
            Jozef Hartinger made changes -
            Field Original Value New Value
            Description Since https://github.com/jboss/cdi/pull/47 it is legal for a normal-scoped component to have a non-passivation capable dependency, e.g:

            {CODE:JAVA}
            @SessionScoped
            public class Foo implements Serializable {

               @Inject
               public Foo(Bar bar) {
               }
            }

            public class Bar {
            }
            {CODE}

            Although the Bar instance reference is not retained by the Foo instance, the Bar instance is still technically a dependent instance of Foo and therefore the container needs to keep a reference to it in order to eventually destroy it properly.

            We may make use of the following part of the spec:

            {QUOTE}
            Finally, the container is permitted to destroy any @Dependent scoped contextual instance at any time if the instance is no
            longer referenced by the application (excluding weak, soft and phantom references)."
            {QUOTE}

            and destroy every non-serializable dependent bean instance of a normal-scoped bean when the creational context for the normal-scoped bean instance is serialized.

            This should be safe for these cases:
            * Foo no longer holds a reference to Bar, therefore we can destroy Bar
            * Foo holds a reference to Bar - does not matter if we destroy Bar prematurely since serialization of Bar is going to fail anyway
            * Foo holds a reference to Bar in a transient field and is therefore either going to "forget" the reference (therefore we can destroy it) or is able to recreate the Bar instance itself on deserialization

            Since https://github.com/jboss/cdi/pull/47 it is legal for a normal-scoped component to have a non-passivation capable dependency, e.g:

            {CODE:JAVA}
            @SessionScoped
            public class Foo implements Serializable {

               @Inject
               public Foo(Bar bar) {
               }
            }

            public class Bar {
            }
            {CODE}

            Although the Bar instance reference is not retained by the Foo instance, the Bar instance is still technically a dependent instance of Foo and therefore the container needs to keep a reference to it in order to eventually destroy it properly.

            This is a problem because dependent instances of a bean are currently supposed to be serialized together with the normal-scoped instance but the Bar instance is not serializable.

            We may work around by making use of the following part of the spec:

            {QUOTE}
            Finally, the container is permitted to destroy any @Dependent scoped contextual instance at any time if the instance is no
            longer referenced by the application (excluding weak, soft and phantom references)."
            {QUOTE}

            and destroy every non-serializable dependent bean instance of a normal-scoped bean when the creational context for the normal-scoped bean instance is serialized.

            This is not 100% equivalent to "the instance is no longer referenced by the application" however covers all the sensible cases including:
            * Foo no longer holds a reference to Bar, therefore we can safely destroy Bar
            * Foo holds a reference to Bar - does not matter if we destroy Bar prematurely or not since serialization of Bar is going to fail anyway
            * Foo holds a reference to Bar in a transient field and is therefore either going to "forget" the reference no serialization (therefore we can destroy it) or is able to recreate the Bar instance itself on deserialization

            Jozef Hartinger made changes -
            Hide
            Jozef Hartinger added a comment -

            Alternatively, we should not use creational context to store dependent instances that do not define @PreDestroy callbacks nor are they intercepted by a @PreDestroy interceptor.

            Show
            Jozef Hartinger added a comment - Alternatively, we should not use creational context to store dependent instances that do not define @PreDestroy callbacks nor are they intercepted by a @PreDestroy interceptor.
            Ales Justin made changes -
            Link This issue is related to WELD-1079 [ WELD-1079 ]
            Jozef Hartinger made changes -
            Status Open [ 1 ] Resolved [ 5 ]
            Resolution Done [ 1 ]
            Jozef Hartinger made changes -
            Fix Version/s 1.2.0.Beta1 [ 12319290 ]
            Forum Reference https://community.jboss.org/message/730179 https://community.jboss.org/message/730179
            Jozef Hartinger made changes -
            Fix Version/s 1.1.8.Final [ 12319459 ]
            Forum Reference https://community.jboss.org/message/730179 https://community.jboss.org/message/730179
            Vlastimil Eliáš made changes -
            Workflow jira [ 12485127 ] GIT Pull Request workflow [ 12548073 ]

              People

              • Assignee:
                Jozef Hartinger
                Reporter:
                Jozef Hartinger
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Development