CDI constructor injection don't work with transient non-serializable dependencies
Asked Answered
L

1

6

I like the constructor injection of CDI a lot but now I found a usecase where constructor injection apparently doesn't work as expected.

In my example I have two classes. Class "BeanA" has no explicit scope defined and does not implement Serializable. Class "BeanB" is annotated with @SessionScoped and does implement Serializable.

public class BeanA{
}

@SessionScoped
public class BeanB implements Serializable{
    @Inject
    private BeanA beanA;
}

When I try to inject an instance of BeanA into BeanB of cource I get an UnserializableDependencyException from Weld because BeanA isn't serializable. This is the expected behaviour.

When I mark the field "beanA" with "transient" the injection works without problems:

@Inject
private transient BeanA beanA;

Now Weld doesn't throw any exceptions.

This is perfectly fine for me but my understanding problem comes when I like to get this working with constructor injection. When I do the following it doesn't work anymore:

@SessionScoped
public class BeanB implements Serializable{
    private transient BeanA beanA;

    @Inject
    public BeanB(BeanA beanA){
        this.beanA = beanA;
    }

    public BeanB(){}
}

With this code I get the UnserializableDependencyException again. I thought that constructor injection and field injection are more or less equivalent but obviously they aren't. What is my mistake?

Leaseholder answered 12/1, 2012 at 23:34 Comment(0)
D
2

That seems like a bug. Does everything work well if you make BeanA serializable? Also which version of Weld are you using?

Demetriusdemeyer answered 16/1, 2012 at 21:52 Comment(3)
Thanks for the answer. I have tested it with version "1.0.1-Final" and with "1.1.5.Final" of weld-servlet. When I make BeanA serializable it works well. For my own classes this would be a solution but the problem is still there when you want to inject classes from other frameworks.Leaseholder
I was looking into the CDI spec and found a paragraph that explains the behaviour: link,6.6.4 says that "If a managed bean which declares a passivating scope: [...] has a non-transient injected field, bean constructor parameter or initializer method parameter that does not resolve to a passivation capable dependency [...] the container automatically detects the problem and treats it as a deployment problem.". Obviously this is the expected behaviour but I don't fully understand what the reason for this differentiation isLeaseholder
I saw that, and you should have had an exception. Please raise a JIRA for Weld.Demetriusdemeyer

© 2022 - 2024 — McMap. All rights reserved.