[
https://issues.jboss.org/browse/CDI-565?page=com.atlassian.jira.plugin.sy...
]
Martin Andersson commented on CDI-565:
--------------------------------------
Or {{java.util.Optional}} since JDK 8.
Yeah, I think we all agree that the ideal world make a minimal use of {{null}}. But I sure
don't think we can ever manage without {{null}}. In fact, {{null}} has some really
good use cases. What would you think if {{Map.get(Object)}} threw an exception instead of
returning {{null}} when the mapping doesn't exist? Well, the CDI container is one huge
map. I ask for a mapped value given a set of types and/or qualifiers - the keys. What is
the difference? Even if you do think {{null}} is absolute evil, then it is with us already
for better or worse. Convenience, or what we together believe is the most intuitive
approach, has to take precedence.
Fail-fast is a good practice, but having it implemented just because one can may be a
brutal way of enforcing dogma upon others. I see this "fail-fast" approach as
both braking intuition and reducing the service offer. I'm not saying I am right. I am
trying to find out why some of us developers has to pay the price, for what benefit, for
what gain?
You say it "helps developers" by "avoiding surprising NPE:s at
runtime". All exceptions not handled is a surprise, whether that happens during
deployment or runtime. But let me point out that if anything is a surprise, then it is the
exception types CDI define and all vendor-specific messages the application servers output
in the log file, and you know I am right on this point. New developers in particular will
have to walk though a lot of struggles until they have a solid understanding of the CDI
vocabulary like "ambiguous" and "unsatisified". Compare that with a a
{{java.lang.NullPointerException}} in the log file with a clear stack trace to the exact
source code line where the reference was dereferenced. What a NPE is and how to deal with
it is probably what all new developers learn on their very first day.
Non-developers like to praise programmers as being some kind of super humans. What I often
find myself saying in response to my friends, and experiences I think you share with me,
is that I am lazy. I am not really a problem solver. I am not really smart. I'm trying
to find the best architecture such that the design can do the thinking for me. I am trying
to reduce complexity, trying to simplify and automate everything. Most importantly, I will
not try to fix a problem before I have one. And that is super important. By trying to fix
a problem before I have it, I might end up introducing one instead. Been there done that
many times over. Recognize the situation? That's why we are having this discussion.
"Premature optimization is the root of all evil" and ya'll know it =) Least
you can do is {{@Optional}}.
Unsatisfied dependency should be null?
--------------------------------------
Key: CDI-565
URL:
https://issues.jboss.org/browse/CDI-565
Project: CDI Specification Issues
Issue Type: Feature Request
Components: Beans
Reporter: Martin Andersson
What if I am writing a component that call a collaborator only if that class exist during
runtime? It is amazingly intuitive to write code like this:
{code:java}
class MyComponent
{
@Inject
SomeCollaborator collaborator;
public void someMethod() {
// .. do something
if (collaborator != null) {
collaborator.callback();
}
}
}
{code}
But the specification currently says in section "5.2.2. Unsatisfied and ambiguous
dependencies" that this code should cause a "deployment problem". IIRC,
GlassFish 4.1 and WildFly 9 doesn't actually crash during deployment. They will inject
{{null}}. WebLogic 12, I just learned, do crash during deployment.
I believe it is unfortunate to have this null value logic for no apparent reason. It is
inevitably so that the application code would crash anyways as soon as it tries to
dereference a null reference. And you probably agree with me that there's a general
guideline established in the developer community which say you shouldn't do null
pointer checks all over the code because null pointers will crash exactly when and where
the absence of a value really is a problem.
The work around is to inject an {{Instance}} of my type and iterate through all of them,
or do any other form of programmatic lookup. However, me personally, I've had this
requirement far too many times now. It is often the case that a component I write has a
"subframework" in place such that when I want to affect how the application
performs, I can just add in new classes of a particular type and it is scoped up. Please
don't even make the notion of a design smell out of your own lack of creativity, if
you want to see a concrete example then of course I am more than happy to provide you with
that. Just saying =)
Something so intuitive and present in our every day coding life as a "null return
value" should be present in the CDI specification too. I mean that is what the
specification in essence is; one huge {{lookupInstanceOf(class)}}-method. Reading this
method name, would you really expect it to crash, or return {{null}}?
How about adding in a new annotation such that the injection point accept null values for
unsatisfied dependencies, but if the injection point has an annotation {{@Required}}, then
an unsatisfied dependency do crash for this injection point?
You will probably say "let's do it the other way around so that we don't
brake backward compatibility" by creating an {{@Optional}} annotation. Hey, if I am
abusive to my wife and she divorce me. Should I continue to be abusive to my next wife so
that I don't break backward compatibility? Our number one goal should be to define the
most awesome specification and API possible - nothing else. If we keep leaving small piles
of poo everywhere, then we will inevitably end up deep in shit.
Thank you all for your hard work and time devoted to making all of our lives so much
greater.
--
This message was sent by Atlassian JIRA
(v6.4.11#64026)