You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-dev@db.apache.org by Craig L Russell <Cr...@Sun.COM> on 2007/10/01 23:07:51 UTC

JDOHelper.getPersistenceManagerFactory section

Javadogs,

I've completed the specification update for these methods. Please  
take a look and comment:

Note that this section doesn't exactly match what Matthew has already  
implemented, but really close...

<proposed>
PersistenceManagerFactory methods
The methods in this section provide for bootstrapping the  
PersistenceManagerFactory by configuration according to the  
properties documented in Section 11.1. Users have a choice of  
configuration techniques:
The application provides a Map of properties used to construct a  
PersistenceManagerFactory
The application provides a Map of override properties and the name of  
a resource that are used to construct a PersistenceManagerFactory
The application provides the name of a resource in standard Java  
Properties format whose contents define the properties for the  
PersistenceManagerFactory
The application provides an InputStream in standard Java Properties  
format whose contents define the properties for the  
PersistenceManagerFactory
The application provides a File whose contents are in standard Java  
Properties format which define the properties for the  
PersistenceManagerFactory
The application provides a JNDI name and context in which the name is  
defined
The application provides a resource named META-INF/jdoconfig.xml and  
optionally META-INF/services/javax.jdo.PersistenceManagerFactory  
which contain configuration information
The application provides a resource named META-INF/persistence.xml  
and optionally META-INF/services/ 
javax.persistence.EntityManagerFactory which contain configuration  
information

For the cases of InputStream, File, and resource name, a Properties  
instance is constructed by JDOHelper and passed to one of the  
getPersistenceManagerFactory(Map) methods. When using these  
techniques, each configuration of PersistenceManagerFactory is  
contained in a separate resource, and the propsLoader parameter is  
used only to load the resource to construct the Map. Once the Map  
with configuration information is obtained, the loader is used for  
loading all other resourses, including the persistence.xml,  
jdoconfig.xml, services locators, and PersistenceManagerFactory class.
A8.6-22 [public static
	PersistenceManagerFactory getPersistenceManagerFactory
		(Map props, String name, ClassLoader loader);]
A8.6-23 [public static
	PersistenceManagerFactory getPersistenceManagerFactory
		(Map props, String name);]
These methods create a new copy of the Map parameter, add the  
property “javax.jdo.option.Name” with the value of the name parameter  
and delegate to the corresponding JDOHelper method taking a Map  
parameter.
A8.6-13 [public static
	PersistenceManagerFactory getPersistenceManagerFactory
		(File propsFile);]
A8.6-14 [public static
	PersistenceManagerFactory getPersistenceManagerFactory
		(File propsFile, ClassLoader loader);]
A8.6-17 [public static
	PersistenceManagerFactory getPersistenceManagerFactory
		(InputStream stream);]
A8.6-18 [public static
	PersistenceManagerFactory getPersistenceManagerFactory
		(InputStream stream, ClassLoader loader);]
These methods use the parameter(s) passed as arguments to construct a  
Properties instance, and then delegate to the JDOHelper method  
getPersistenceManagerFactory that takes a Map parameter.
A8.6-15 [public static
	PersistenceManagerFactory getPersistenceManagerFactory
		(String propsResourceName);]
A8.6-16 [public static
	PersistenceManagerFactory getPersistenceManagerFactory
		(String propsResourceName, ClassLoader loader);]
A8.6-21[public static
	PersistenceManagerFactory getPersistenceManagerFactory
		(String propsResourceName, ClassLoader propsLoader,
			ClassLoader pmfLoader);]
These methods use the propsLoader getResourceAsStream method with the  
propsResourceName as an argument to obtain an InputStream, construct  
a new Properties instance, then delegate to the corresponding  
JDOHelper method getPersistenceManagerFactory that takes a Map  
parameter.
If the named resource does not exist, JDOHelper constructs a new Map,  
adds a property named “javax.jdo.option.Name” with the value of the  
propsResourceName parameter, and then delegates to the corresponding  
JDOHelper method taking a Map parameter. The empty string (not a null  
string) identifies the default PersistenceManagerFactory name.
A8.6-2 [public static
	PersistenceManagerFactory getPersistenceManagerFactory
		(Map props);]
A8.6-3 [This method delegates to the corresponding method with a  
class loader parameter, using the calling thread’s current  
contextClassLoader as the class loader.]
A8.6-1 [public static
	PersistenceManagerFactory getPersistenceManagerFactory
		(Map props, ClassLoader loader);]
This method returns a PersistenceManagerFactory based on entries  
contained in the Map parameter. Three map entries are significant to  
the processing of this method:
javax.jdo.option.PersistenceUnitName: If not null, this identifies  
the name of the persistence unit to be accessed. The  
Persistence.createEntityManagerFactory method is called with the  
props and PersistenceUnitName as parameters. The result is cast to  
PersistenceManagerFactory and returned to the user.
javax.jdo.option.Name: If not null, this identifies the name of the  
PersistenceManagerFactory listed in jdoconfig. The class loader loads  
META-INF/jdoconfig.xml and finds the PersistenceManagerFactory by  
name. If the value of the entry javax.jdo.option.Name is the empty  
string, this identifies the unnamed PersistenceManagerFactory listed  
in jdoconfig. JDOHelper constructs a Map instance with the contents  
of the jdoconfig entry and overrides its contents with the props  
parameter. Processing continues with PersistenceManagerFactoryClass.
javax.jdo.PersistenceManagerFactoryClass:
If not null, this identifies the name of the  
PersistenceManagerFactory class. JDOHelper uses the loader to resolve  
the PersistenceManagerFactory class name.A8.6-6 [If the class named  
by the PersistenceManagerFactoryClass property cannot be found, or is  
not accessible to the user, then JDOFatalUserException is thrown.]  
JDOHelper invokes the static method getPersistenceManagerFactory in  
the named class, passing the props as the parameter. A8.6-7 [If there  
is no public static implementation of the getPersistenceManagerFactory 
(Map) method, ]A8.6-5 [or if there are any exceptions while trying to  
call the static method,] A8.6-8 [or if the implementation of the  
static getPersistenceManagerFactory(Map) method throws an exception,  
then JDOFatalInternalException is thrown]. The nested exception  
indicates the root cause of the exception.
If null, JDOHelper loads the PersistenceManagerFactory class using  
the services lookup pattern. That is, resources named META-INF/ 
services/PersistenceManagerFactory are loaded by the loader and each  
class in turn is used to call its static getPersistenceManagerFactory  
method, passing the props as the parameter. If one of the resources  
succeeds in returning a non-null PersistenceManagerFactory, it is  
returned to the user and any exceptions (thrown by other resources)  
are ignored. If no resource succeeds, JDOFatalUserException exception  
is thrown to the user, with a nested exception for each failure.
The standard key values for the properties are found in Section 11.1.
JDO implementations are permitted to define key values of their own.  
A8.6-9 [Any key values not recognized by the implementation must be  
ignored.] A8.6-10 [Key values that are recognized but not supported  
by an implementation must result in a JDOFatalUserException thrown by  
the method.]
A8.6-11 [The returned PersistenceManagerFactory is not configurable  
(the setXXX methods will throw an exception).] A8.6-12 [JDO  
implementations might manage a map of instantiated  
PersistenceManagerFactory instances based on specified property key  
values, and return a previously instantiated  
PersistenceManagerFactory instance. In this case, the properties of  
the returned instance must exactly match the requested properties.]
A8.6-19 [public static
	PersistenceManagerFactory getPersistenceManagerFactory
		(String jndiLocation, Context context);]
A8.6-20 [@deprecated public static
	PersistenceManagerFactory getPersistenceManagerFactory
		(String jndiLocation, Context context, ClassLoader loader);]
These methods look up the PersistenceManagerFactory using the naming  
context and name supplied. The implementation’s factory method is not  
called. The behavior of this method depends on the implementation of  
the context and its interaction with the saved  
PersistenceManagerFactory object. As with the other factory methods,  
the returned PersistenceManagerFactory is not configurable.
</proposed>

Craig Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!


Re: JDOHelper.getPersistenceManagerFactory section

Posted by Craig L Russell <Cr...@Sun.COM>.
Hi Matthew,

On Oct 9, 2007, at 11:18 PM, Matthew Adams wrote:

> Note:  I created a JIRA issue, JDO-545, for this.  This email is  
> just a copy of it...
>
> <property-overrides.01.patch>
> See my changes inline below, enclosed by "<<<" and ">>>", and my  
> comments.
>
> -matthew
>
> On Oct 1, 2007, at 2:07 PM, Craig L Russell wrote:
>
>> Javadogs,
>>
>> I've completed the specification update for these methods. Please  
>> take a look and comment:
>>
>> Note that this section doesn't exactly match what Matthew has  
>> already implemented, but really close...
>>
>> <proposed>
>> PersistenceManagerFactory methods
>> The methods in this section provide for bootstrapping the  
>> PersistenceManagerFactory by configuration according to the  
>> properties documented in Section 11.1. Users have a choice of  
>> configuration techniques:
>> The application provides a Map of properties used to construct a  
>> PersistenceManagerFactory
> The application provides a Map of override properties and <<<the  
> name of a resource in standard Java Properties format, the name of  
> a named PersistenceManagerFactory, or a JPA persistence unit  
> name>>> that are used to construct a PersistenceManagerFactory

ok, but same wording also applies to the following bullet.

>> The application provides the name of a resource in standard Java  
>> Properties format whose contents define the properties for the  
>> PersistenceManagerFactory
>> The application provides an InputStream in standard Java  
>> Properties format whose contents define the properties for the  
>> PersistenceManagerFactory
>> The application provides a File whose contents are in standard  
>> Java Properties format which define the properties for the  
>> PersistenceManagerFactory
>> The application provides a JNDI name and context in which the name  
>> is defined
>> The application provides a resource named META-INF/jdoconfig.xml  
>> and optionally META-INF/services/ 
>> javax.jdo.PersistenceManagerFactory which contain configuration  
>> information
>> The application provides a resource named META-INF/persistence.xml  
>> and optionally META-INF/services/ 
>> javax.persistence.EntityManagerFactory which contain configuration  
>> information
>>
> For the cases of InputStream, File, and resource name, a Properties  
> instance is constructed by JDOHelper and passed to one of the  
> getPersistenceManagerFactory(Map) methods. When using these  
> techniques, each configuration of PersistenceManagerFactory is  
> contained <<<either in a Java Properties resource, in a META-INF/ 
> jdoconfig.xml and optionally a META-INF/services/ 
> javax.jdo.PersistenceManagerFactory, or in a META-INF/ 
> persistence.xml and optionally a META-INF/services/ 
> javax.persistence.EntityManagerFactory.  The >>> propsLoader  
> parameter is used only to load the resource to construct the Map.  
> Once the Map with configuration information is obtained, the loader  
> is used for loading all other resour<<<c>>>es,
>
> Comment:  I'm confused about what the "propsLoader" and the  
> "loader" are.  I'll assume the "propsLoader" is the ClassLoader  
> used to load resources required to build the Properties instance  
> (aka "Map"), and the "loader" is the ClassLoader used to load  
> classes and whatever other resources whose loading can't be  
> controlled.

The propsLoader is used only to convert the resource name to a  
Properties instance via getResourceAsStream. Once you have a  
Properties, the propsLoader isn't used any more.
>
>> including the persistence.xml, jdoconfig.xml, services locators,  
>> and PersistenceManagerFactory class.
>
> Comment:  This is not true; some of these resources are loaded by  
> propsLoader, some are not.  If all native JDO means of creating a  
> Properties instance (aka "Map") fail, we delegate to  
> javax.persistence.Persistence, and we can't tell  
> Persistence.createEntityManagerFactory(..) which ClassLoader to use  
> for resource loading and which to use for class loading; in fact,  
> we can't tell it anything about which ClassLoader(s) to use.

Right. I'll update this section.
>
> In order to build the Properties instance (aka "Map"), the  
> following resources are loaded by the propsLoader:  the Java  
> Properties resource with the given name, and if that's not found,  
> all META-INF/jdoconfig.xml files on the classpath.  If, after  
> constructing a Properties instance there is no  
> javax.jdo.PersistenceManagerFactoryClass property, then the  
> propsLoader is used again to load a META-INF/services/ 
> javax.jdo.PersistenceManagerFactory; the exact one is determined by  
> ClassLoader's getResourceAsStream(String) method.  If no META-INF/ 
> jdoconfig.xml files are found or no PersistenceManagerFactory is  
> found with the requested name, then JDOHelper delegates to  
> javax.persistence.Persistence.createEntityManagerFactory(String) to  
> look up the META-INF/persistence.xml file with the persistence unit  
> name given, then casts the returned EntityManagerFactory to a  
> PersistenceManagerFactory.
>
>> A8.6-22 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(Map props, String name, ClassLoader loader);]
>> A8.6-23 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(Map props, String name);]
>> These methods create a new copy of the Map parameter, add the  
>> property “javax.jdo.option.Name” with the value of the name  
>> parameter and delegate to the corresponding JDOHelper method  
>> taking a Map parameter.
>
> Comment:  This is new and not yet coded.  I understand the  
> motivation to add these methods (which is  
> Persistence.createEntityManagerFactory(String,Map)), so I'm cool  
> with adding these, but we'll have to tighten up the description of  
> the overriding Properties, especially in the case that no Java  
> Properties resource is found and the named PMF is not found.  Do we  
> pass the given Map down to Persistence.createEntityManagerFactory 
> (String,Map)?  I am inclined to say yes (see end comments plus the  
> patch).
>
>> A8.6-13 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(File propsFile);]
>> A8.6-14 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(File propsFile, ClassLoader loader);]
>> A8.6-17 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(InputStream stream);]
>> A8.6-18 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(InputStream stream, ClassLoader loader);]
>> These methods use the parameter(s) passed as arguments to  
>> construct a Properties instance, and then delegate to the  
>> JDOHelper method getPersistenceManagerFactory that takes a Map  
>> parameter.
>> A8.6-15 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(String propsResourceName);]
>> A8.6-16 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(String propsResourceName, ClassLoader loader);]
>> A8.6-21[public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(String propsResourceName, ClassLoader propsLoader,
>> 			ClassLoader pmfLoader);]
>> These methods use the propsLoader getResourceAsStream method with  
>> the propsResourceName as an argument to obtain an InputStream,  
>> construct a new Properties instance, then delegate to the  
>> corresponding JDOHelper method getPersistenceManagerFactory that  
>> takes a Map parameter.
>
> Comment:  Correct.
>
>> If the named resource does not exist, JDOHelper constructs a new  
>> Map, adds a property named “javax.jdo.option.Name” with the value  
>> of the propsResourceName parameter, and then delegates to the  
>> corresponding JDOHelper method taking a Map parameter.
>
> Comment:  Minor detail (see below).  JDOHelper conveniently  
> converts a null name to an empty string.
>
>> The empty string (not a null string) identifies the default  
>> PersistenceManagerFactory name.
>
> Comment:  JDOHelper's gerPersistenceManagerFactory(String 
> [,ClassLoader[,ClassLoader]]) methods treat the empty string and a  
> null string equally.  Officially, the empty string is the name of  
> the anonymous or unnamed PMF; null strings are just converted to  
> empty strings for convenience.  We should probably add a constant  
> ANONYMOUS_PERSISTENCE_MANAGER_FACTOR_NAME (or  
> UNNAMED_PERSISTENCE_MANAGER_FACTORY_NAME) String with the value ""  
> to javax.jdo.Constants just so that it's explicit in the code.   
> What do you think?

I just want to make sure that we don't accidentally mix up the user  
setting the property and us setting it and getting confused.
>
>> A8.6-2 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(Map props);]
>> A8.6-3 [This method delegates to the corresponding method with a  
>> class loader parameter, using the calling thread’s current  
>> contextClassLoader as the class loader.]
>> A8.6-1 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(Map props, ClassLoader loader);]
>> This method returns a PersistenceManagerFactory based on entries  
>> contained in the Map parameter. Three map entries are significant  
>> to the processing of this method:
>> javax.jdo.option.PersistenceUnitName: If not null, this identifies  
>> the name of the persistence unit to be accessed. The  
>> Persistence.createEntityManagerFactory method is called with the  
>> props and PersistenceUnitName as parameters. The result is cast to  
>> PersistenceManagerFactory and returned to the user.
>> javax.jdo.option.Name: If not null, this identifies the name of  
>> the PersistenceManagerFactory listed in jdoconfig. The class  
>> loader loads META-INF/jdoconfig.xml and finds the  
>> PersistenceManagerFactory by name. If the value of the entry  
>> javax.jdo.option.Name is the empty string, this identifies the  
>> unnamed PersistenceManagerFactory listed in jdoconfig. JDOHelper  
>> constructs a Map instance with the contents of the jdoconfig entry  
>> and overrides its contents with the props parameter. Processing  
>> continues with PersistenceManagerFactoryClass.
>> javax.jdo.PersistenceManagerFactoryClass:
>> If not null, this identifies the name of the  
>> PersistenceManagerFactory class. JDOHelper uses the loader to  
>> resolve the PersistenceManagerFactory class name.
>> A8.6-6 [If the class named by the PersistenceManagerFactoryClass  
>> property cannot be found, or is not accessible to the user, then  
>> JDOFatalUserException is thrown.] JDOHelper invokes the static  
>> method getPersistenceManagerFactory in the named class, passing  
>> the props as the parameter. A8.6-7 [If there is no public static  
>> implementation of the getPersistenceManagerFactory(Map) method, ] 
>> A8.6-5 [or if there are any exceptions while trying to call the  
>> static method,] A8.6-8 [or if the implementation of the static  
>> getPersistenceManagerFactory(Map) method throws an exception, then  
>> JDOFatalInternalException is thrown]. The nested exception  
>> indicates the root cause of the exception.
>
> Comment:  Correct so far.
>
>> If null, JDOHelper loads the PersistenceManagerFactory class using  
>> the services lookup pattern. That is, resources named META-INF/ 
>> services/javax.jdo.PersistenceManagerFactory are loaded by the  
>> loader and each class in turn is used to call its static  
>> getPersistenceManagerFactory method, passing the props as the  
>> parameter. If one of the resources succeeds in returning a non- 
>> null PersistenceManagerFactory, it is returned to the user and any  
>> exceptions (thrown by other resources) are ignored. If no resource  
>> succeeds, JDOFatalUserException exception is thrown to the user,  
>> with a nested exception for each failure.
>
> Comment:  The implementation only attempts to find one resource  
> named META-INF/services/javax.jdo/PersistenceManagerFactory (via  
> ClassLoader's getResourceAsStream(String) method), not all of  
> them.  Are you suggesting that we change this?
>
>> The standard key values for the properties are found in Section 11.1.
>
> Comment:  To implement support for user-supplied, property- 
> overriding Maps, I suggest that we make the existing methods
>
> getPersistenceManagerFactory(String name)
> getPersistenceManagerFactory(String name, ClassLoader resourceLoader)
> getPersistenceManagerFactory(String name, ClassLoader  
> resourceLoader, ClassLoader pmfLoader)
>
> and the new methods
>
> getPersistenceManagerFactory(Map overrides, String name)
> getPersistenceManagerFactory(Map overrides, String name,  
> ClassLoader resourceLoader)
>
> convenience methods that delegate to the meaty method
>
> getPersistenceManagerFactory(Map overrides, String name,  
> ClassLoader resourceLoader, ClassLoader pmfLoader)
>
> If I understand all of this correctly, then the last operation of  
> this method before delegating to
> getPersistenceManagerFactory(Map props, ClassLoader resourceLoader,  
> ClassLoader pmfLoader)
> is to replace any values in props with values from overrides.  If  
> this method ends up delegating instead to  
> Persistence.createEntityManagerFactory(String,Map), then it will  
> pass the overriding properties as the Map in that method.
>
> I implemented this while going through this post.  Please review  
> the attached patch to make sure that I got it right.

I'll take a closer look tomorrow. But the idea of adding a meaty  
method is fine. Just worried about the "not-specified" null versus  
empty issue.
>
> Note that it is only in JDOHelper's getPersistenceManagerFactory 
> (Map props, ClassLoader resourceLoader, ClassLoader pmfLoader  
> method that META-INF/services lookup is used, and then only when  
> there is no javax.jdo.PersistenceManagerFactoryClass property in  
> props!

Yup.

Craig
>
>
>> JDO implementations are permitted to define key values of their  
>> own. A8.6-9 [Any key values not recognized by the implementation  
>> must be ignored.] A8.6-10 [Key values that are recognized but not  
>> supported by an implementation must result in a  
>> JDOFatalUserException thrown by the method.]
>> A8.6-11 [The returned PersistenceManagerFactory is not  
>> configurable (the setXXX methods will throw an exception).]  
>> A8.6-12 [JDO implementations might manage a map of instantiated  
>> PersistenceManagerFactory instances based on specified property  
>> key values, and return a previously instantiated  
>> PersistenceManagerFactory instance. In this case, the properties  
>> of the returned instance must exactly match the requested  
>> properties.]
>> A8.6-19 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(String jndiLocation, Context context);]
>> A8.6-20 [@deprecated public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(String jndiLocation, Context context, ClassLoader loader);]
>> These methods look up the PersistenceManagerFactory using the  
>> naming context and name supplied. The implementation’s factory  
>> method is not called. The behavior of this method depends on the  
>> implementation of the context and its interaction with the saved  
>> PersistenceManagerFactory object. As with the other factory  
>> methods, the returned PersistenceManagerFactory is not configurable.
>> </proposed>
>>
>> Craig Russell
>> Architect, Sun Java Enterprise System http://java.sun.com/products/ 
>> jdo
>> 408 276-5638 mailto:Craig.Russell@sun.com
>> P.S. A good JDO? O, Gasp!
>>
>

Craig Russell
Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!


Re: JDOHelper.getPersistenceManagerFactory section

Posted by Matthew Adams <ma...@matthewadams.org>.
I thought the list server might drop the patch.  See JDO-545 for it.

-matthew

On Oct 9, 2007, at 11:18 PM, Matthew Adams wrote:

> Note:  I created a JIRA issue, JDO-545, for this.  This email is  
> just a copy of it...
>
> See my changes inline below, enclosed by "<<<" and ">>>", and my  
> comments.
>
> -matthew
>
> On Oct 1, 2007, at 2:07 PM, Craig L Russell wrote:
>
>> Javadogs,
>>
>> I've completed the specification update for these methods. Please  
>> take a look and comment:
>>
>> Note that this section doesn't exactly match what Matthew has  
>> already implemented, but really close...
>>
>> <proposed>
>> PersistenceManagerFactory methods
>> The methods in this section provide for bootstrapping the  
>> PersistenceManagerFactory by configuration according to the  
>> properties documented in Section 11.1. Users have a choice of  
>> configuration techniques:
>> The application provides a Map of properties used to construct a  
>> PersistenceManagerFactory
>> The application provides a Map of override properties and <<<the  
>> name of a resource in standard Java Properties format, the name of  
>> a named PersistenceManagerFactory, or a JPA persistence unit  
>> name>>> that are used to construct a PersistenceManagerFactory
>> The application provides the name of a resource in standard Java  
>> Properties format whose contents define the properties for the  
>> PersistenceManagerFactory
>> The application provides an InputStream in standard Java  
>> Properties format whose contents define the properties for the  
>> PersistenceManagerFactory
>> The application provides a File whose contents are in standard  
>> Java Properties format which define the properties for the  
>> PersistenceManagerFactory
>> The application provides a JNDI name and context in which the name  
>> is defined
>> The application provides a resource named META-INF/jdoconfig.xml  
>> and optionally META-INF/services/ 
>> javax.jdo.PersistenceManagerFactory which contain configuration  
>> information
>> The application provides a resource named META-INF/persistence.xml  
>> and optionally META-INF/services/ 
>> javax.persistence.EntityManagerFactory which contain configuration  
>> information
>>
>> For the cases of InputStream, File, and resource name, a  
>> Properties instance is constructed by JDOHelper and passed to one  
>> of the getPersistenceManagerFactory(Map) methods. When using these  
>> techniques, each configuration of PersistenceManagerFactory is  
>> contained <<<either in a Java Properties resource, in a META-INF/ 
>> jdoconfig.xml and optionally a META-INF/services/ 
>> javax.jdo.PersistenceManagerFactory, or in a META-INF/ 
>> persistence.xml and optionally a META-INF/services/ 
>> javax.persistence.EntityManagerFactory.  The >>> propsLoader  
>> parameter is used only to load the resource to construct the Map.  
>> Once the Map with configuration information is obtained, the  
>> loader is used for loading all other resour<<<c>>>es,
>
> Comment:  I'm confused about what the "propsLoader" and the  
> "loader" are.  I'll assume the "propsLoader" is the ClassLoader  
> used to load resources required to build the Properties instance  
> (aka "Map"), and the "loader" is the ClassLoader used to load  
> classes and whatever other resources whose loading can't be  
> controlled.
>
>> including the persistence.xml, jdoconfig.xml, services locators,  
>> and PersistenceManagerFactory class.
>
> Comment:  This is not true; some of these resources are loaded by  
> propsLoader, some are not.  If all native JDO means of creating a  
> Properties instance (aka "Map") fail, we delegate to  
> javax.persistence.Persistence, and we can't tell  
> Persistence.createEntityManagerFactory(..) which ClassLoader to use  
> for resource loading and which to use for class loading; in fact,  
> we can't tell it anything about which ClassLoader(s) to use.
>
> In order to build the Properties instance (aka "Map"), the  
> following resources are loaded by the propsLoader:  the Java  
> Properties resource with the given name, and if that's not found,  
> all META-INF/jdoconfig.xml files on the classpath.  If, after  
> constructing a Properties instance there is no  
> javax.jdo.PersistenceManagerFactoryClass property, then the  
> propsLoader is used again to load a META-INF/services/ 
> javax.jdo.PersistenceManagerFactory; the exact one is determined by  
> ClassLoader's getResourceAsStream(String) method.  If no META-INF/ 
> jdoconfig.xml files are found or no PersistenceManagerFactory is  
> found with the requested name, then JDOHelper delegates to  
> javax.persistence.Persistence.createEntityManagerFactory(String) to  
> look up the META-INF/persistence.xml file with the persistence unit  
> name given, then casts the returned EntityManagerFactory to a  
> PersistenceManagerFactory.
>
>> A8.6-22 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(Map props, String name, ClassLoader loader);]
>> A8.6-23 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(Map props, String name);]
>> These methods create a new copy of the Map parameter, add the  
>> property “javax.jdo.option.Name” with the value of the name  
>> parameter and delegate to the corresponding JDOHelper method  
>> taking a Map parameter.
>
> Comment:  This is new and not yet coded.  I understand the  
> motivation to add these methods (which is  
> Persistence.createEntityManagerFactory(String,Map)), so I'm cool  
> with adding these, but we'll have to tighten up the description of  
> the overriding Properties, especially in the case that no Java  
> Properties resource is found and the named PMF is not found.  Do we  
> pass the given Map down to Persistence.createEntityManagerFactory 
> (String,Map)?  I am inclined to say yes (see end comments plus the  
> patch).
>
>> A8.6-13 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(File propsFile);]
>> A8.6-14 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(File propsFile, ClassLoader loader);]
>> A8.6-17 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(InputStream stream);]
>> A8.6-18 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(InputStream stream, ClassLoader loader);]
>> These methods use the parameter(s) passed as arguments to  
>> construct a Properties instance, and then delegate to the  
>> JDOHelper method getPersistenceManagerFactory that takes a Map  
>> parameter.
>> A8.6-15 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(String propsResourceName);]
>> A8.6-16 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(String propsResourceName, ClassLoader loader);]
>> A8.6-21[public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(String propsResourceName, ClassLoader propsLoader,
>> 			ClassLoader pmfLoader);]
>> These methods use the propsLoader getResourceAsStream method with  
>> the propsResourceName as an argument to obtain an InputStream,  
>> construct a new Properties instance, then delegate to the  
>> corresponding JDOHelper method getPersistenceManagerFactory that  
>> takes a Map parameter.
>
> Comment:  Correct.
>
>> If the named resource does not exist, JDOHelper constructs a new  
>> Map, adds a property named “javax.jdo.option.Name” with the value  
>> of the propsResourceName parameter, and then delegates to the  
>> corresponding JDOHelper method taking a Map parameter.
>
> Comment:  Minor detail (see below).  JDOHelper conveniently  
> converts a null name to an empty string.
>
>> The empty string (not a null string) identifies the default  
>> PersistenceManagerFactory name.
>
> Comment:  JDOHelper's gerPersistenceManagerFactory(String 
> [,ClassLoader[,ClassLoader]]) methods treat the empty string and a  
> null string equally.  Officially, the empty string is the name of  
> the anonymous or unnamed PMF; null strings are just converted to  
> empty strings for convenience.  We should probably add a constant  
> ANONYMOUS_PERSISTENCE_MANAGER_FACTOR_NAME (or  
> UNNAMED_PERSISTENCE_MANAGER_FACTORY_NAME) String with the value ""  
> to javax.jdo.Constants just so that it's explicit in the code.   
> What do you think?
>
>> A8.6-2 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(Map props);]
>> A8.6-3 [This method delegates to the corresponding method with a  
>> class loader parameter, using the calling thread’s current  
>> contextClassLoader as the class loader.]
>> A8.6-1 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(Map props, ClassLoader loader);]
>> This method returns a PersistenceManagerFactory based on entries  
>> contained in the Map parameter. Three map entries are significant  
>> to the processing of this method:
>> javax.jdo.option.PersistenceUnitName: If not null, this identifies  
>> the name of the persistence unit to be accessed. The  
>> Persistence.createEntityManagerFactory method is called with the  
>> props and PersistenceUnitName as parameters. The result is cast to  
>> PersistenceManagerFactory and returned to the user.
>> javax.jdo.option.Name: If not null, this identifies the name of  
>> the PersistenceManagerFactory listed in jdoconfig. The class  
>> loader loads META-INF/jdoconfig.xml and finds the  
>> PersistenceManagerFactory by name. If the value of the entry  
>> javax.jdo.option.Name is the empty string, this identifies the  
>> unnamed PersistenceManagerFactory listed in jdoconfig. JDOHelper  
>> constructs a Map instance with the contents of the jdoconfig entry  
>> and overrides its contents with the props parameter. Processing  
>> continues with PersistenceManagerFactoryClass.
>> javax.jdo.PersistenceManagerFactoryClass:
>> If not null, this identifies the name of the  
>> PersistenceManagerFactory class. JDOHelper uses the loader to  
>> resolve the PersistenceManagerFactory class name.
>> A8.6-6 [If the class named by the PersistenceManagerFactoryClass  
>> property cannot be found, or is not accessible to the user, then  
>> JDOFatalUserException is thrown.] JDOHelper invokes the static  
>> method getPersistenceManagerFactory in the named class, passing  
>> the props as the parameter. A8.6-7 [If there is no public static  
>> implementation of the getPersistenceManagerFactory(Map) method, ] 
>> A8.6-5 [or if there are any exceptions while trying to call the  
>> static method,] A8.6-8 [or if the implementation of the static  
>> getPersistenceManagerFactory(Map) method throws an exception, then  
>> JDOFatalInternalException is thrown]. The nested exception  
>> indicates the root cause of the exception.
>
> Comment:  Correct so far.
>
>> If null, JDOHelper loads the PersistenceManagerFactory class using  
>> the services lookup pattern. That is, resources named META-INF/ 
>> services/<<<javax.jdo.>>>PersistenceManagerFactory are loaded by  
>> the loader and each class in turn is used to call its static  
>> getPersistenceManagerFactory method, passing the props as the  
>> parameter. If one of the resources succeeds in returning a non- 
>> null PersistenceManagerFactory, it is returned to the user and any  
>> exceptions (thrown by other resources) are ignored. If no resource  
>> succeeds, JDOFatalUserException exception is thrown to the user,  
>> with a nested exception for each failure.
>
> Comment:  The implementation only attempts to find one resource  
> named META-INF/services/javax.jdo/PersistenceManagerFactory (via  
> ClassLoader's getResourceAsStream(String) method), not all of  
> them.  Are you suggesting that we change this?
>
>> The standard key values for the properties are found in Section 11.1.
>
> Comment:  To implement support for user-supplied, property- 
> overriding Maps, I suggest that we make the existing methods
>
> getPersistenceManagerFactory(String name)
> getPersistenceManagerFactory(String name, ClassLoader resourceLoader)
> getPersistenceManagerFactory(String name, ClassLoader  
> resourceLoader, ClassLoader pmfLoader)
>
> and the new methods
>
> getPersistenceManagerFactory(Map overrides, String name)
> getPersistenceManagerFactory(Map overrides, String name,  
> ClassLoader resourceLoader)
>
> convenience methods that delegate to the meaty method
>
> getPersistenceManagerFactory(Map overrides, String name,  
> ClassLoader resourceLoader, ClassLoader pmfLoader)
>
> If I understand all of this correctly, then the last operation of  
> this method before delegating to
> getPersistenceManagerFactory(Map props, ClassLoader resourceLoader,  
> ClassLoader pmfLoader)
> is to replace any values in props with values from overrides.  If  
> this method ends up delegating instead to  
> Persistence.createEntityManagerFactory(String,Map), then it will  
> pass the overriding properties as the Map in that method.
>
> I implemented this while going through this post.  Please review  
> the attached patch to make sure that I got it right.
>
> Note that it is only in JDOHelper's getPersistenceManagerFactory 
> (Map props, ClassLoader resourceLoader, ClassLoader pmfLoader  
> method that META-INF/services lookup is used, and then only when  
> there is no javax.jdo.PersistenceManagerFactoryClass property in  
> props!
>
>
>> JDO implementations are permitted to define key values of their  
>> own. A8.6-9 [Any key values not recognized by the implementation  
>> must be ignored.] A8.6-10 [Key values that are recognized but not  
>> supported by an implementation must result in a  
>> JDOFatalUserException thrown by the method.]
>> A8.6-11 [The returned PersistenceManagerFactory is not  
>> configurable (the setXXX methods will throw an exception).]  
>> A8.6-12 [JDO implementations might manage a map of instantiated  
>> PersistenceManagerFactory instances based on specified property  
>> key values, and return a previously instantiated  
>> PersistenceManagerFactory instance. In this case, the properties  
>> of the returned instance must exactly match the requested  
>> properties.]
>> A8.6-19 [public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(String jndiLocation, Context context);]
>> A8.6-20 [@deprecated public static
>> 	PersistenceManagerFactory getPersistenceManagerFactory
>> 		(String jndiLocation, Context context, ClassLoader loader);]
>> These methods look up the PersistenceManagerFactory using the  
>> naming context and name supplied. The implementation’s factory  
>> method is not called. The behavior of this method depends on the  
>> implementation of the context and its interaction with the saved  
>> PersistenceManagerFactory object. As with the other factory  
>> methods, the returned PersistenceManagerFactory is not configurable.
>> </proposed>
>>
>> Craig Russell
>> Architect, Sun Java Enterprise System http://java.sun.com/products/ 
>> jdo
>> 408 276-5638 mailto:Craig.Russell@sun.com
>> P.S. A good JDO? O, Gasp!
>>
>


Re: JDOHelper.getPersistenceManagerFactory section

Posted by Matthew Adams <ma...@matthewadams.org>.
Note:  I created a JIRA issue, JDO-545, for this.  This email is just  
a copy of it...