db-jdo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Matthew Adams <matt...@matthewadams.org>
Subject Re: JDOHelper.getPersistenceManagerFactory section
Date Wed, 10 Oct 2007 06:20:46 GMT
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!
>>
>


Mime
View raw message