OpenWebBeans
  1. OpenWebBeans
  2. OWB-589

" ... requires a passivation capable dependency ..." for producer method with return type String and non serializable injected dependency

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 1.1.0
    • Fix Version/s: 1.1.2
    • Component/s: Injection and Lookup
    • Labels:
      None
    • Environment:
      OWB 1.1.1-SNAPSHOT

      Description

      For @Produces method like:

      @Produces
      @MyOwnQualifier
      public String getSomeString(NonserializableDependency dependency)

      { return dependency.getSomeString(); }

      I've got exception:

      "If a producer method or field of scope @Dependent returns an serializable object for injection into an injection point Method Injection Point, method name : getSomeString, Bean Owner : [String, Name:null, WebBeans Type:PRODUCERMETHOD, API Types:[java.lang.Object,java.lang.Comparable,java.io.Serializable,java.lang.CharSequence,java.lang.String], Qualifiers:[javax.enterprise.inject.Any,MyOwnQualifier]] that requires a passivation capable dependency"

      I don't understand much what does it say , but with some help from debugger OWB validates for Serializable the injected parameter in producer method - NonserializableDependency dependency in this case.

      I checked the same with WELD 1.1.1 and it works without exception.

      1. OWB-589-test.patch
        6 kB
        Markus Mueller

        Activity

        Hide
        Martin Kočí added a comment -

        But if this is expected behaviour which part of specification requires that?

        Show
        Martin Kočí added a comment - But if this is expected behaviour which part of specification requires that?
        Hide
        Joe Bergmark added a comment -

        I agree that we shouldn't be checking that parameters injected into a producer method are serializable just because the producer method happens to return a serializable object. The producer method doesn't even appear to have a passivating scope in this case.

        It is possible that this code is trying to protect against these dependent objects getting stored in the creational context of a passivating scope if they aren't serializable. For example

        SessionScopedBean has @Inject @MyOwnQualifier String which in turn injects a NonserializableDependency. In this case we would try to store the NonserializableDependency in the creational context of the SessionScopedBean even though it might not be serializable. This is assuming that both the producer method and NonserializableDependency are dependent scoped.

        The spec does say we should check the parameters of the ProducerMethod itself declares a passivating scope 6.6.4.

        Show
        Joe Bergmark added a comment - I agree that we shouldn't be checking that parameters injected into a producer method are serializable just because the producer method happens to return a serializable object. The producer method doesn't even appear to have a passivating scope in this case. It is possible that this code is trying to protect against these dependent objects getting stored in the creational context of a passivating scope if they aren't serializable. For example SessionScopedBean has @Inject @MyOwnQualifier String which in turn injects a NonserializableDependency. In this case we would try to store the NonserializableDependency in the creational context of the SessionScopedBean even though it might not be serializable. This is assuming that both the producer method and NonserializableDependency are dependent scoped. The spec does say we should check the parameters of the ProducerMethod itself declares a passivating scope 6.6.4.
        Hide
        Mark Struberg added a comment -

        Martin, do you have a small working example maven project for us?

        txs!

        Show
        Mark Struberg added a comment - Martin, do you have a small working example maven project for us? txs!
        Hide
        Mark Struberg added a comment -

        I checked the code and the commit history. It seems that we only added this check to make some old TCK happy. Maybe the TCK got changed in the meantime and this overly strict rule got removed.
        In any case it's not about the parameter but really about the return type! I've removed it and the standalone TCK now still passes.

        In most cases the defined checks for Serializable are too strict in JSR-299. It doesn't honour that someone could also provide an own Externalizable#writeExternal/readExternal or Serializable readObject/writeObject implementation. I will move this to the EG.

        Show
        Mark Struberg added a comment - I checked the code and the commit history. It seems that we only added this check to make some old TCK happy. Maybe the TCK got changed in the meantime and this overly strict rule got removed. In any case it's not about the parameter but really about the return type! I've removed it and the standalone TCK now still passes. In most cases the defined checks for Serializable are too strict in JSR-299. It doesn't honour that someone could also provide an own Externalizable#writeExternal/readExternal or Serializable readObject/writeObject implementation. I will move this to the EG.
        Hide
        Mark Struberg added a comment -

        The target must (acc to 6.6.4) check
        "throw an IllegalProductException. If a producer method or field of scope @Dependent returns an unserializable object for injection into an injection point that requires a passivation capable dependency, the container must throw an Illegal- ProductException"

        The question now is what "injection point that requires a passivation capable dependency".

        Imo we are currently too strict about that and we should do something like:

        IF (injectionpoint is in passivatable scope AND retVal IS_NOT Serializable
        AND NOT ( injectionpoint hasMethod("writeObject") OR injectionpoint hasMethod("writeExternal") )
        throw IllegalProductException...

        I'll create a series of unit tests for it.

        Show
        Mark Struberg added a comment - The target must (acc to 6.6.4) check "throw an IllegalProductException. If a producer method or field of scope @Dependent returns an unserializable object for injection into an injection point that requires a passivation capable dependency, the container must throw an Illegal- ProductException" The question now is what "injection point that requires a passivation capable dependency". Imo we are currently too strict about that and we should do something like: IF (injectionpoint is in passivatable scope AND retVal IS_NOT Serializable AND NOT ( injectionpoint hasMethod("writeObject") OR injectionpoint hasMethod("writeExternal") ) throw IllegalProductException... I'll create a series of unit tests for it.
        Hide
        Mark Struberg added a comment -
        Show
        Mark Struberg added a comment - see spec issue https://issues.jboss.org/browse/CDI-140
        Hide
        Martin Kočí added a comment -

        Is there a workaround for this problem or a planned fix? I would like to migrate away from WELD but this is one of blocker issues for us.

        Show
        Martin Kočí added a comment - Is there a workaround for this problem or a planned fix? I would like to migrate away from WELD but this is one of blocker issues for us.
        Hide
        Martin Kočí added a comment -

        How to reproduce:

        AQualifierForString.java:
        @Qualifier
        @Retention(RetentionPolicy.RUNTIME)
        @Target(

        { ElementType.FIELD, ElementType.METHOD}

        )
        public @interface AQualifierForString {}

        SomeBean.java
        public class SomeBean {

        @Produces @Named public NonSerializableProduct getNonSerializableProduct()

        { return new NonSerializableProduct(); }

        @Produces @AQualifierForString public String getAString(NonSerializableProduct p)

        {return p.getSomeString();}

        @Alternative public static class NonSerializableProduct {
        public String getSomeString()

        { return "OWB"; }

        }
        }

        +

        use inject in client:
        @Inject @AQualifierForString String aString;

        Show
        Martin Kočí added a comment - How to reproduce: AQualifierForString.java: @Qualifier @Retention(RetentionPolicy.RUNTIME) @Target( { ElementType.FIELD, ElementType.METHOD} ) public @interface AQualifierForString {} SomeBean.java public class SomeBean { @Produces @Named public NonSerializableProduct getNonSerializableProduct() { return new NonSerializableProduct(); } @Produces @AQualifierForString public String getAString(NonSerializableProduct p) {return p.getSomeString();} @Alternative public static class NonSerializableProduct { public String getSomeString() { return "OWB"; } } } + use inject in client: @Inject @AQualifierForString String aString;
        Hide
        Mark Struberg added a comment -

        Hi!
        Actually you should file a bug against Weld because this is exactly what the spec requires at the moment
        With 'we' I was talking about hte JSR-337 Expert Group

        But yes, we will fix this problem nontheless. I will work on the spec wording in CDI-140 and overally improve the serialization handling in the CDI-1.1 spec and in OWB.

        Show
        Mark Struberg added a comment - Hi! Actually you should file a bug against Weld because this is exactly what the spec requires at the moment With 'we' I was talking about hte JSR-337 Expert Group But yes, we will fix this problem nontheless. I will work on the spec wording in CDI-140 and overally improve the serialization handling in the CDI-1.1 spec and in OWB.
        Hide
        Markus Mueller added a comment -

        Test case for clarified section 6.6.4 in CDI-1.1

        Show
        Markus Mueller added a comment - Test case for clarified section 6.6.4 in CDI-1.1
        Hide
        Mark Struberg added a comment -

        fixed in r1182364 by switching to the less strict behaviour which got defined in CDI-1.1. This was needed since CDI-1.0 was way too strict

        Show
        Mark Struberg added a comment - fixed in r1182364 by switching to the less strict behaviour which got defined in CDI-1.1. This was needed since CDI-1.0 was way too strict
        Hide
        Mark Struberg added a comment -

        shipped in OpenWebBeans-1.1.2

        Show
        Mark Struberg added a comment - shipped in OpenWebBeans-1.1.2

          People

          • Assignee:
            Mark Struberg
            Reporter:
            Martin Kočí
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development