Author: awhite Date: Fri Oct 13 14:07:17 2006 New Revision: 463829 URL: http://svn.apache.org/viewvc?view=rev&rev=463829 Log: Validate product derivations before caching them so we don't end up with runtime errors when clients use JPA without jdo.jar or JDO without jpa.jar. Give a more succinct warning when some product derivations are uninstantiable, with more detailed information available via the ProductDerivations class's main().
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaTool.java incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/AbstractProductDerivation.java incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivation.java incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java incubator/openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties incubator/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCPersistenceProductDerivation.java incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaTool.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaTool.java?view=diff&rev=463829&r1=463828&r2=463829 ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaTool.java (original) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/SchemaTool.java Fri Oct 13 14:07:17 2006 @@ -625,44 +625,6 @@ } } - // indexes - /* - if (_indexes) - { - Index[] idxs; - Index idx; - for (int i = 0; i < schemas.length; i++) - { - tabs = schemas[i].getTables (); - for (int j = 0; j < tabs.length; j++) - { - if (!isDroppable (tabs[j])) - continue; - idxs = tabs[j].getIndexes (); - reposTable = repos.findTable (tabs[j]); - if (!tables && reposTable == null) - continue; - - for (int k = 0; k < idxs.length; k++) - { - idx = null; - if (reposTable != null) - idx = reposTable.getIndex (idxs[k].getName ()); - if (reposTable == null || idx == null - || !idxs[k].equalsIndex (idx)) - { - if (dropIndex (idxs[k])) - tabs[j].removeIndex (idxs[k]); - else - _log.warn (_loc.get ("drop-index", idxs[k], - tabs[j])); - } - } - } - } - } - */ - // primary keys if (_pks) { PrimaryKey pk; @@ -830,41 +792,6 @@ } } - // indexes - /* - if (_indexes) - { - Index[] idxs; - Index idx; - for (int i = 0; i < schemas.length; i++) - { - tabs = schemas[i].getTables (); - for (int j = 0; j < tabs.length; j++) - { - if (!isDroppable (tabs[j])) - continue; - idxs = tabs[j].getIndexes (); - dbTable = db.findTable (tabs[j]); - for (int k = 0; k < idxs.length; k++) - { - idx = null; - if (dbTable != null) - idx = dbTable.getIndex (idxs[k].getName ()); - if (dbTable == null || idx == null) - continue; - - if (dropIndex (idxs[k])) - if (dbTable != null) - dbTable.removeIndex (idx); - else - _log.warn (_loc.get ("drop-index", idxs[k], - tabs[j])); - } - } - } - } - */ - // drop the tables we calculated above dropTables(drops, db); @@ -885,11 +812,12 @@ if (dbTable == null || col == null) continue; - if (dropColumn(cols[k])) + if (dropColumn(cols[k])) { if (dbTable != null) dbTable.removeColumn(col); else _log.warn(_loc.get("drop-col", cols[k], tabs[j])); + } } } } @@ -948,11 +876,9 @@ if (tables.isEmpty()) return; - Collection nodes = tables; - Table table; Table changeTable; - for (Iterator itr = nodes.iterator(); itr.hasNext();) { + for (Iterator itr = tables.iterator(); itr.hasNext();) { table = (Table) itr.next(); if (dropTable(table)) { changeTable = change.findTable(table); @@ -1338,11 +1264,14 @@ * <ul> * <li>Write a script to stdout to re-create the current database * schema:<br /> - * <code>java org.apache.openjpa.jdbc.schema.SchemaTool -f stdout -a createDB</code> + * <code>java org.apache.openjpa.jdbc.schema.SchemaTool -f stdout + * -a createDB</code></li> * <li>Drop the current database schema:<br /> - * <code>java org.apache.openjpa.jdbc.schema.SchemaTool -a dropDB</code></li> + * <code>java org.apache.openjpa.jdbc.schema.SchemaTool + * -a dropDB</code></li> * <li>Create a schema based on an XML schema definition file:<br /> - * <code>java org.apache.openjpa.jdbc.schema.SchemaTool myschema.xml</code></li> + * <code>java org.apache.openjpa.jdbc.schema.SchemaTool + * myschema.xml</code></li> * </ul> */ public static void main(String[] args) Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java?view=diff&rev=463829&r1=463828&r2=463829 ============================================================================== --- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java (original) +++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java Fri Oct 13 14:07:17 2006 @@ -3561,14 +3561,8 @@ return key; } finally { if (rs != null) - try { - rs.close(); - } catch (SQLException se) { - } - try { - stmnt.close(); - } catch (SQLException se) { - } + try { rs.close(); } catch (SQLException se) {} + try { stmnt.close(); } catch (SQLException se) {} } } Modified: incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/AbstractProductDerivation.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/AbstractProductDerivation.java?view=diff&rev=463829&r1=463828&r2=463829 ============================================================================== --- incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/AbstractProductDerivation.java (original) +++ incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/AbstractProductDerivation.java Fri Oct 13 14:07:17 2006 @@ -31,6 +31,10 @@ return null; } + public void validate() + throws Exception { + } + public ConfigurationProvider loadGlobals(ClassLoader loader) throws Exception { return null; Modified: incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivation.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivation.java?view=diff&rev=463829&r1=463828&r2=463829 ============================================================================== --- incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivation.java (original) +++ incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivation.java Fri Oct 13 14:07:17 2006 @@ -46,6 +46,15 @@ public String getConfigurationPrefix(); /** + * Ensure that this derivation is valid. This action might consist of + * loading classes for the product this derivation represents to be sure + * they exist. Throw any throwable to indicate an invalid derivation. + * Invalid derivations will not be used. + */ + public void validate() + throws Exception; + + /** * Load globals into the returned ConfigurationProvider, or return null if * no globals are found. */ Modified: incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java?view=diff&rev=463829&r1=463828&r2=463829 ============================================================================== --- incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java (original) +++ incubator/openjpa/trunk/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ProductDerivations.java Fri Oct 13 14:07:17 2006 @@ -38,31 +38,41 @@ (ProductDerivations.class); private static final ProductDerivation[] _derivations; + private static final String[] _derivationNames; + private static final Throwable[] _derivationErrors; private static final String[] _prefixes; static { - ClassLoader cl = ProductDerivation.class.getClassLoader(); - String[] pds = Services.getImplementors(ProductDerivation.class, cl); - List derivations = new ArrayList(pds.length); - for (int i = 0; i < pds.length; i++) { - try { - Class cls = Class.forName(pds[i], true, cl); - derivations.add(cls.newInstance()); - } catch (UnsupportedClassVersionError ucve) { - // ignore so that < 1.5 users don't get errors about - // 1.5 products they aren't using + ClassLoader l = ProductDerivation.class.getClassLoader(); + _derivationNames = Services.getImplementors(ProductDerivation.class, l); + _derivationErrors = new Throwable[_derivationNames.length]; + List derivations = new ArrayList(_derivationNames.length); + for (int i = 0; i < _derivationNames.length; i++) { + try { + ProductDerivation d = (ProductDerivation) Class. + forName(_derivationNames[i], true, l).newInstance(); + d.validate(); + derivations.add(d); } catch (Throwable t) { - System.err.println(_loc.get("bad-product-derivation", pds[i], - t)); + _derivationErrors[i] = t; } } // must be at least one product derivation to define metadata factories, // etc. if (derivations.isEmpty()) { - Localizer loc = Localizer.forPackage(ProductDerivations.class); - throw new MissingResourceException(loc.get("no-product-derivations", - ProductDerivation.class.getName()).getMessage(), - ProductDerivations.class.getName(), "derivations"); + throw new MissingResourceException(_loc.get + ("no-product-derivations", ProductDerivation.class.getName(), + derivationErrorsToString()).getMessage(), + ProductDerivations.class.getName(),"derivations"); + } + + // if some derivations weren't instantiable, warn + for (int i = 0; i < _derivationErrors.length; i++) { + if (_derivationErrors[i] == null) + continue; + System.err.println(_loc.get("bad-product-derivations", + ProductDerivations.class.getName())); + break; } Collections.sort(derivations, new ProductDerivationComparator()); @@ -269,5 +279,29 @@ getName()); } } + + /** + * Prints product derivation information. + */ + public static void main(String[] args) { + System.err.println(derivationErrorsToString()); + } + + /** + * Return a message about the status of each product derivation. + */ + private static String derivationErrorsToString() { + StringBuffer buf = new StringBuffer(); + buf.append("ProductDerivations: ").append(_derivationNames.length); + for (int i = 0; i < _derivationNames.length; i++) { + buf.append("\n").append(i + 1).append(". "). + append(_derivationNames[i]).append(": "); + if (_derivationErrors[i] == null) + buf.append("OK"); + else + buf.append(_derivationErrors[i].toString()); + } + return buf.toString(); + } } Modified: incubator/openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties?view=diff&rev=463829&r1=463828&r2=463829 ============================================================================== --- incubator/openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties (original) +++ incubator/openjpa/trunk/openjpa-lib/src/main/resources/org/apache/openjpa/lib/conf/localizer.properties Fri Oct 13 14:07:17 2006 @@ -67,10 +67,9 @@ If you are using ant, a common solution to this problem is to place \ the jar libraries of the OpenJPA distribution in the \ $'{user.home}/.ant/lib directory. Another common cause of this problem \ - is an overly-restrictive security manager. -bad-product-derivation: An error occurred while attempting to load {0}. This \ - may indicate a corrupt system configuration, or may just be the result \ - of the inclusion of unused OpenJPA modules in your classpath. Error: {1} + is an overly-restrictive security manager.\n{1} +bad-product-derivations: Some product derivations are being skipped. For \ + information about product derivation status, run:\njava {0} Log-name: Log factory Log-desc: LogFactory and configuration Modified: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCPersistenceProductDerivation.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCPersistenceProductDerivation.java?view=diff&rev=463829&r1=463828&r2=463829 ============================================================================== --- incubator/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCPersistenceProductDerivation.java (original) +++ incubator/openjpa/trunk/openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/JDBCPersistenceProductDerivation.java Fri Oct 13 14:07:17 2006 @@ -44,6 +44,13 @@ } @Override + public void validate() + throws Exception { + // make sure JPA is available + javax.persistence.EntityManagerFactory.class.getClassLoader(); + } + + @Override public boolean beforeConfigurationLoad(Configuration c) { if (c instanceof OpenJPAConfiguration) { ((OpenJPAConfiguration) c).getStoreFacadeTypeRegistry(). Modified: incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java?view=diff&rev=463829&r1=463828&r2=463829 ============================================================================== --- incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java (original) +++ incubator/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java Fri Oct 13 14:07:17 2006 @@ -76,6 +76,13 @@ public int getType() { return TYPE_SPEC; } + + @Override + public void validate() + throws Exception { + // make sure JPA is available + javax.persistence.EntityManagerFactory.class.getClassLoader(); + } @Override public boolean beforeConfigurationLoad(Configuration c) {