javaee / ejb-spec

See javax.ejb project for API. Contains legacy issues only.
https://github.com/javaee/javax.ejb
6 stars 1 forks source link

Disambiguating broken default references #109

Open glassfishrobot opened 11 years ago

glassfishrobot commented 11 years ago

This is something I brought up EJB 3.1, but didn't drive enough for it to make it to the spec – we had a lot of priorities. Logging it so we can tackle it in EJB 3.3

The issue is there's no easy solution for dealing with application that has made extensive use of and later grows out of the default/type-based matching rules. For example, an application might have 100 EJBs that might reference the bean of SomeType like so:

@EJB
SomeType bean;

This works fine as long as there is only one bean of type SomeType. The day another bean is added of type SomeType the application will break. If there are 100 references like the above, the only recourse is to create 100 xml overrides or change the code in 100 places. Neither is ideal.

What we need is some syntax to communicate, "when I am not specific, I mean X". Some way to flag or map one of the beans of SomeType as the default. This would allow a second SomeType to be introduced without breaking the existing unnamed SomeType references.

There are a few possible approaches to this syntax. One avenue is xml, allow some way to say "this is the default". Possibly by updating the schema to allow and declarations that only contain a type and not a name, such as:

<ejb-local-ref>
  <local>org.some.awesome.code.SomeType</local>
  <ejb-link>Fred</ejb-link>
</ejb-local-ref>

The intention here would be that this would override all @EJB references to SomeType that do not explicitly set a name. So this reference would be overridden:

@EJB
private SomeType bean;

This reference would not be overridden:

@EJB(name="Sam")
private SomeType bean;

The xml declaration rules would be similar to those of the assembly descriptor, such that more specific declarations always win – i.e. xml declarations that use the name take precedence over declarations that do not.

glassfishrobot commented 11 years ago

Reported by dblevins

glassfishrobot commented 11 years ago

@ljnelson said: Yes, please.

This is a real-world problem that real-world teams face every day.

Sure, it would be nice if at the onset of frantic development everyone had a nice naming scheme ready to go and dutifully and conscientiously named all their tt>@EJB</tt references. Never going to happen.

It doesn't help that most examples in the wild use, simply, tt>@EJB</tt, because they were trying to show ease of development and "fewest number of keystrokes!" as a winning feature.

When you scale up and your customers now say, oh, that's nice, but I'd like to bundle in this other set of EJBs to fill some of those references, it is hard to look them in the eye and tell them they have to change dozens or hundreds of elements.

glassfishrobot commented 11 years ago

@ljnelson said: I did want to add that in our case we have probably hundreds of classes with references in them—I feel that perhaps people are laboring under the delusion that real applications must only have to deal with a few of these things. That is incorrect.

At build/deploy time, we combine them together into different configurations, based on the needs of our customers. There are probably 10 or 20 of these outstanding. Quick: which ones have which references? Your guess is as good as mine without exhaustive research—which the tools of the Java EE ecosystem, incidentally, don't make easy either, but that's a separate feature request.

Again, hundreds of references that might need to be overridden.

So any given application has a collection of dozens of references—sometimes more—that all need assigning.

We need an easy way to be able to say: "All references of this type that are otherwise unqualified need to be assigned this implementation class (this EJB)." The current means of configuring things just doesn't do it. Thanks!

glassfishrobot commented 11 years ago

@arjantijms said: Great proposal!

In addition to the XML avenue, what about expressing on the bean itself that it's the default?

@Stateless(default = true)
public class MyBean implements SomeType {
    // ... }

@Stateless(name = "Sam")
public class MyOtherBean implements SomeType {
    // ... }

Like in David's example above, with those two types on the classpath the following would inject the MyBean implementation:

@EJB
private SomeType bean;

It would be a deployment error if two beans with the same type both had the default attribute set to true, unless XML sorted the situation out.

glassfishrobot commented 7 years ago

This issue was imported from java.net JIRA EJB_SPEC-109