gnu.classpath
Class ServiceFactory
A factory for plug-ins that conform to a service provider
interface. This is a general mechanism that gets used by a number
of packages in the Java API. For instance,
CharsetProvider
allows to write custom
encoders and decoders for character sets,
ImageReaderSpi
allows to support custom image
formats, and
PrintService
makes it possible to
write custom printer drivers.
The plug-ins are concrete implementations of the service
provider interface, which is defined as an interface or an abstract
class. The implementation classes must be public and have a public
constructor that takes no arguments.
Plug-ins are usually deployed in JAR files. A JAR that provides
an implementation of a service must declare this in a resource file
whose name is the fully qualified service name and whose location
is the directory
META-INF/services
. This UTF-8 encoded
text file lists, on separate lines, the fully qualified names of
the concrete implementations. Thus, one JAR file can provide an
arbitrary number of implementations for an arbitrary count of
service provider interfaces.
Example
For example, a JAR might provide two implementations of the
service provider interface
org.foo.ThinkService
,
namely
com.acme.QuickThinker
and
com.acme.DeepThinker
. The code for
QuickThinker
woud look as follows:
package com.acme;
/**
* Provices a super-quick, but not very deep implementation of ThinkService.
*/
public class QuickThinker
implements org.foo.ThinkService
{
/**
* Constructs a new QuickThinker. The service factory (which is
* part of the Java environment) calls this no-argument constructor
* when it looks up the available implementations of ThinkService.
*
* <p>Note that an application might query all available
* ThinkService providers, but use just one of them. Therefore,
* constructing an instance should be very inexpensive. For example,
* large data structures should only be allocated when the service
* actually gets used.
*/
public QuickThinker()
{
}
/**
* Returns the speed of this ThinkService in thoughts per second.
* Applications can choose among the available service providers
* based on this value.
*/
public double getSpeed()
{
return 314159.2654;
}
/**
* Produces a thought. While the returned thoughts are not very
* deep, they are generated in very short time.
*/
public Thought think()
{
return null;
}
}
The code for
com.acme.DeepThinker
is left as an
exercise to the reader.
Acme’s
ThinkService
plug-in gets deployed as
a JAR file. Besides the bytecode and resources for
QuickThinker
and
DeepThinker
, it also
contains the text file
META-INF/services/org.foo.ThinkService
:
# Available implementations of org.foo.ThinkService
com.acme.QuickThinker
com.acme.DeepThinker
Thread Safety
It is safe to use
ServiceFactory
from multiple
concurrent threads without external synchronization.
Note for User Applications
User applications that want to load plug-ins should not directly
use
gnu.classpath.ServiceFactory
, because this class
is only available in Java environments that are based on GNU
Classpath. Instead, it is recommended that user applications call
javax.imageio.spi.ServiceRegistry.lookupProviders(Class)
. This API
is actually independent of image I/O, and it is available on every
environment.
clone , equals , extends Object> getClass , finalize , hashCode , notify , notifyAll , toString , wait , wait , wait |
lookupProviders
public static Iterator<E> lookupProviders(Class<T> spi)
Finds service providers that are implementing the specified
Service Provider Interface, using the context class loader
for loading providers.
spi
- the service provider interface which must be
implemented by any loaded service providers.
- an iterator over instances of
spi
.
lookupProviders
public static Iterator<E> lookupProviders(Class<T> spi,
ClassLoader loader)
Finds service providers that are implementing the specified
Service Provider Interface.
On-demand loading: Loading and initializing service
providers is delayed as much as possible. The rationale is that
typical clients will iterate through the set of installed service
providers until one is found that matches some criteria (like
supported formats, or quality of service). In such scenarios, it
might make sense to install only the frequently needed service
providers on the local machine. More exotic providers can be put
onto a server; the server will only be contacted when no suitable
service could be found locally.
Security considerations: Any loaded service providers
are loaded through the specified ClassLoader, or the system
ClassLoader if
classLoader
is
null
. When
lookupProviders
is called,
the current
AccessControlContext
gets recorded. This
captured security context will determine the permissions when
services get loaded via the
next()
method of the
returned
Iterator
.
spi
- the service provider interface which must be
implemented by any loaded service providers.loader
- the class loader that will be used to load the
service providers, or null
for the system class
loader. For using the context class loader, see lookupProviders(Class)
.
- an iterator over instances of
spi
.
lookupProviders
public static Iterator<E> lookupProviders(Class<T> spi,
ClassLoader loader,
boolean error)
Finds service providers that are implementing the specified
Service Provider Interface.
On-demand loading: Loading and initializing service
providers is delayed as much as possible. The rationale is that
typical clients will iterate through the set of installed service
providers until one is found that matches some criteria (like
supported formats, or quality of service). In such scenarios, it
might make sense to install only the frequently needed service
providers on the local machine. More exotic providers can be put
onto a server; the server will only be contacted when no suitable
service could be found locally.
Security considerations: Any loaded service providers
are loaded through the specified ClassLoader, or the system
ClassLoader if
classLoader
is
null
. When
lookupProviders
is called,
the current
AccessControlContext
gets recorded. This
captured security context will determine the permissions when
services get loaded via the
next()
method of the
returned
Iterator
.
spi
- the service provider interface which must be
implemented by any loaded service providers.loader
- the class loader that will be used to load the
service providers, or null
for the system class
loader. For using the context class loader, see lookupProviders(Class)
.error
- true if a ServiceConfigurationError
should be thrown when an error occurs, rather
than it merely being logged.
- an iterator over instances of
spi
.
ServiceFactory.java -- Factory for plug-in services.
Copyright (C) 2004 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version.