In Kodo, each factory maintains a set of resources shared by all the 
		EntityManagers or 
		PersistenceManagers produced by that factory.  
		Sharing common structures like connection pools and data caches 
		drastically reduces the resource consumption of each manager,
		increasing your application's scalability.  Kodo takes this concept 
		one step further by also giving its factories the ability to 
		act as servers for PersistenceManagers or
		EntityManagers on remote machines.  You can 
		thus leverage the full JDO or Java Persistence API in your client
		tier without duplicating limited resources like database connections on
		each client.
		
In addition to ensuring that your application scales as more clients are added, this model may allow you to use Kodo in situations where the client machine cannot directly access the necessary server-side resources itself - for example, when the database is only available to the local network.
This remote capability means that you can design your application as a simple two-tiered servlet-database application, and then migrate to a more scalable servlet-Kodo middle tier-database architecture as the load on your system increases. This end picture looks much like a standard J2EE application server architecture, except that the code that uses the persistence APIs in the servlet does not need to change at all to toggle between the more performant two-tier architecture and the more scalable three-tier architecture.
Additionally, Kodo's remote capability is useful for applet and Java Web Start application development. In conjunction with the compressed HTTP transport, you can deploy code that uses standard persistence APIs in an applet or a Web Start application.
		The EntityManagers and 
		PersistenceManagers in these applications 
		will then connect back to the server that they were downloaded from in 
		order to access the database.
		
			To configure a factory act as a standalone server to remote clients,
			the factory's 
			kodo.PersistenceServer configuration 
			property to a plugin string (see 
			Section 2.4, “Plugin Configuration”) describing the 
			
			com.solarmetric.remote.Transport 
			implementation to use for remote communication.  You can implement 
			your own Transport, or use one of the 
			bulit-in options:
			
					false: The default value.  No server is
					started.
					
					tcp: An alias for
					
					com.solarmetric.remote.TCPTransport
					, a TCP transport layer.  This transport layer has 
					the following settings:
					
							Port: The port the server will 
							listen on.  Defaults to 5637.
							
							Host: The host name of the 
							server.  Defaults to localhost.
							This setting is not used by the server, but by 
							clients.  We discuss client configuration below.
							
							SoTimeout: The socket read
							timeout in milliseconds.  Defaults to 0 for no
							timeout.
							
							Decorators: See
							Section 11.2.4, “Data Compression and Filtering”
							
Example 11.2. Configuring a Standalone Persistence Server
JPA XML format:
<property name="kodo.PersistenceServer" value="tcp(Port=5555)"/>
JDO properties format:
kodo.PersistenceServer: tcp(Port=5555)
			The 
			kodo.remote.Remote class
			Javadoc details the methods Kodo exposes for manually managing
			a persistence server thread.
			
Example 11.3. Starting a Persistence Server
After obtaining the server factory for the first time, you must start the server thread. Attempting to start the server thread when it is already running or when there is no persistence server configured will have no effect.
JPA:
import kodo.remote.*;
import org.apache.openjpa.persistence.*;
...
EntityManagerFactory emf = Persistence.createEntityManagerFactory ("kodo");
if (Remote.getInstance (OpenJPAPersistence.toBrokerFactory (emf)).startPersistenceServer ())
    // server started...
else
    // server not started; may have already been running or not configured 
JDO:
import kodo.jdo.*;
...
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory (kodo.properties");
if (((KodoPersistenceManagerFactory) pmf).startPersistenceServer ())
    // server started...
else
    // server not started; may have already been running or not configured 
			Your Kodo distribution also includes a program to start a standalone
			persistence server.  You can run the program through its Java class,
			kodo.jdbc.kernel.StartPersistenceServer, or
			through the provided startserver command-line
			script.  The script accepts the standard Kodo command-line arguments
			outlined in Section 2.3, “Command Line Configuration”.
			
			
			Kodo's remote managers can communicate with the server
			over HTTP, allowing you to use them through firewalls that shut off
			other ports and protocols.  In order to receive HTTP requests from
			remote clients, Kodo includes the
			
			kodo.remote.PersistenceServerServlet
			.  You can deploy this servlet into any standards-compliant
			servlet container.
			
			The PersistenceServerServlet services
			remote requests using an internal factory.  The
			servlet provides several mechanisms for configuring this factory:
			
					First, the servlet checks the value of the 
					kodo.jndi servlet initialization parameter
					(servlet initialization parameters are specified in the
					standard web.xml deployment file; see 
					your servlet container documentation for details).  If the 
					value of this parameter is non-null, Kodo attempts to look 
					up the kodo.kernel.BrokerFactory at 
					the indicated JNDI location.  (A BrokerFactory
					 is the native Kodo component that underlies
					every PersistenceManagerFactory or
					EntityManagerFactory.)
					
					If the kodo.jndi initialization parameter
					is not set, Kodo checks the kodo.properties
					 initialization parameter.  The value of this 
					parameter is a resource path to 
					
					an JPA XML
					
					or
					
					a JDO properties
					
					file containing Kodo configuration properties.
					
Finally, Kodo checks the remainder of the servlet initialization parameters for Kodo configuration properties. These parameter values override the value supplied in the configuration file (if any).
					If you use servlet parameters alone to configure the
					persistence server, Kodo will not know whether to apply JPA 
					or JDO defaults.  Set the
					kodo.Specification servlet parameter to
					ejb or jdo to tell
					Kodo which specification defaults to apply.
					
You can make sure that the servlet's factory is configured as expected by navigating to the servlet in your web browser. The servlet will display a simple web page detailing the configuration of its internal factory.
			Client EntityManagers and 
			PersistenceManagers are remote 
			proxies to server-side managers created by the server-side 
			factory you are communicating with.  From an API standpoint, a 
			client manager is exactly like a local one, complete 
			with all Kodo API extensions.  Behind the scenes, however, the 
			actions you take on a client manager are sent to the 
			corresponding server-side manager for processing.  For 
			performance reasons and because your persistent objects are not 
			proxies themselves, each client manager has a local 
			cache of managed objects, synchronized with the server-side 
			manager's cache. 
			
			You obtain client EntityManagers and 
			PersistenceManagers in 
			the same way you obtain local managers: from an 
			EntityManagerFactory or 
			PersistenceManagerFactory that you have constructed 
			through JCA or the Persistence helper / 
			JDOHelper helper.
			Client configuration properties are the same as those used for 
			local Kodo operation, with the following exceptions:
			
					You must set the
					
					kodo.BrokerFactory property to 
					remote.
					
					The 
					kodo.PersistenceServer setting is
					used to find the remote server.  If you are using a 
					standalone
					server, the value of this property is typically the 
					same as its value on the server.  If you are using the 
					HTTP servlet
					, the value of this property on the client is:
					
http(URL=<servlet-url>)
					http in the setting above is an alias
					for the 
					
					com.solarmetric.remote.HTTPTransport
					, whose URL property indicates
					the URL to connect to.  You can also specify a 
					Decorators property, as discussed in
					Section 11.2.4, “Data Compression and Filtering”.		
					
					The 
					kodo.ConnectionRetainMode property 
					controls how the client handles connections to the server,
					not how the server handles connections to the database.  
					The available values are the same as the options for 
					database connections:
					
							always: Each client manager
							obtains a single connection to its server-side 
							counterpart and uses this connection until it is
							closed.
							
							transaction: A connection is
							obtained when each transaction begins, and 
							relinquished when the transaction completes.
							Nontransactional connections are obtained as needed
							and released immediately.
							
							on-demand: A connection to the
							server is obtained when needed, and immediately
							closed when the request has been fulfilled.  This
							is the default.
							
					
					kodo.ConnectionFactoryProperties controls
					pooling not for database connections, but for connections
					from the client machine to the remote server.  The following
					pooling options are available:
					
							ExceptionAction: The action 
							to take when when a connection that has thrown 
							an exception is returned to the pool.  Set to 
							destroy to destroy the 
							connection. Set to validate to 
							validate the connection (subject to the 
							TestOnReturn, 
							TestOnBorrow, and other test settings).
							Set to none to ignore the fact 
							that the connection has thrown an exception, and 
							assume it is still usable.  Defaults to 
							destroy.
							
							MaxActive: The maximum number of
							connections in use at one time.  Defaults to 8.
							
							MaxIdle: The maximum number of
							idle connections to keep in the pool.  Defaults
							to 8.
							
							MaxWait: The maximum number of
							milliseconds to wait for a free connection to 
							become available before giving up.  Defaults to 
							3000.
							
							MinEvictableIdleTimeMillis: The 
							minimum number of milliseconds that a 
							connection can sit idle before it becomes a 
							candidate for eviction from the pool.  Defaults to 
							30 minutes.  Set to 0 to never evict a connection 
							based on idle time alone.
						
							TestOnBorrow: Whether to to 
							validate connections before obtaining them from the 
							pool.  Defaults to true.
							
							TestOnReturn: Set to 
							true to validate connections 
							when they are returned to the pool.
							
							TestWhileIdle: Set to 
							true to periodically validate 
							idle connections.
							
							TimeBetweenEvictionRunsMillis: 
							The number of milliseconds between runs of the 
							eviction thread.  Defaults to -1, meaning the 
							eviction thread will never run.
							
							ValidationTimeout:
							The minimum number of milliseconds that must elapse 
							before a connection will ever be re-validated.  This
							property is usually used with TestOnBorrow
							 or TestOnReturn to 
							reduce the number of validations performed, because 
							the same connection is often borrowed and returned 
							many times in short periods of time.  Defaults to 
							300000 (5 minutes).
							
							WhenExhaustedAction: The action 
							to take when there are no available connections
							in the pool.  Set to exception to
							immediately throw an exception.  Set to 
							block to block until a connection
							is available or the maximum wait time is exceeded.
							Set to grow to automatically 
							grow the pool.  Defaults to 
							block.
							
					Remember that persistent connections to the server consume
					server-side resources, and therefore should be minimized
					if possible.  To disable pooling altogether, set 
					MaxActive to 0.
					
					Database connectivity and JDBC-related properties are
					ignored by the client factory.  All
					database communication takes place on the server, so these
					properties are only valid on the server-side factory.
					There are, however, two exceptions to
					this rule.  If specified, the client will transfer your 
					local 
					kodo.ConnectionUserName
					 and 
					
					kodo.ConnectionPassword
					 settings to the server. This allows different 
					remote clients to connect as different database users.
					
Other than the bullet points above, you configure client factories in the same way as local factories. Keep in mind, though, that the configuration you specify on the client only applies to the client factory, not the server. For example, if you configure a data cache and query cache on the client, these caches will only "see" changes made by the client; they will not automatically synchronize with changes made by any other client or changes made on the server. Thus, you will typically want to configure components like the data cache, query cache, lock manager, etc. on the server only (where clients can still benefit from them by proxy), and turn them off on the client.
Example 11.5. Client Configuration
JPA XML format:
<property name="kodo.BrokerFactory" value="remote"/> <property name="kodo.PersistenceServer" value="tcp(Host=kodohost.mydomain.com, Port=5555)"/> <property name="kodo.ConnectionRetainMode" value="transaction"/> <property name="kodo.ConnectionFactoryProperties" value="MaxIdle=3, ValidationTimeout=60000"/>
JDO properties format:
kodo.BrokerFactory: remote kodo.PersistenceServer: tcp(Host=kodohost.mydomain.com, Port=5555) kodo.ConnectionRetainMode: transaction kodo.ConnectionFactoryProperties: MaxIdle=3, ValidationTimeout=60000
Example 11.6. HTTP Client Configuration
JPA XML format:
<property name="kodo.BrokerFactory" value="remote"/> <property name="kodo.PersistenceServer" value="http(URL=http://jdohost.mydomain.com/tomcat/pmserver)"/> <property name="kodo.ConnectionRetainMode" value="transaction"/> <property name="kodo.ConnectionFactoryProperties" value="MaxIdle=3, ValidationTimeout=60000"/>
JDO properties format:
kodo.BrokerFactory: remote kodo.PersistenceServer: http(URL=http://jdohost.mydomain.com/tomcat/pmserver) kodo.ConnectionRetainMode: transaction kodo.ConnectionFactoryProperties: MaxIdle=3, ValidationTimeout=60000
			Kodo's built in transport implementations - tcp, 
			http - allow you to wrap their data streams in decorators
			to add additional functionality such as data compression and
			filtering.  Each accepts a Decorators 
			configuration property specifying a semicolon-separated list of 
			
			com.solarmetric.remote.StreamDecorators
			 to decorate the input and output streams between the
			client and server.  Each item in the list can be the full class 
			name of a custom decorator, or one of the following built-in
			aliases:
			
					gzip: Use gzip compression when 
					transferring data.
					
Using Kodo's remote features involves deploying Kodo to the server machine as well as one or more client machines. Deploying Kodo on the server is exactly the same as deploying Kodo for local use. You must include all Kodo libraries, your configuration properties file (if you use one), your logging configuration file (again, if you use one), your JDBC drivers, your enhanced persistent classes, your metadata, and your O/R mapping information. All of these topics are covered in other sections of this manual.
Deploying Kodo on the client is also the same as deploying Kodo for local use, with two small exceptions:
JDBC libraries are not required on the client.
O/R mapping information is not required on the client.
Note that you may include the above information in your deployment; it is simply not required.
			The Kodo remote package provides a mechanism for your application to
			register an object that can listen for transfer events.
			Transfer events take place during flush operations as objects 
			are sent to the server, and when objects are loaded from the server
			by extents, queries, or obtaining objects by id.
			For more details, please see the javadoc for 
			
			kodo.remote.RemoteTransferListener.