Index: trunk/api2/src/java/javax/jdo/JDOHelper.java =================================================================== --- trunk/api2/src/java/javax/jdo/JDOHelper.java (revision 694575) +++ trunk/api2/src/java/javax/jdo/JDOHelper.java (working copy) @@ -773,47 +773,90 @@ * 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 { + URL curURL = (URL)urls.nextElement(); + System.out.print("curURL path: " + curURL.getPath()); + + pmfClassName = getClassNameFromURL( + curURL); + // (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