On 3/5/07, Bernhard Huemer <[EMAIL PROTECTED]> wrote:
Hello,
2007/3/5, Craig McClanahan <[EMAIL PROTECTED]>:
>
> Two common scenarios where you might want to override the
> configuration information that was originally specified with
> annotations:
>
> * Third party beans where you don't have the ability
> to modify the sources to meet your requirements.
>
> * Use cases where the annotated configuration is
> default values, but the bean is explicitly designed to
> allow you to customize things (via configuration files).
>
> This pattern is essentially universal across all of Java EE ...
> everything you can specify with annotations can be overridden with
> configuration files. Thus, it made sense to emulate this pattern with
> Shale as well, because Shale users will likely expect the same sorts
> of behaviors.
Don't get me wrong. I'm not saying that I don't want to override the
type of a managed bean, but in that case I would rather replace the
existing bean than to merge the characteristics. This behavior would
be in accord with other Java EE technologies. Consider following
example:
/// EmployeeServiceBean.java
package com.acme;
import javax.ejb.Stateless;
import javax.persistence.PersistenceContext;
@Stateless
public class EmployeeServiceBean implements EmployeeService {
@PersistenceContext
private PersistenceContext employees;
...
}
\\\
/// EmployeeServiceImpl.java
package com.acme;
import javax.annotation.Resource;
import javax.sql.DataSource;
public class EmployeeServiceImpl implements EmployeeService {
@Resource
private DataSource employeeDs;
...
}
\\\
/// ejb-jar.xml
....
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>EmployeeServiceBean</ejb-name>
....
<ejb-class>com.acme.EmployeeServiceImpl</ejb-class>
....
</session>
</enterprise-beans>
</ejb-jar>
\\\
Note that even though the class EmployeeServiceBean expresses a
dependency on a persistence context, the EJB container won't inject
this dependency as the ejb-jar.xml _replaces_ the annotated EJB.
Actually, I don't know exactly what the EJB container internally
really does, but at least no exception will be thrown because of a
missing field 'employees'.
> I don't understand quite what you are saying. Managed bean
> annotations can only be in one place ... on the source code for bean
> classes in your application.
I just wanted to say that one can't know the bean class which defines
the annotations, just from looking at the faces-config.xml. Unlike the
shale-tiger module an EJB container just injects those dependencies
that have been declared in the actual ejb-class (no matter how many
other enterprise beans you define using annotations with the same
ejb-name; see also the example above).
I agree that something like what you are describing is a good long
term direction. But, there is a critical missing piece of
functionality needed to make it work for our managed bean case -- a
syntax for metadata that lets you override just part of the annotated
behavior.
Right now, Tiger use the same DTD/Schema for faces-config.xml
resources that the standard JSF implementation uses. This implies
that, for example, the <managed-bean-class> element is *required* to
have your config resource pass XML validation. This is not what you'd
want if you just want to override one of the value expressions to
inject a customized property.
GIven the restriction of using the existing DTD/Schema, that left me
with two design choices:
* If you specify a managed bean in a faces-config.xml resource,
the entire definition *replaces* any annotation-based definition
for the same managed bean name.
* If you specify a managed bean in faces-config.xml, and you have
defined an annotation based managed bean for the same name,
*some* of the XML stuff is ignored, and *some* of it is used
to override the original settings in the annotations.
The current implementation implements the first approach. Which
approach do you feel causes less confusion? If you like the latter
approach, how do you decide which config elements are overrides, and
which ones should be ignored?
As far as I can tell, the only way to do overrides in a way similar to
the rest of Java EE is to define a new configuration syntax that lets
you explicitly do so. We can go invent such a thing (and if you want
to help do so, we'd definitely be interested in the help) -- but this
is where whatever we do is very likely to get replaced by some future
change to the JSF specification. To say nothing of the risk that
whatever we do might not be possible to support in that future
version.
This is why the functionality works the way it works today.
Personally, I am not really motivated to define our own configuration
format for merging and overriding, but I'm open to suggestions on how
we might be able to accomplish this before a potential future JSF spec
version makes it irrelevant. I'd be much more interested if someone
wanted to offer code as well as ideas in this regard.
Craig
Bernhard Huemer