OPENJPA-2244: Applied Helen's patch to trunk.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1415486 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Heath Thomann 2012-11-30 03:14:37 +00:00
parent 7d897d94ce
commit 9fa9ef4fe8
5 changed files with 123 additions and 34 deletions

View File

@ -22,13 +22,17 @@ import java.io.File;
import java.security.AccessController; import java.security.AccessController;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.lib.conf.Configuration; import org.apache.openjpa.lib.conf.Configuration;
import org.apache.openjpa.lib.conf.ConfigurationImpl; import org.apache.openjpa.lib.conf.ConfigurationImpl;
import org.apache.openjpa.lib.conf.ConfigurationProvider; import org.apache.openjpa.lib.conf.ConfigurationProvider;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.conf.ProductDerivations; import org.apache.openjpa.lib.conf.ProductDerivations;
import org.apache.openjpa.lib.util.J2DoPrivHelper; import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.MultiClassLoader;
import org.apache.tools.ant.AntClassLoader; import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.DirectoryScanner;
@ -92,8 +96,10 @@ public abstract class AbstractTask extends MatchingTask {
* The task configuration. * The task configuration.
*/ */
public Configuration getConfiguration() { public Configuration getConfiguration() {
if (_conf == null) if (_conf == null) {
_conf = newConfiguration(); _conf = newConfiguration();
_conf.setDeferResourceLoading(true);
}
return _conf; return _conf;
} }
@ -158,11 +164,18 @@ public abstract class AbstractTask extends MatchingTask {
// if the user didn't supply a conf file, load the default // if the user didn't supply a conf file, load the default
if (_conf == null) if (_conf == null)
_conf = newConfiguration(); _conf = newConfiguration();
if (_conf.getPropertiesResource() == null) { ConfigurationProvider cp = null;
ConfigurationProvider cp = ProductDerivations.loadDefaults String propertiesResource = _conf.getPropertiesResource();
(AccessController.doPrivileged( if ( propertiesResource == null) {
J2DoPrivHelper.getClassLoaderAction(_conf.getClass()))); cp = ProductDerivations.loadDefaults(getConfigPropertiesResourceLoader());
if (cp != null) } else if (_conf.isDeferResourceLoading() && !StringUtils.isEmpty(propertiesResource)) {
Map<String, String> result = Configurations.parseConfigResource(propertiesResource);
String path = result.get(Configurations.CONFIG_RESOURCE_PATH);
String anchor = result.get(Configurations.CONFIG_RESOURCE_ANCHOR);
cp = ProductDerivations.load(path, anchor, getConfigPropertiesResourceLoader());
}
if (cp != null){
cp.setInto(_conf); cp.setInto(_conf);
} }
@ -179,6 +192,15 @@ public abstract class AbstractTask extends MatchingTask {
} }
} }
private MultiClassLoader getConfigPropertiesResourceLoader() {
MultiClassLoader loader = AccessController
.doPrivileged(J2DoPrivHelper.newMultiClassLoaderAction());
loader.addClassLoader(getClassLoader());
loader.addClassLoader(AccessController.doPrivileged(
J2DoPrivHelper.getClassLoaderAction(_conf.getClass())));
return loader;
}
private String[] getFiles() { private String[] getFiles() {
List<String> files = new ArrayList<String>(); List<String> files = new ArrayList<String>();
for(FileSet fs : fileSets) { for(FileSet fs : fileSets) {

View File

@ -126,6 +126,9 @@ public class ConfigurationImpl
// cache descriptors // cache descriptors
private PropertyDescriptor[] _pds = null; private PropertyDescriptor[] _pds = null;
private MethodDescriptor[] _mds = null; private MethodDescriptor[] _mds = null;
//Ant task needs to defer the resource loading
//until the classpath setting is loaded properly
private boolean _deferResourceLoading = false;
/** /**
* Default constructor. Attempts to load default properties through * Default constructor. Attempts to load default properties through
@ -272,6 +275,14 @@ public class ConfigurationImpl
} }
} }
public boolean isDeferResourceLoading() {
return _deferResourceLoading;
}
public void setDeferResourceLoading(boolean deferResourceLoading) {
this._deferResourceLoading = deferResourceLoading;
}
public void instantiateAll() { public void instantiateAll() {
StringWriter errs = null; StringWriter errs = null;
PrintWriter stack = null; PrintWriter stack = null;
@ -843,15 +854,17 @@ public class ConfigurationImpl
* <code>properties</code> value with the name of a resource. * <code>properties</code> value with the name of a resource.
*/ */
public void setProperties(String resourceName) throws IOException { public void setProperties(String resourceName) throws IOException {
if (!_deferResourceLoading) {
String anchor = null; String anchor = null;
if (resourceName.indexOf("#") != -1) if (resourceName.indexOf("#") != -1) {
{
anchor = resourceName.substring(resourceName.lastIndexOf("#") + 1); anchor = resourceName.substring(resourceName.lastIndexOf("#") + 1);
resourceName = resourceName.substring(0, resourceName = resourceName.substring(0, resourceName.length() - anchor.length() - 1);
resourceName.length() - anchor.length() - 1);
} }
ProductDerivations.load(resourceName, anchor,
getClass().getClassLoader()).setInto(this); ProductDerivations.load(resourceName, anchor, getClass().getClassLoader()).setInto(this);
}
_auto = resourceName; _auto = resourceName;
} }
@ -863,6 +876,7 @@ public class ConfigurationImpl
public void setPropertiesFile(File file) throws IOException { public void setPropertiesFile(File file) throws IOException {
ProductDerivations.load(file, null, getClass().getClassLoader()). ProductDerivations.load(file, null, getClass().getClassLoader()).
setInto(this); setInto(this);
setDeferResourceLoading(false);
_auto = file.toString(); _auto = file.toString();
} }

View File

@ -23,6 +23,7 @@ import java.security.AccessController;
import java.security.PrivilegedActionException; import java.security.PrivilegedActionException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -40,7 +41,6 @@ import org.apache.commons.lang.exception.NestableRuntimeException;
import org.apache.openjpa.lib.log.Log; import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.J2DoPrivHelper; import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.MultiClassLoader;
import org.apache.openjpa.lib.util.Options; import org.apache.openjpa.lib.util.Options;
import org.apache.openjpa.lib.util.ParseException; import org.apache.openjpa.lib.util.ParseException;
import org.apache.openjpa.lib.util.StringDistance; import org.apache.openjpa.lib.util.StringDistance;
@ -65,6 +65,9 @@ public class Configurations {
private static final Object NULL_LOADER = "null-loader"; private static final Object NULL_LOADER = "null-loader";
public static final String CONFIG_RESOURCE_PATH = "configResourcePath";
public static final String CONFIG_RESOURCE_ANCHOR = "configResourceAnchor";
/** /**
* Return the class name from the given plugin string, or null if none. * Return the class name from the given plugin string, or null if none.
*/ */
@ -331,18 +334,9 @@ public class Configurations {
String props = opts.removeProperty("properties", "p", null); String props = opts.removeProperty("properties", "p", null);
ConfigurationProvider provider; ConfigurationProvider provider;
if (!StringUtils.isEmpty(props)) { if (!StringUtils.isEmpty(props)) {
String path = props; Map<String, String> result = parseConfigResource(props);
String anchor = null; String path = result.get(CONFIG_RESOURCE_PATH);
int idx = path.lastIndexOf('#'); String anchor = result.get(CONFIG_RESOURCE_ANCHOR);
if (idx != -1) {
if (idx < path.length() - 1)
anchor = path.substring(idx + 1);
path = path.substring(0, idx);
if (path.length() == 0)
throw new MissingResourceException(_loc.get("anchor-only",
props).getMessage(), Configurations.class.getName(),
props);
}
File file = new File(path); File file = new File(path);
if ((AccessController.doPrivileged(J2DoPrivHelper if ((AccessController.doPrivileged(J2DoPrivHelper
@ -370,6 +364,25 @@ public class Configurations {
opts.setInto(conf); opts.setInto(conf);
} }
public static Map<String, String> parseConfigResource(String props) {
String path = props;
String anchor = null;
int idx = path.lastIndexOf('#');
if (idx != -1) {
if (idx < path.length() - 1)
anchor = path.substring(idx + 1);
path = path.substring(0, idx);
if (path.length() == 0)
throw new MissingResourceException(_loc.get("anchor-only",
props).getMessage(), Configurations.class.getName(),
props);
}
Map <String, String> result = new HashMap<String, String>();
result.put(CONFIG_RESOURCE_PATH, path);
result.put(CONFIG_RESOURCE_ANCHOR, anchor);
return result;
}
/** /**
* Helper method to throw an informative description on instantiation error. * Helper method to throw an informative description on instantiation error.
*/ */

View File

@ -61,6 +61,7 @@ import org.apache.openjpa.lib.meta.XMLMetaDataParser;
import org.apache.openjpa.lib.meta.XMLVersionParser; import org.apache.openjpa.lib.meta.XMLVersionParser;
import org.apache.openjpa.lib.util.J2DoPrivHelper; import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.MultiClassLoader;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
@ -512,8 +513,11 @@ public class PersistenceProductDerivation
private Boolean load(ConfigurationProviderImpl cp, String rsrc, private Boolean load(ConfigurationProviderImpl cp, String rsrc,
String name, Map m, ClassLoader loader, boolean explicit) String name, Map m, ClassLoader loader, boolean explicit)
throws IOException { throws IOException {
if (loader == null) ClassLoader contextLoader = null;
loader = AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction()); if (loader == null) {
contextLoader = AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction());
loader = contextLoader;
}
List<URL> urls = getResourceURLs(rsrc, loader); List<URL> urls = getResourceURLs(rsrc, loader);
if (urls == null || urls.size() == 0) if (urls == null || urls.size() == 0)
@ -537,8 +541,22 @@ public class PersistenceProductDerivation
} }
// Process jar-file references after confirming OpenJPA is the desired JPA provider. // Process jar-file references after confirming OpenJPA is the desired JPA provider.
if ( loader != contextLoader && loader instanceof MultiClassLoader) {
// combine the MultiClassLoader and set to the context
// so that it could be used in the jar validation
MultiClassLoader mutliClassLoader = (MultiClassLoader) loader;
contextLoader = (contextLoader != null) ? contextLoader
: AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction());
mutliClassLoader.addClassLoader(contextLoader);
AccessController.doPrivileged(J2DoPrivHelper.setContextClassLoaderAction(mutliClassLoader));
}
pinfo.processJarFileNames(); pinfo.processJarFileNames();
if (contextLoader != null) {
//restore the context loader
AccessController.doPrivileged(J2DoPrivHelper.setContextClassLoaderAction(contextLoader));
}
cp.addProperties(pinfo.toOpenJPAProperties()); cp.addProperties(pinfo.toOpenJPAProperties());
cp.setSource(pinfo.getPersistenceXmlFileUrl().toString()); cp.setSource(pinfo.getPersistenceXmlFileUrl().toString());
return Boolean.TRUE; return Boolean.TRUE;

View File

@ -19,6 +19,7 @@
package org.apache.openjpa.persistence; package org.apache.openjpa.persistence;
import java.io.File; import java.io.File;
import java.lang.reflect.Method;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
@ -237,8 +238,10 @@ public class PersistenceUnitInfoImpl
} }
public void validateJarFileName(String name) { public void validateJarFileName(String name) {
ClassLoader contextClassLoader = AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction());
MultiClassLoader loader = AccessController MultiClassLoader loader = AccessController
.doPrivileged(J2DoPrivHelper.newMultiClassLoaderAction()); .doPrivileged(J2DoPrivHelper.newMultiClassLoaderAction());
loader.addClassLoader(contextClassLoader);
loader.addClassLoader(getClass().getClassLoader()); loader.addClassLoader(getClass().getClassLoader());
loader.addClassLoader(MultiClassLoader.THREAD_LOADER); loader.addClassLoader(MultiClassLoader.THREAD_LOADER);
URL url = AccessController.doPrivileged( URL url = AccessController.doPrivileged(
@ -249,9 +252,28 @@ public class PersistenceUnitInfoImpl
} }
// jar file is not a resource; check classpath // jar file is not a resource; check classpath
String[] cp = (AccessController.doPrivileged( String classPath = null;
J2DoPrivHelper.getPropertyAction("java.class.path")))
.split(J2DoPrivHelper.getPathSeparator()); //first check if the classpath is set from ant class loader
if (contextClassLoader instanceof MultiClassLoader) {
for (ClassLoader classLoader : ((MultiClassLoader) contextClassLoader).getClassLoaders()){
try {
Method getClassPathMethod = classLoader.getClass().getMethod("getClasspath", new Class[]{});
classPath = (String) getClassPathMethod.invoke(classLoader, new Object[]{});
if (classPath != null)
break;
} catch (Exception e) {
//do nothing
}
}
}
if (classPath == null) {
classPath = AccessController.doPrivileged(
J2DoPrivHelper.getPropertyAction("java.class.path"));
}
String[] cp = classPath.split(J2DoPrivHelper.getPathSeparator());
for (int i = 0; i < cp.length; i++) { for (int i = 0; i < cp.length; i++) {
if (cp[i].equals(name) if (cp[i].equals(name)
|| cp[i].endsWith(File.separatorChar + name)) { || cp[i].endsWith(File.separatorChar + name)) {