dev@javaserverfaces.java.net

Re: InjectionProviders

From: Ed Burns <ed.burns_at_sun.com>
Date: Wed, 3 Jan 2007 11:08:46 -0800

>>>>> On Tue, 02 Jan 2007 10:50:59 -0800, Ryan Lubke <Ryan.Lubke_at_Sun.COM> said:

RL> Thought I would throw this out to see if anyone would care to
RL> comment on some ideas/work I've done on the InjectionProvide system
RL> in the RI.

RL> Currenly, vendors can implement the InjectionProvider interface and
RL> explicitly configure it via a context initialization parameter or
RL> system property.

RL> The above system is fine, however, it's somewhat limiting if I want
RL> to add InjectionProvider implementations for Tomcat6 and Jetty6.
RL> We'd have to document how to configure the provider for their
RL> container. Ideally, it would just work without any steps by the
RL> developer.

RL> To that end, I have the following coded up in my local workspace:

RL> Added a new Abstract class called DiscoverableInjectionProvider that
RL> implements InjectionProvider and provides a static method:

RL> *
RL> ** /**
RL> * @param delegateClass the name of the delegate used by the
RL> * <code>InjectionProvider</code> implementation.
RL> * @return returns <code>true</code> if the
RL> * <code>InjectionProvider</code> instance
RL> * is appropriate for the container its currently
RL> * deployed within, otherwise return <code>false</code>
RL> */
RL> public static boolean isProviderAppropriate(String delegateClass)

This name doesn't feel right at all. What this method is doing is
taking the argument string, which is a FQCN for a class that provides a
resource injection feature (the feature set of which varies from
container to container). After talking to Ryan, I have learned the sun
jsf-impl.jar will have
META-INF/services/com.sun.faces.spi.injectionprovider entries for
Glassfish, Jetty6 and Tomcat6. For entry, the part before the ':' is
really an adapter between whatever is provided by the container, which
is non standardized and may vary, and what is required of a real
InjectionProvider implementation.

Given this information, I think a much more appropriate name is

isInjectionProviderFeatureAvailable

RL> *This method would be called by the InjectionProviderFactory (see
RL> below) to determine if this particular InjectionProvider could be
RL> used. More on the 'delegateClass' argument later.

RL> Modifications to InjectionProviderFactory:

RL> * The factory algorithm will check the following,
RL> in order, to provide the appropriate provider
RL> - If explicitly configured, return that InjectionProvider
RL> - If no explicit configuration, check
RL> META-INF/services/com.sun.faces.spi.injectionprovider.
RL> The format of the entries within the
RL> 'com.sun.faces.spi.injectionprovider file is:
RL> <InjectionProviderImplementation>:<DelegateClass>
RL> So an example for GlassFish would be:
                    
RL> com.sun.faces.vendor.GlassFishInjectionProvider:com.sun.enterprise.InjectionManager

>>>>> On Tue, 02 Jan 2007 13:55:22 -0500, jacob_at_hookom.net said:

JH> It might be worthwhile to abstract this factory one step further and
JH> have a single meta-inf entry for all RI-based Factories:

JH> /META-INF/services/com.sun.faces.spi.factories
JH> com.sun.enterprise.InjectionManager:com.sun.faces.vendor.GlassFishInjectio
JH> some other type: some other implementation

While this is useful and makes sense, it goes against the convention of
having one factory per file, which is the convention used in the jsf-api
for a number of factories. Also, the "one kind of factory per file"
convention is simpler because you can discover the number of kinds of
factories in a jar by a simple jar -tf. Otherwise, you would have to
examine the file itself for multiple factories.

-1 for this idea.

RL> When processing, the factory will split the two, and pass
RL> the <DelegateClass> portion to
RL> DiscoverableInjectionProvider.isProviderAppropriate(String). If it
RL> returns true, then we return this InjectionProvider.

RL> NOTE: Any InjectionProvider declared in the services file
RL> must extends DiscoverableInjectionProvider. The appropriate
RL> messages would be logged if this was not the case

RL> - If no provider is found in the services configuration, check
RL> to see if the PostConstruct and PreDestroy annotations are present,
RL> if so, provide support for those two annotations *only*.

RL> - If no provider has been found at this point, no resource
RL> injection will be provided.

RL> I've tested the above locally, and so far, it all seems to work.

RL> The other part to this issue, is how to handle the build if we
RL> provide these InjectionProvider implementations for other
RL> containers. These providers will obviously be dependent on
RL> container specific classes, so I see a two options:

RL> 1. Have a separate set of targets to build a jsf-ri-iprovider.jar
RL> that is checked into the workspace. When the RI itself is built,
RL> then the classes contained in the jsf-ri-provider.jar would be
RL> included.

Ok

-- 
| ed.burns_at_sun.com  | office: 408 884 9519 OR x31640
| homepage:         | http://purl.oclc.org/NET/edburns/
| aim: edburns0sunw | iim: ed.burns_at_sun.com