Index: api2/src/java/javax/jdo/JDOHelper.java
===================================================================
--- api2/src/java/javax/jdo/JDOHelper.java (revision 693935)
+++ api2/src/java/javax/jdo/JDOHelper.java (working copy)
@@ -773,47 +773,85 @@
* PersistenceManagerFactory.
* @param pmfClassLoader the class loader to use to load the
* PersistenceManagerFactory class
+ * @throws JDOFatalUserException If either the pmfClassLoader passed is
+ * invalid or a valid class name cannot be obtained from
+ * either props or system resources.
* @since 2.1
*/
protected static PersistenceManagerFactory getPersistenceManagerFactory
- (Map overrides, Map props, ClassLoader pmfClassLoader) {
+ (Map overrides, Map props, ClassLoader pmfClassLoader) throws JDOFatalUserException {
List exceptions = new ArrayList();
if (pmfClassLoader == null)
throw new JDOFatalUserException (msg.msg (
"EXC_GetPMFNullLoader")); //NOI18N
+ // try and get the class name from the properties object.
String pmfClassName = (String) props.get (
PROPERTY_PERSISTENCE_MANAGER_FACTORY_CLASS);
+ // test to be sure all the throwables are in the nested exceptions
+ // array. There are multiple jar files where the class loader can
+ // exist in - and this code will find all of them.
+ // positive test: a bad implementation of a class:
+ // META-INF is missing a class or the class is bad.
+ // test 1: check that all bad classes are skipped
+ // test 2: check that when all classes are bad, that all exceptions are
+ // caught.
+ // use JDOHelperConfigTest and JDOConfigTestClassLoader
+ // have multiple jar files in classpath
if (!isNullOrBlank(pmfClassName)) {
+ // a valid name was returned from the properties.
return invokeGetPersistenceManagerFactoryOnImplementation(
pmfClassName, overrides, props, pmfClassLoader);
} else {
- // PMF class name null or blank -- try services
- // for each file META-INF/services/javax.jdo.PersistenceManagerFactory
- // try to invoke the getPersistenceManagerFactory method of the
- // implementation class
+ /*
+ * If you have a .jar file that provides services, a file name for
+ * each service goes into the jar file
+ * META-INF/services/javax.naming.initialContext.
+ * The contents of the file is a string that is the PMF class name,
+ * null or blank. For each file
+ * META-INF/services/javax.jdo.PersistenceManagerFactory
+ * try to invoke the getPersistenceManagerFactory method of the
+ * implementation class. Return the factory if a valid class name is
+ * extracted from resources. Otherwise add the exception thrown to
+ * an exception list.
+ */
+ Enumeration urls = null;
try {
- Enumeration urls = getResources(pmfClassLoader,
- SERVICE_LOOKUP_PMF_RESOURCE_NAME);
+ urls = getResources(pmfClassLoader,
+ SERVICE_LOOKUP_PMF_RESOURCE_NAME);
+ } catch (Throwable ex) {
+ exceptions.add(ex);
+ }
+
+ if (urls != null){
while (urls.hasMoreElements()) {
- pmfClassName = getClassNameFromURL((URL)urls.nextElement());
+
+ try {
+ pmfClassName = getClassNameFromURL(
+ (URL) urls.nextElement());
+
+ // return the first class name that is valid.
return invokeGetPersistenceManagerFactoryOnImplementation(
- pmfClassName, overrides, props, pmfClassLoader);
+ pmfClassName, overrides, props, pmfClassLoader);
+
+ } catch (Throwable ex) {
+
+ // remember exceptions from failed pmf invocations
+ exceptions.add(ex);
+
+ }
}
- } catch (Throwable ex) {
- // remember exceptions from failed pmf invocations
- exceptions.add(ex);
}
+
}
- // no PMF class name and no services
+ // no PMF class name and no services.
throw new JDOFatalUserException(msg.msg(
"EXC_GetPMFNoPMFClassNamePropertyOrPUNameProperty"),
- (Throwable[])
- exceptions.toArray(new Throwable[exceptions.size()]));
+ (Throwable[]) exceptions.toArray(new Throwable[exceptions.size()]));
}
/** Get a class name from a URL. The URL is from getResources with
Index: api2/test/java/javax/jdo/JDOHelperConfigTest.java
===================================================================
--- api2/test/java/javax/jdo/JDOHelperConfigTest.java (revision 693934)
+++ api2/test/java/javax/jdo/JDOHelperConfigTest.java (working copy)
@@ -527,6 +527,7 @@
}
}
+
public void testNegative07_EmptyServicesFile()
throws IOException {
JDOConfigTestClassLoader testLoader = new JDOConfigTestClassLoader(
@@ -556,6 +557,31 @@
}
}
+ public void testNegative09_MultipleInvalidClassesInDifferentConfigFiles()
+ throws IOException {
+
+ // failure ensured with a bad class name in Negative09/jdoconfig.xml
+ try {
+ URLClassLoader loader = new JDOConfigTestClassLoader(
+ JDOCONFIG_CLASSPATH_PREFIX,
+ getClass().getClassLoader());
+ ClasspathHelper.addFile(
+ JDOCONFIG_CLASSPATH_PREFIX + "/Negative09", loader);
+
+ JDOHelper.getPersistenceManagerFactory(loader);
+
+ fail("JDOHelper failed to throw JDOFatalUserException");
+ }
+ catch (JDOFatalUserException x) {
+
+ // if nested exceptions are returned, we're on the happy farm ...
+ if (x.getNestedExceptions() == null){
+ fail("JDOHelper failed to include any nested exceptions");
+ }
+
+ }
+ }
+
public void testNegative08_ServicesFileWithOnlyComments()
throws IOException {
JDOConfigTestClassLoader testLoader = new JDOConfigTestClassLoader(
Index: api2/test/schema/jdoconfig/Negative09/META-INF/jdoconfig.xml
===================================================================
--- api2/test/schema/jdoconfig/Negative09/META-INF/jdoconfig.xml (revision 693934)
+++ api2/test/schema/jdoconfig/Negative09/META-INF/jdoconfig.xml (working copy)
@@ -8,9 +8,12 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">
-
-
+
+
+
+
\ No newline at end of file