Author: rmannibucau
Date: Mon Aug 12 08:15:25 2013
New Revision: 1513074
URL: http://svn.apache.org/r1513074
Log:
OPENEJB-2035 replacing real jar when using deploy time enhacement otherwise existing classloaders
are broken + trying to use container classloader to create datasource when possible
Modified:
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/DeployTimeEnhancer.java
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java
tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/classloader/URLClassLoaderFirst.java
Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/DeployTimeEnhancer.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/DeployTimeEnhancer.java?rev=1513074&r1=1513073&r2=1513074&view=diff
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/DeployTimeEnhancer.java
(original)
+++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/DeployTimeEnhancer.java
Mon Aug 12 08:15:25 2013
@@ -27,7 +27,6 @@ import org.apache.openejb.util.Logger;
import org.apache.openejb.util.Saxs;
import org.apache.openejb.util.URLs;
import org.apache.openejb.util.classloader.URLClassLoaderFirst;
-import org.apache.xbean.finder.filter.Filter;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
@@ -39,7 +38,6 @@ import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
-import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -60,7 +58,6 @@ public class DeployTimeEnhancer {
private static final String PROPERTIES_FILE_PROP = "propertiesFile";
private static final String META_INF_PERSISTENCE_XML = "META-INF/persistence.xml";
private static final String TMP_ENHANCEMENT_SUFFIX = ".tmp-enhancement";
- private static final String JAR_ENHANCEMENT_SUFFIX = "-enhanced";
private final Method enhancerMethod;
private final Constructor<?> optionsConstructor;
@@ -91,37 +88,32 @@ public class DeployTimeEnhancer {
// find persistence.xml
final Map<String, List<String>> classesByPXml = new HashMap<String,
List<String>>();
- final Filter filter = new AlreadyEnhancedFilter();
final List<URL> usedUrls = new ArrayList<URL>(); // for fake classloader
for (URL url : event.getUrls()) {
final File file = URLs.toFile(url);
- if (filter.accept(file.getName())) {
- if (file.isDirectory()) {
- final String pXmls = getWarPersistenceXml(url);
- if (pXmls != null) {
- feed(classesByPXml, pXmls);
- }
+ if (file.isDirectory()) {
+ final String pXmls = getWarPersistenceXml(url);
+ if (pXmls != null) {
+ feed(classesByPXml, pXmls);
+ }
- usedUrls.add(url);
- } else if (file.getName().endsWith(".jar")) {
- try {
- final JarFile jar = new JarFile(file);
- ZipEntry entry = jar.getEntry(META_INF_PERSISTENCE_XML);
- if (entry != null) {
- final String path = file.getAbsolutePath();
- final File unpacked = new File(path.substring(0, path.length()
- 4) + TMP_ENHANCEMENT_SUFFIX);
- JarExtractor.extract(file, unpacked);
+ usedUrls.add(url);
+ } else if (file.getName().endsWith(".jar")) {
+ try {
+ final JarFile jar = new JarFile(file);
+ ZipEntry entry = jar.getEntry(META_INF_PERSISTENCE_XML);
+ if (entry != null) {
+ final String path = file.getAbsolutePath();
+ final File unpacked = new File(path.substring(0, path.length() -
4) + TMP_ENHANCEMENT_SUFFIX);
+ JarExtractor.extract(file, unpacked);
- // replace jar by folder url since otherwise enhancement doesn't
work
- usedUrls.add(unpacked.toURI().toURL());
+ // replace jar by folder url since otherwise enhancement doesn't
work
+ usedUrls.add(unpacked.toURI().toURL());
- feed(classesByPXml, new File(unpacked, META_INF_PERSISTENCE_XML).getAbsolutePath());
- }
- } catch (IOException e) {
- // ignored
+ feed(classesByPXml, new File(unpacked, META_INF_PERSISTENCE_XML).getAbsolutePath());
}
- } else {
- usedUrls.add(url);
+ } catch (IOException e) {
+ // ignored
}
} else {
usedUrls.add(url);
@@ -159,7 +151,7 @@ public class DeployTimeEnhancer {
usedUrls.clear();
}
- // clean up extracted jars
+ // clean up extracted jars and replace jar to keep consistent classloading
for (Map.Entry<String, List<String>> entry : classesByPXml.entrySet())
{
final List<String> values = entry.getValue();
for (String rawPath : values) {
@@ -168,11 +160,13 @@ public class DeployTimeEnhancer {
final File file = new File(rawPath.substring(0, rawPath.length() - TMP_ENHANCEMENT_SUFFIX.length()
- 1) + ".jar");
if (file.exists()) {
String name = dir.getName();
- name = name.substring(0, name.length() - TMP_ENHANCEMENT_SUFFIX.length())
+ JAR_ENHANCEMENT_SUFFIX + ".jar";
- try {
- JarCreator.jarDir(dir, new File(dir.getParentFile(), name));
- Files.delete(file); // don't delete if any exception is thrown
- } catch (IOException e) {
+ name = name.substring(0, name.length() - TMP_ENHANCEMENT_SUFFIX.length())
+ ".jar";
+
+ final File target = new File(dir.getParentFile(), name);
+ try { // override existing jar otherwise classloading is broken in
tomee
+ Files.delete(file);
+ JarCreator.jarDir(dir, target);
+ } catch (final IOException e) {
LOGGER.error("can't repackage enhanced jar file " + file.getName());
}
Files.delete(dir);
@@ -280,7 +274,7 @@ public class DeployTimeEnhancer {
@Override
public void characters(final char ch[], final int start, final int length) throws
SAXException {
if (getIt) {
- paths.add(new StringBuilder().append(ch, start, length).toString());
+ paths.add(String.valueOf(ch, start, length));
}
}
@@ -293,13 +287,4 @@ public class DeployTimeEnhancer {
return paths;
}
}
-
- private static class AlreadyEnhancedFilter implements Filter {
- public static final String SUFFIX = JAR_ENHANCEMENT_SUFFIX + ".jar";
-
- @Override
- public boolean accept(final String s) {
- return !s.endsWith(SUFFIX);
- }
- }
}
Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java?rev=1513074&r1=1513073&r2=1513074&view=diff
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java
(original)
+++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/DataSourceFactory.java
Mon Aug 12 08:15:25 2013
@@ -87,56 +87,68 @@ public class DataSourceFactory {
"true".equalsIgnoreCase((String)
properties.remove(LOG_SQL_PROPERTY)));
final DataSourceCreator creator = creator(properties.remove(DATA_SOURCE_CREATOR_PROP),
logSql);
- DataSource ds;
- if (createDataSourceFromClass(impl)) { // opposed to "by driver"
- trimNotSupportedDataSourceProperties(properties);
-
- final ObjectRecipe recipe = new ObjectRecipe(impl);
- recipe.allow(Option.CASE_INSENSITIVE_PROPERTIES);
- recipe.allow(Option.IGNORE_MISSING_PROPERTIES);
- recipe.allow(Option.NAMED_PARAMETERS);
- recipe.setAllProperties(properties);
- if (!properties.containsKey("url") && properties.containsKey("JdbcUrl"))
{ // depend on the datasource class so add all well known keys
- recipe.setProperty("url", properties.getProperty("JdbcUrl"));
- }
-
- final DataSource dataSource = (DataSource) recipe.create();
-
- if (managed) {
- if (usePool(properties)) {
- ds = creator.poolManaged(name, dataSource, properties);
- } else {
- ds = creator.managed(name, dataSource);
+ final boolean useContainerLoader = "true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.resources.use-container-loader",
"true")) && (impl == null || impl.getClassLoader() == DataSourceFactory.class.getClassLoader());
+ final ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
+ if (useContainerLoader) {
+ Thread.currentThread().setContextClassLoader(DataSourceFactory.class.getClassLoader());
+ }
+
+ try {
+ DataSource ds;
+ if (createDataSourceFromClass(impl)) { // opposed to "by driver"
+ trimNotSupportedDataSourceProperties(properties);
+
+ final ObjectRecipe recipe = new ObjectRecipe(impl);
+ recipe.allow(Option.CASE_INSENSITIVE_PROPERTIES);
+ recipe.allow(Option.IGNORE_MISSING_PROPERTIES);
+ recipe.allow(Option.NAMED_PARAMETERS);
+ recipe.setAllProperties(properties);
+ if (!properties.containsKey("url") && properties.containsKey("JdbcUrl"))
{ // depend on the datasource class so add all well known keys
+ recipe.setProperty("url", properties.getProperty("JdbcUrl"));
}
- } else {
- if (usePool(properties)) {
- ds = creator.pool(name, dataSource, properties);
+
+ final DataSource dataSource = (DataSource) recipe.create();
+
+ if (managed) {
+ if (usePool(properties)) {
+ ds = creator.poolManaged(name, dataSource, properties);
+ } else {
+ ds = creator.managed(name, dataSource);
+ }
} else {
- ds = dataSource;
+ if (usePool(properties)) {
+ ds = creator.pool(name, dataSource, properties);
+ } else {
+ ds = dataSource;
+ }
}
- }
- } else { // by driver
- if (managed) {
- final XAResourceWrapper xaResourceWrapper = SystemInstance.get().getComponent(XAResourceWrapper.class);
- if (xaResourceWrapper != null) {
- ds = creator.poolManagedWithRecovery(name, xaResourceWrapper, impl.getName(),
properties);
+ } else { // by driver
+ if (managed) {
+ final XAResourceWrapper xaResourceWrapper = SystemInstance.get().getComponent(XAResourceWrapper.class);
+ if (xaResourceWrapper != null) {
+ ds = creator.poolManagedWithRecovery(name, xaResourceWrapper, impl.getName(),
properties);
+ } else {
+ ds = creator.poolManaged(name, impl.getName(), properties);
+ }
} else {
- ds = creator.poolManaged(name, impl.getName(), properties);
+ ds = creator.pool(name, impl.getName(), properties);
}
- } else {
- ds = creator.pool(name, impl.getName(), properties);
}
- }
- // ds and creator are associated here, not after the proxying of the next if if active
- creatorByDataSource.put(ds, creator);
+ // ds and creator are associated here, not after the proxying of the next if
if active
+ creatorByDataSource.put(ds, creator);
- if (logSql) {
- ds = (DataSource) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
- new Class<?>[]{DataSource.class},
new LoggingSqlDataSource(ds));
- }
+ if (logSql) {
+ ds = (DataSource) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
+ new Class<?>[]{DataSource.class},
new LoggingSqlDataSource(ds));
+ }
- return ds;
+ return ds;
+ } finally {
+ if (useContainerLoader) {
+ Thread.currentThread().setContextClassLoader(oldLoader);
+ }
+ }
}
private static void convert(final Properties properties, final Duration duration, final
String key, final String oldKey) {
Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/classloader/URLClassLoaderFirst.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/classloader/URLClassLoaderFirst.java?rev=1513074&r1=1513073&r2=1513074&view=diff
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/classloader/URLClassLoaderFirst.java
(original)
+++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/util/classloader/URLClassLoaderFirst.java
Mon Aug 12 08:15:25 2013
@@ -34,6 +34,7 @@ public class URLClassLoaderFirst extends
// log4j is optional, moreover it will likely not work if not skipped and loaded by a
temp classloader
private static final boolean SKIP_LOG4J = "true".equals(SystemInstance.get().getProperty("openejb.skip.log4j",
"true")) && skipLib("org.apache.log4j.Logger");
private static final boolean SKIP_MYFACES = "true".equals(SystemInstance.get().getProperty("openejb.skip.myfaces",
"true")) && skipLib("org.apache.myfaces.spi.FactoryFinderProvider");
+ private static final boolean SKIP_HSQLDB = skipLib("org.hsqldb.lib.HsqlTimer");
// commons-net is only in tomee-plus
private static final boolean SKIP_COMMONS_NET = skipLib("org.apache.commons.net.pop3.POP3Client");
@@ -309,6 +310,7 @@ public class URLClassLoaderFirst extends
}
// other org packages
+ if (org.startsWith("hsqldb.") && SKIP_HSQLDB) return true;
if (org.startsWith("codehaus.swizzle")) return true;
if (org.startsWith("w3c.dom")) return true;
if (org.startsWith("quartz")) return true;
@@ -353,10 +355,7 @@ public class URLClassLoaderFirst extends
try {
final Enumeration<URL> resources = loader.getResources(classname);
final Collection<URL> thisJSf = Collections.list(resources);
- if (thisJSf == null || thisJSf.isEmpty()) {
- return true;
- }
- return thisJSf.size() <= 1;
+ return thisJSf.isEmpty() || thisJSf.size() <= 1;
} catch (final IOException e) {
return true;
}
@@ -392,8 +391,9 @@ public class URLClassLoaderFirst extends
}
public static boolean shouldSkipSlf4j(final ClassLoader loader, final String name) {
- return name != null && name.startsWith("org.slf4j.")
- && loader.getResource(SLF4J_BINDER_CLASS).equals(findParent(loader).getResource(SLF4J_BINDER_CLASS));
+ final URL resource = loader.getResource(SLF4J_BINDER_CLASS);
+ return name != null && name.startsWith("org.slf4j.") && resource
!= null
+ && resource.equals(findParent(loader).getResource(SLF4J_BINDER_CLASS));
}
// useful method for SPI
|