diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/ant/AbstractTask.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/ant/AbstractTask.java index 5c15eca53..c0f2dbf19 100644 --- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/ant/AbstractTask.java +++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/ant/AbstractTask.java @@ -22,13 +22,17 @@ import java.io.File; import java.security.AccessController; import java.util.ArrayList; 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.ConfigurationImpl; 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.util.J2DoPrivHelper; 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.BuildException; import org.apache.tools.ant.DirectoryScanner; @@ -92,8 +96,10 @@ public abstract class AbstractTask extends MatchingTask { * The task configuration. */ public Configuration getConfiguration() { - if (_conf == null) - _conf = newConfiguration(); + if (_conf == null) { + _conf = newConfiguration(); + _conf.setDeferResourceLoading(true); + } return _conf; } @@ -158,12 +164,19 @@ public abstract class AbstractTask extends MatchingTask { // if the user didn't supply a conf file, load the default if (_conf == null) _conf = newConfiguration(); - if (_conf.getPropertiesResource() == null) { - ConfigurationProvider cp = ProductDerivations.loadDefaults - (AccessController.doPrivileged( - J2DoPrivHelper.getClassLoaderAction(_conf.getClass()))); - if (cp != null) - cp.setInto(_conf); + ConfigurationProvider cp = null; + String propertiesResource = _conf.getPropertiesResource(); + if ( propertiesResource == null) { + cp = ProductDerivations.loadDefaults(getConfigPropertiesResourceLoader()); + } else if (_conf.isDeferResourceLoading() && !StringUtils.isEmpty(propertiesResource)) { + Map 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); } String[] files = getFiles(); @@ -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() { List files = new ArrayList(); for(FileSet fs : fileSets) { diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java index 09b3a967f..7447bb025 100644 --- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java +++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/ConfigurationImpl.java @@ -126,6 +126,9 @@ public class ConfigurationImpl // cache descriptors private PropertyDescriptor[] _pds = 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 @@ -272,6 +275,14 @@ public class ConfigurationImpl } } + public boolean isDeferResourceLoading() { + return _deferResourceLoading; + } + + public void setDeferResourceLoading(boolean deferResourceLoading) { + this._deferResourceLoading = deferResourceLoading; + } + public void instantiateAll() { StringWriter errs = null; PrintWriter stack = null; @@ -843,15 +854,17 @@ public class ConfigurationImpl * properties value with the name of a resource. */ public void setProperties(String resourceName) throws IOException { - String anchor = null; - if (resourceName.indexOf("#") != -1) - { - anchor = resourceName.substring(resourceName.lastIndexOf("#") + 1); - resourceName = resourceName.substring(0, - resourceName.length() - anchor.length() - 1); + + if (!_deferResourceLoading) { + String anchor = null; + if (resourceName.indexOf("#") != -1) { + anchor = resourceName.substring(resourceName.lastIndexOf("#") + 1); + resourceName = resourceName.substring(0, resourceName.length() - anchor.length() - 1); + } + + ProductDerivations.load(resourceName, anchor, getClass().getClassLoader()).setInto(this); } - ProductDerivations.load(resourceName, anchor, - getClass().getClassLoader()).setInto(this); + _auto = resourceName; } @@ -863,6 +876,7 @@ public class ConfigurationImpl public void setPropertiesFile(File file) throws IOException { ProductDerivations.load(file, null, getClass().getClassLoader()). setInto(this); + setDeferResourceLoading(false); _auto = file.toString(); } diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java index 2d2557b4b..81ac83329 100644 --- a/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java +++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/conf/Configurations.java @@ -23,6 +23,7 @@ import java.security.AccessController; import java.security.PrivilegedActionException; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; import java.util.List; 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.util.J2DoPrivHelper; 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.ParseException; import org.apache.openjpa.lib.util.StringDistance; @@ -65,6 +65,9 @@ public class Configurations { 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. */ @@ -331,18 +334,9 @@ public class Configurations { String props = opts.removeProperty("properties", "p", null); ConfigurationProvider provider; if (!StringUtils.isEmpty(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 result = parseConfigResource(props); + String path = result.get(CONFIG_RESOURCE_PATH); + String anchor = result.get(CONFIG_RESOURCE_ANCHOR); File file = new File(path); if ((AccessController.doPrivileged(J2DoPrivHelper @@ -370,6 +364,25 @@ public class Configurations { opts.setInto(conf); } + public static Map 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 result = new HashMap(); + result.put(CONFIG_RESOURCE_PATH, path); + result.put(CONFIG_RESOURCE_ANCHOR, anchor); + return result; + } + /** * Helper method to throw an informative description on instantiation error. */ diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java index 2d178bf3e..d8c46d766 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java @@ -61,6 +61,7 @@ import org.apache.openjpa.lib.meta.XMLMetaDataParser; import org.apache.openjpa.lib.meta.XMLVersionParser; import org.apache.openjpa.lib.util.J2DoPrivHelper; import org.apache.openjpa.lib.util.Localizer; +import org.apache.openjpa.lib.util.MultiClassLoader; import org.xml.sax.Attributes; import org.xml.sax.SAXException; @@ -512,8 +513,11 @@ public class PersistenceProductDerivation private Boolean load(ConfigurationProviderImpl cp, String rsrc, String name, Map m, ClassLoader loader, boolean explicit) throws IOException { - if (loader == null) - loader = AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction()); + ClassLoader contextLoader = null; + if (loader == null) { + contextLoader = AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction()); + loader = contextLoader; + } List urls = getResourceURLs(rsrc, loader); 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. + 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(); + if (contextLoader != null) { + //restore the context loader + AccessController.doPrivileged(J2DoPrivHelper.setContextClassLoaderAction(contextLoader)); + } + cp.addProperties(pinfo.toOpenJPAProperties()); cp.setSource(pinfo.getPersistenceXmlFileUrl().toString()); return Boolean.TRUE; diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceUnitInfoImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceUnitInfoImpl.java index 91f7ce05e..c5d1e54b2 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceUnitInfoImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceUnitInfoImpl.java @@ -19,6 +19,7 @@ package org.apache.openjpa.persistence; import java.io.File; +import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; @@ -237,8 +238,10 @@ public class PersistenceUnitInfoImpl } public void validateJarFileName(String name) { + ClassLoader contextClassLoader = AccessController.doPrivileged(J2DoPrivHelper.getContextClassLoaderAction()); MultiClassLoader loader = AccessController .doPrivileged(J2DoPrivHelper.newMultiClassLoaderAction()); + loader.addClassLoader(contextClassLoader); loader.addClassLoader(getClass().getClassLoader()); loader.addClassLoader(MultiClassLoader.THREAD_LOADER); URL url = AccessController.doPrivileged( @@ -249,9 +252,28 @@ public class PersistenceUnitInfoImpl } // jar file is not a resource; check classpath - String[] cp = (AccessController.doPrivileged( - J2DoPrivHelper.getPropertyAction("java.class.path"))) - .split(J2DoPrivHelper.getPathSeparator()); + String classPath = null; + + //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++) { if (cp[i].equals(name) || cp[i].endsWith(File.separatorChar + name)) {