Hi,
1. to JDK "bug":
it's not a bug according to Java language Specification:

http://java.sun.com/docs/books/jls/third_edition/html/classes.html#23530

 2. to attributes:
JSF specification states that components have properties (so called renderkit independend), which are getter/setter based AND
 attributes (renderkit dependend).

Maybe we could use it as it says:
- have getter/setter pairs for properties (defined in spec alone) and rest - attributes in HTML renderkit's doc (called as ATTRIBUTES anyway) along with all enhancing TLD tags' attributes - use as keys/values in getAttributes() Map. As all properties are set in stone, this would be one-time work to write them.
Adding attributes would be automaticly handled by Map.

This access would mean to change PROGRAMMATIC access to components from setXXX(val) to getAttributes().put("XXX", val). To switch to this from users' side (when using only in JSF pages) it would mean to rewrite direct setting in tag handlers to use Map.
(Map handles calling setters/getters too if needed/forgotten)

BTW, Mojarra stopped in half way with handling HTML attributes only with Map. Now they have mixed approach - using getter/setter pair BUT accessing value from Map in renderer.

Regards,
 Zdenek

Simon Kitching napsal(a):
Yes, third-party code that tries to use reflection on such a UIComponent to 
access the standard JSF attributes will fail.

The question is whether the TCK will test this (I doubt it), and whether for other cases we care.
One case where it would be significant is if GUI-builders for JSF use 
reflection on UIComponent objects. But if not, then I cannot imagine any other 
case where anyone would actually do that; the attributes map already provides 
access to that info.

It would be really nice to have the same approach for myfaces core as for the 
other modules.

Regards, Simon

---- Martin Marinschek <[EMAIL PROTECTED]> schrieb:
Hi Simon,

this is true - but what happens if someone else tries to access
component attributes via reflection?

regards,

Martin

On 2/8/08, Simon Kitching <[EMAIL PROTECTED]> wrote:
In the practice the problem is that jsf core (myfaces and ri) uses
reflection to set the attributes and the following case fail:

Fail with the following exception

java.lang.IllegalAccessException: Class javax.faces.component._Util can not
access a member of class org.apache.myfaces.test.AbstractComponent with
modifiers "public"
        at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at javax.faces.component._Util.getValue(_Util.java:54)
        at javax.faces.component.BaseComponent.getValueReflection(
BaseComponent.java:32)
        at javax.faces.other.ComponentTest.main(ComponentTest.java:14)

This behavior is a JDK bug:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071957
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4533479

One possible workaround is put the following line before invoke:

            readMethod.setAccessible(true);

Or make AbstractComponent public.

The conclusion is that the abstract base class should be public if and only
if it has in his body a attribute definition available on the tld. If the
abstract base class has some different code it can be package scope. This
behavior discard this approach for myfaces core api!

I'm not sure this behaviour is a bug, or that it is fatal for the purposes
of generating base classes for myfaces-api.

When a Method object refers to a public method in a package-scoped class,
then Method.invoke fails with the above exception *when executed by some
class outside that package*. However it succeeds fine when invoked by code
within that package (eg its concrete subclass) or by the class itself. I
have tested this behaviour and it is the same on both java1.6 and java1.3.
It also seems quite reasonable behaviour.

So one solution is for the generated base class to override getAttributes()
to return a custom map where that class itself implements the fetching of
the attributes it implements, and delegates to the map created by
UIComponentBase.getAttributes() for anything else. This seems quite
feasable.

Regards,
Simon
--
View this message in context:
http://www.nabble.com/Re%3A--Myfaces-Wiki--Update-of-%22Code-Generation%22-by-SimonKitching-tp15216313p15353739.html
Sent from the My Faces - Dev mailing list archive at Nabble.com.


--

http://www.irian.at

Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German

Professional Support for Apache MyFaces


Reply via email to