sca-j message
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]
| [List Home]
Subject: Re: [sca-j] [JAVA-1] Proposed styles of code for the SCAClientFactory
- From: Raymond Feng <rfeng@us.ibm.com>
- To: sca-j@lists.oasis-open.org
- Date: Thu, 19 Feb 2009 09:12:42 -0800
Hi, Mark.
The abstract factory classes seems to
be the widely-used pattern.
But we have encountered various issues
for this pattern in an OSGi-based runtime. First, that the classloader-based
discovery of META-INF/services doesn't work well in OSGi as OSGi has a
network of classloaders instead of a flat one. Passing in the name of the
factory impl class via system property also depends on TCCL or the classloader
of the SCAClientFactory class and it's not OSGi friendly.
I propose that we add a static setter
or field on SCAClientFactory so that a subclass of SCAClientFactory (class
or instance) or an instance of SCAClientFactoryFinder can be injected by
the runtime. Something like:
public abstract class SCAClientFactory
{
private static SCAClientFactory
defaultFactory; // This instance to be injected, if null, the finder will
be used
public static void setDefaultSCAClientFactory(SCAClientFactory
factory) {
defaultFactory
= factory;
}
public abstract SCAClient
createSCAClient();
public static SCAClientFactory
newInstance() {
if(defaultFactory
== null) {
return SCAClientFactoryFinder.find();
} else
{
return defaultFactory;
}
}
}
Two more points:
1) Do we really need to define the algorithm
on how the subclass of the SCAClientFactory is discovered?
2) Should we define if the SCAClientFactory
is thread-safe or not?
Thanks,
Raymond
From:
| "Mark Combellack" <mcombellack@avaya.com>
|
To:
| <sca-j@lists.oasis-open.org>
|
Date:
| 02/18/2009 07:51 AM
|
Subject:
| [sca-j] [JAVA-1] Proposed styles of
code for the SCAClientFactory |
Hi,
I took an action item on Monday’s call to
provide code fragments to show how we could implement the SCAClientFactory
code for creating SCAClient
instances in a standard way but still allow Vendors to plug in Vendor specific
code as required by their runtime.
Overview of the Proposals
I have written up the 4 proposals at the
end of this email and they are:
Proposal 1: Follow style defined by SDO –
instance variable on Interface set by a separate finder class
Proposal 2: Follow style defined by JAXB
– method on abstract class which delegates to a separate finder class
Proposal 3: Follow style defined in Mark’s
proposal – method on concrete class
Proposal 4: Follow style defined in Mark’s
proposal with a tweak from Simon – method on a concrete class which delegates
to a separate finder class
In the following discussion Proposal 3 is
not considered as it has been replaced by Proposal 4
Comparison of the Proposals
In SCA terms, the 3 proposals (1, 2 and 4)
conceptually do the same thing (with a few minor differences in how they
do it). Conceptually, they all:
- Provide a SCAClientFactory
class/interface that is used to create concrete instances of SCAClient
using the SCAClientFactory
- SCAClientFactory
delegates to a separate class for actually creating the concrete instance
of SCAClient
– such as SCAClientFactoryFinder
or HelperProvider
- SCA would provide a reference implementation
of the class that SCAClientFactory
delegates to a for creating the concrete instances of SCAClient
·
The reference
implementation uses System Properties, META-INF/services
and/or ClassLoader to load the Vendor implementation of the SCAClientFactory
- Vendors are able to replace the reference
implementation of the finder with a vendor specific implementation that
will interact with their SCA Runtime as required.
Recommended Approach for moving forward
From these proposals, which one is the best
approach? My thoughts are:
- I think proposal 2 seems the best option
(JAXB style)
- I would suggest that we don’t do proposal
4 (Mark’s custom code) since there is little point in inventing something
new.
- I personally don’t like proposal 2 (SDO)
since it has an instance variable on an interface so I would not do proposal
1.
What does this all mean for SCA? The main
points are listed below:
- SCAClient
is an interface and provided by the SCA Specification.
- SCAClientFactory
is an abstract class and provided by the SCA Specification.
- SCAClientFactory
has a static method called newInstance()
that delegates to the SCAClientFactoryFinder
class for creating the Vendor instance of SCAClientFactory
- The SCA Specification provides a reference
implementation of SCAClientFactoryFinder
that uses a combination of a System Property and META-INF/services
to locate the correct Vendor specific implementation of the
SCAClientFactory
- Vendors MUST subclass SCAClientFactory
and implement the createSCAClient()method.
This will create and return a new instance of the Vendor specific SCAClient
implementation.
- Vendors MAY choose to replace the reference
implementation of SCAClientFactoryFinder
with an alternative implementation which can be tailored to their own SCA
Runtime.
What would the SCA code look like when
following the above recommended approach?
From all of the above, what code would a
SCA User need to write in their code? They would need to write:
SCAClient scaClient = SCAClientFactory.newInstance().createSCAClient();
The SCAClientFactory
would look something like:
public abstract class SCAClientFactory
{
public abstract SCAClient
createSCAClient();
public static SCAClientFactory
newInstance() {
return
SCAClientFactoryFinder.find();
}
}
The SCAClientFactoryFinder
would look something like the following pseudo code:
public class SCAClientFactoryFinder
{
public static SCAClientFactory
find() throws SCARuntimeException {
// First
look in the System Properties
String
vendorImplClass = getVendorImplClassNameFromSystemProperties();
if (vendorImplClass
== null) {
// Secondly look in META-INF/services
vendorImplClass = getVendorImplClassNameFromMETAINFServices();
}
if (vendorImplClass
== null) {
throw new SCARuntimeException("No SCAClientFactory implementation
provided");
}
return
createInstanceOfVendorImplClassFromClassName(vendorImplClass);
}
}
I will be interested in people’s opinion
on this approach. Sorry this email is a bit long but hopefully it will
continue the discussion on JAVA-1.
Thanks,
Mark
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Note: You may want to stop reading here if
you are not really interested in the details of the investigation into
the 4 proposals.
My original write up of the 4 proposals is
shown below. I’ve included in the email for completeness but it is probably
not worth reading it unless you are really interested.
These patterns assume that SCAClient
has the following methods:
public <T> T getService(Class<T>
interfaze, String serviceURI, URI domainURI)
throws
NoSuchServiceException, NoSuchDomainException;
Proposal 1: Follow style defined by SDO
– Instance variable on Interface
SDO uses the concept of an instance variable
on an interface for obtaining the default vendor implementation. In SCA
terms, this would look like:
SCAClient scaClient = SCAClientFactory.INSTANCE.createSCAClient();
In this style SCAClient
and SCAClientFactory
are both interfaces. The SCAClientFactory
interface would look like:
public interface SCAClientFactory
{
SCAClient createSCAClient();
SCAClientFactory INSTANCE
= HelperProvider.getSCAClientFactory();
}
This interface delegates the creation of
the SCAClientFactory
instance to the getSCAClientFactory()
method on HelperProvider
in the impl
package. SDO provides a reference implementation of the HelperProvider
class but Vendors may replace this class with their own implementation.
Following this style, the SCA API should
provide a reference implementation of the HelperProvider
class but Vendors are encourage to replace the class to meet the requirements
of their SCA Runtimes. The SCA Reference implementation of HelperProvider
would search the System Properties and META-INF/services
for the implementation of SCAClientFactory.
As an example, the code for the Tuscany SDO
HelperProvider
can be seen at http://svn.apache.org/viewvc/tuscany/java/sdo/sdo-api/src/main/java/commonj/sdo/impl/HelperProvider.java?view=markup&sortby=date
Proposal 2: Follow style defined by JAXB
– method on abstract interface
In JAXB, the initial JAXBContext
is looked up by calling the newInstance()
method on the abstract JAXBContext
class. The abstract JAXBContext
class delegates to the ContextFinder class that will use the ClassLoaders
to instantiate the Vendor implementation that subclasses JAXBContext. In
SCA terms, this would look like:
SCAClientFactory scaClientFactory =
SCAClientFactory.newInstance();
SCAClient scaClient = scaClientFactory.createSCAClient();
Or combined as one statement:
SCAClient scaClient = SCAClientFactory.newInstance().createSCAClient();
In this style SCAClient
is an interface and SCAClientFactory
is an abstract class. The SCAClientFactory
abstract class would look like:
public abstract class SCAClientFactory
{
public abstract SCAClient
createSCAClient();
public static SCAClientFactory
newInstance() {
return
SCAClientFactoryFinder.find();
}
}
This abstract class delegates the creation
of the SCAClientFactory
instance to the find()
method on SCAClientFactoryFinder.
JAXB provides a reference implementation of the JAXB Finder class but Vendors
may replace this class with their own implementation.
Following this style, the SCA API should
provide a reference implementation of the SCAClientFactoryFinder
class but Vendors are encourage to replace the class to meet the
requirements of their SCA Runtimes. The SCA Reference implementation of
SCAClientFactoryFinder
would search the System Properties and META-INF/services
for the implementation of SCAClientFactory.
Proposal 3: Follow style defined in Mark’s
original code proposal for JAVA-1
Note: This proposal has been superseded by
Proposal 4 below.
The SCAClientFactory
class is responsible for providing the indirection from the user’s generic
SCA code and the vendor’s implementation of the SCA Runtime. The user’s
code will ask it for a SCAClient
via the createSCAClient()
method.
The SCAClientFactory
class provides this indirection to the vendor’s implementation by attempting
to discover the class name of the vendor’s implementation using:
- The org.oasisopen.sca.SCAClientFactory
System Property
- The META-INF/services/org.oasisopen.sca.SCAClientFactory
file.
It is important to note that this class does
not need to be updated by the Vendor to include their implementation. All
the Vendor needs to do is set the System Property or provide the correct
services file
The difference here is that the SCA Specification
provides the definitive implementation of the SCAClientFactory
lookup code and Vendors cannot change this lookup code.
Proposal 4: Follow style defined in Mark’s
original code proposal for JAVA-1 with a tweak from Simon
Simon pointed out that Vendors may want to
override the way that the SCAClientFactory
implementation is discovered. Therefore, the code should be moved into
a separate class in a separate package so that Vendors can override this
class if they wish.
Mark Combellack|
Software Developer|
Avaya |
Eastern Business
Park | St.
Mellons | Cardiff
| CF3
5EA | Voice:
+44 (0) 29 2081 7624 |
mcombellack@avaya.com
[Date Prev]
| [Thread Prev]
| [Thread Next]
| [Date Next]
--
[Date Index]
| [Thread Index]
| [List Home]