Bug 418306 - [enterprise] Update of web application fails
diff --git a/org.eclipse.virgo.web.enterprise.appdeployer/.classpath b/org.eclipse.virgo.web.enterprise.appdeployer/.classpath
index db963f3..591e67d 100755
--- a/org.eclipse.virgo.web.enterprise.appdeployer/.classpath
+++ b/org.eclipse.virgo.web.enterprise.appdeployer/.classpath
@@ -6,15 +6,16 @@
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/org.apache.openejb.core/4.0.0.beta-2_v201205260545-virgo-2/org.apache.openejb.core-4.0.0.beta-2_v201205260545-virgo-2.jar" sourcepath="/IVY_CACHE/org.eclipse.virgo.mirrored/org.apache.openejb.core/4.0.0.beta-2_v201205260545-virgo-2/org.apache.openejb.core.source-4.0.0.beta-2_v201205260545-virgo-2.jar"/>
- <classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/org.apache.openejb.loader/4.0.0.beta-2_v201205041336/org.apache.openejb.loader-4.0.0.beta-2_v201205041336.jar"/>
+ <classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/org.apache.openejb.core/4.5.2.virgo-1/org.apache.openejb.core-4.5.2.virgo-1.jar" sourcepath="/IVY_CACHE/org.eclipse.virgo.mirrored/org.apache.openejb.core/4.0.0.beta-2_v201205260545-virgo-2/org.apache.openejb.core.source-4.0.0.beta-2_v201205260545-virgo-2.jar"/>
+ <classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/org.apache.openejb.loader/4.5.2/org.apache.openejb.loader-4.5.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/javax.ejb/3.1.1.v201204261316/javax.ejb-3.1.1.v201204261316.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/org.apache.catalina/7.0.35.v201302131125/org.apache.catalina-7.0.35.v201302131125.jar" sourcepath="/IVY_CACHE/org.eclipse.virgo.mirrored/org.apache.catalina/7.0.35.v201302131125/org.apache.catalina.source-7.0.35.v201302131125.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.medic/org.eclipse.virgo.medic/3.7.0.D-20130521041335/org.eclipse.virgo.medic-3.7.0.D-20130521041335.jar" sourcepath="/IVY_CACHE/org.eclipse.virgo.medic/org.eclipse.virgo.medic/3.1.0.M01/org.eclipse.virgo.medic-sources-3.1.0.M01.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/org.slf4j.api/1.7.2.v20121108-1250/org.slf4j.api-1.7.2.v20121108-1250.jar" sourcepath="/IVY_CACHE/org.eclipse.virgo.mirrored/org.slf4j.api/1.7.2.v20121108-1250/org.slf4j.api.source-1.7.2.v20121108-1250.jar"/>
- <classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/org.apache.openejb.jee/4.0.0.beta-2_v201205041336/org.apache.openejb.jee-4.0.0.beta-2_v201205041336.jar"/>
+ <classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/org.apache.openejb.jee/4.5.2/org.apache.openejb.jee-4.5.2.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/javax.validation/1.0.0.GA_v201205091237/javax.validation-1.0.0.GA_v201205091237.jar"/>
<classpathentry kind="var" path="IVY_CACHE/javax.servlet/javax.servlet/3.0.0.v201103241009/javax.servlet-3.0.0.v201103241009.jar" sourcepath="/IVY_CACHE/javax.servlet/javax.servlet/3.0.0.v201103241009/javax.servlet-sources-3.0.0.v201103241009.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/org.eclipse.osgi/3.8.1.v20120830-144521/org.eclipse.osgi-3.8.1.v20120830-144521.jar" sourcepath="/IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.7.1.R37x_v20110808-1106/org.eclipse.osgi-sources-3.7.1.R37x_v20110808-1106.jar"/>
+ <classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/org.apache.xbean.finder/3.9.0.v201205031350-virgo-1/org.apache.xbean.finder-3.9.0.v201205031350-virgo-1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/org.eclipse.virgo.web.enterprise.appdeployer/src/main/java/org/eclipse/virgo/web/enterprise/openejb/deployer/VirgoDeployerEjb.java b/org.eclipse.virgo.web.enterprise.appdeployer/src/main/java/org/eclipse/virgo/web/enterprise/openejb/deployer/VirgoDeployerEjb.java
index 5805ff7..d4d1329 100755
--- a/org.eclipse.virgo.web.enterprise.appdeployer/src/main/java/org/eclipse/virgo/web/enterprise/openejb/deployer/VirgoDeployerEjb.java
+++ b/org.eclipse.virgo.web.enterprise.appdeployer/src/main/java/org/eclipse/virgo/web/enterprise/openejb/deployer/VirgoDeployerEjb.java
@@ -14,6 +14,8 @@
import static javax.ejb.TransactionManagementType.BEAN;
import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -25,6 +27,7 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.jar.JarFile;
import java.util.Properties;
import java.util.TreeMap;
@@ -61,11 +64,20 @@
import org.apache.openejb.config.DeploymentLoader;
import org.apache.openejb.config.DeploymentModule;
import org.apache.openejb.config.DynamicDeployer;
+import org.apache.openejb.config.FinderFactory;
import org.apache.openejb.config.ServiceUtils;
+import org.apache.openejb.config.WebModule;
+import org.apache.openejb.config.WebappAggregatedArchive;
import org.apache.openejb.config.sys.Resource;
import org.apache.openejb.config.sys.ServiceProvider;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.util.Contexts;
+import org.apache.xbean.finder.AnnotationFinder;
+import org.apache.xbean.finder.IAnnotationFinder;
+import org.apache.xbean.finder.archive.Archive;
+import org.apache.xbean.finder.archive.CompositeArchive;
+import org.apache.xbean.finder.archive.FilteredArchive;
+import org.apache.xbean.finder.archive.JarArchive;
import org.eclipse.virgo.medic.eventlog.LogEvent;
import org.eclipse.virgo.web.enterprise.openejb.deployer.log.OpenEjbDeployerLogEvents;
import org.osgi.framework.Bundle;
@@ -206,12 +218,97 @@
}
throw new OpenEJBException("Error while deploying application with real path '" + loc + "' and web context path '" + this.webContextPath + "'.", e);
} finally {
+ if (appModule != null) {
+ try {
+ closeOpenJars(appModule);
+ } catch (Exception e) {
+ logger.warn("Could not close open application jars");
+ }
+ }
+
if(webAppClassLoader != null) {
Thread.currentThread().setContextClassLoader(webAppClassLoader);
}
}
}
+
+ private void closeOpenJars(AppModule appModule) throws Exception {
+ List<WebModule> webModules = appModule.getWebModules();
+ for (WebModule webModule : webModules) {
+ closeWebModuleOpenJars(webModule);
+ }
+ }
+
+ private void closeWebModuleOpenJars(WebModule webModule) throws Exception {
+ IAnnotationFinder finder = webModule.getFinder();
+ if (finder == null) {
+ logger.debug("The IAnnotationFinder in WebModule [" + webModule + "] is null; no jar closing will be performed");
+ return;
+ }
+ AnnotationFinder annotationFinder = null;
+ if (finder instanceof FinderFactory.ModuleLimitedFinder) {
+ annotationFinder = (AnnotationFinder)((FinderFactory.ModuleLimitedFinder)finder).getDelegate();
+ } else if (finder instanceof AnnotationFinder) {
+ annotationFinder = (AnnotationFinder) finder;
+ }
+
+ if (annotationFinder != null) {
+ WebappAggregatedArchive aggregateArchive = (WebappAggregatedArchive) annotationFinder.getArchive();
+
+ // get internal CompositeArchive
+ Field archive = WebappAggregatedArchive.class.getDeclaredField("archive");
+ archive.setAccessible(true);
+ CompositeArchive compositeArchive = (CompositeArchive)archive.get(aggregateArchive);
+ archive.setAccessible(false);
+
+ // get internal list of FilteredArchives
+ handleCompositeArchive(compositeArchive);
+ }
+ }
+
+ private void handleArchivesList(List<Archive> archives) throws Exception {
+ for (Archive arch : archives) {
+ handleArchive(arch);
+ }
+ }
+
+ private void handleCompositeArchive(CompositeArchive compositeArchive) throws Exception {
+ Field archives = CompositeArchive.class.getDeclaredField("archives");
+ archives.setAccessible(true);
+ List<Archive> internalArchives = (List<Archive>)archives.get(compositeArchive);
+ archives.setAccessible(false);
+ handleArchivesList(internalArchives);
+ }
+
+ private void handleFilteredArchive(FilteredArchive filteredArchive) throws Exception {
+ Field internalArchiveField = FilteredArchive.class.getDeclaredField("archive");
+ internalArchiveField.setAccessible(true);
+ Archive internalArchive = (Archive)internalArchiveField.get(filteredArchive);
+ internalArchiveField.setAccessible(false);
+ handleArchive(internalArchive);
+ }
+
+ private void handleArchive(Archive arch) throws Exception {
+ if (arch instanceof FilteredArchive) {
+ FilteredArchive filteredArchive = (FilteredArchive) arch;
+ handleFilteredArchive(filteredArchive);
+ } else if (arch instanceof CompositeArchive) {
+ CompositeArchive compositeArchive = (CompositeArchive) arch;
+ handleCompositeArchive(compositeArchive);
+ } else if (arch instanceof JarArchive) {
+ JarArchive jarArchive = (JarArchive) arch;
+ Field jarField = JarArchive.class.getDeclaredField("jar");
+ jarField.setAccessible(true);
+ JarFile jar = (JarFile)jarField.get(jarArchive);
+ jarField.setAccessible(false);
+ try {
+ jar.close();
+ } catch(IOException e) {
+ // do nothing
+ }
+ }
+ }
private boolean isAppBringingOwnPersistence(StandardContext standardContext) {
ServletContext servletContext = standardContext.getServletContext();
diff --git a/org.eclipse.virgo.web.enterprise.appdeployer/src/main/java/org/eclipse/virgo/web/enterprise/openejb/deployer/VirgoDeploymentLoader.java b/org.eclipse.virgo.web.enterprise.appdeployer/src/main/java/org/eclipse/virgo/web/enterprise/openejb/deployer/VirgoDeploymentLoader.java
index 215054e..521d03d 100755
--- a/org.eclipse.virgo.web.enterprise.appdeployer/src/main/java/org/eclipse/virgo/web/enterprise/openejb/deployer/VirgoDeploymentLoader.java
+++ b/org.eclipse.virgo.web.enterprise.appdeployer/src/main/java/org/eclipse/virgo/web/enterprise/openejb/deployer/VirgoDeploymentLoader.java
@@ -295,6 +295,8 @@
} catch (IOException e) {
return;
+ } finally {
+ ClassLoaderUtil.destroyClassLoader(loader);
}
Beans complete = null;
diff --git a/org.eclipse.virgo.web.enterprise.appdeployer/template.mf b/org.eclipse.virgo.web.enterprise.appdeployer/template.mf
index 974bced..fc4b020 100644
--- a/org.eclipse.virgo.web.enterprise.appdeployer/template.mf
+++ b/org.eclipse.virgo.web.enterprise.appdeployer/template.mf
@@ -14,7 +14,7 @@
org.apache.naming.*;version="${org.apache.catalina:[=.=.=, +1)}",
org.apache.openejb.*;version="0",
org.apache.webbeans.*;version="0",
- org.apache.xbean.finder;version="0",
+ org.apache.xbean.finder.*;version="0",
org.osgi.framework;version="0",
org.eclipse.virgo.medic.*;version="${org.eclipse.virgo.medic:[=.=.=, +1)}",
org.slf4j;version="0"