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().



git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@463829 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
A. Abram White 2006-10-13 21:07:17 +00:00
parent 72594b2ac8
commit c8b5b2746e
8 changed files with 90 additions and 107 deletions

View File

@ -625,44 +625,6 @@ public class SchemaTool {
}
}
// 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 @@ public class SchemaTool {
}
}
// 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 @@ public class SchemaTool {
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 @@ public class SchemaTool {
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 @@ public class SchemaTool {
* <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)

View File

@ -3561,14 +3561,8 @@ public class DBDictionary
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) {}
}
}

View File

@ -31,6 +31,10 @@ public abstract class AbstractProductDerivation
return null;
}
public void validate()
throws Exception {
}
public ConfigurationProvider loadGlobals(ClassLoader loader)
throws Exception {
return null;

View File

@ -45,6 +45,15 @@ public interface ProductDerivation {
*/
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.

View File

@ -38,31 +38,41 @@ public class ProductDerivations {
(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++) {
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 {
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
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 @@ public class ProductDerivations {
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();
}
}

View File

@ -67,10 +67,9 @@ no-product-derivations: Your system is missing product derivations. Product \
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

View File

@ -43,6 +43,13 @@ public class JDBCPersistenceProductDerivation
return TYPE_SPEC_STORE;
}
@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) {

View File

@ -76,6 +76,13 @@ public class PersistenceProductDerivation
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) {