Bug 405261 - [enterprise] Update versions of enterprise components
diff --git a/build.versions b/build.versions
index dd2e5a4..74b9114 100644
--- a/build.versions
+++ b/build.versions
@@ -19,22 +19,30 @@
org.slf4j.jul=1.7.2.v20121108-1250
# Enterprise Compile
-org.apache.openejb.core=4.0.0.beta-2_v201205260545-virgo-7
-org.apache.openejb.loader=4.0.0.beta-2_v201205041336
-org.apache.openejb.jee=4.0.0.beta-2_v201205041336
+org.apache.openejb.core=4.5.2.virgo-1
+org.apache.openejb.loader=4.5.2
+org.apache.openejb.jee=4.5.2
javax.validation=1.0.0.GA_v201205091237
javax.transaction=1.1.1.v201105210645
-org.glassfish.com.sun.faces=2.1.6.v201205171319-virgo-3
+org.glassfish.com.sun.faces=2.1.18.v201304210537-virgo-1
org.ow2.jotm.jotm-core=2.1.9.v201204271116
javax.ejb=3.1.1.v201204261316
org.apache.tomcat.api=7.0.35.v201302120746
javax.persistence=2.0.4.v201112161009
javax.annotation=1.1.0.v201108011116
-org.apache.bval=0.3.0.v201205161050
+org.apache.bval=0.5.0
org.apache.derby=10.8.2.2_v201211210650
org.eclipse.persistence.core=2.4.1.v20121003-ad44345
org.eclipse.persistence.jpa=2.4.1.v20121003-ad44345
-org.apache.openwebbeans.tomcat7=1.1.3.v201210311100
+javassist=3.17.1.GA
+org.apache.xbean.finder=3.12.0.v201304201405
+org.apache.openwebbeans.ee=1.1.7.v201304200545
+org.apache.openwebbeans.ee.common=1.1.7.v201304201405
+org.apache.openwebbeans.impl=1.1.7.v201304201405
+org.apache.openwebbeans.spi=1.1.7.v201304201405
+org.apache.openwebbeans.jsf=1.1.7.v201304201405
+org.apache.openwebbeans.tomcat7=1.1.7.v201304201405
+cdi.api=1.0.0.v201105160744
# Test
ch.qos.logback.classic=1.0.7.v20121108-1250
diff --git a/org.eclipse.virgo.web.enterprise.appdeployer/ivy.xml b/org.eclipse.virgo.web.enterprise.appdeployer/ivy.xml
index 7754f01..1af41e1 100644
--- a/org.eclipse.virgo.web.enterprise.appdeployer/ivy.xml
+++ b/org.eclipse.virgo.web.enterprise.appdeployer/ivy.xml
@@ -13,14 +13,21 @@
</publications>
<dependencies>
- <dependency org="org.eclipse.virgo.mirrored" name="javax.ejb" rev="${javax.ejb}" conf="compile->runtime"/>
- <dependency org="org.eclipse.virgo.mirrored" name="javax.servlet" rev="${javax.servlet}" conf="compile->runtime"/>
- <dependency org="org.eclipse.virgo.mirrored" name="javax.validation" rev="${javax.validation}" conf="compile->runtime"/>
- <dependency org="org.eclipse.virgo.mirrored" name="org.apache.catalina" rev="${org.apache.catalina}" conf="compile->runtime"/>
- <dependency org="org.eclipse.virgo.mirrored" name="org.apache.openejb.core" rev="${org.apache.openejb.core}" conf="compile->runtime"/>
- <dependency org="org.eclipse.virgo.mirrored" name="org.apache.openejb.loader" rev="${org.apache.openejb.loader}" conf="compile->runtime"/>
- <dependency org="org.eclipse.virgo.mirrored" name="org.apache.openejb.jee" rev="${org.apache.openejb.jee}" conf="compile->runtime"/>
- <dependency org="org.eclipse.virgo.mirrored" name="org.eclipse.osgi" rev="${org.eclipse.osgi}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="cdi.api" rev="${cdi.api}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="javax.ejb" rev="${javax.ejb}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="javax.servlet" rev="${javax.servlet}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="javax.validation" rev="${javax.validation}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="org.apache.catalina" rev="${org.apache.catalina}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="org.apache.openejb.core" rev="${org.apache.openejb.core}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="org.apache.openejb.loader" rev="${org.apache.openejb.loader}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="org.apache.openejb.jee" rev="${org.apache.openejb.jee}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="org.apache.openwebbeans.ee" rev="${org.apache.openwebbeans.ee}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="org.apache.openwebbeans.impl" rev="${org.apache.openwebbeans.impl}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="org.apache.openwebbeans.spi" rev="${org.apache.openwebbeans.spi}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="org.apache.openwebbeans.jsf" rev="${org.apache.openwebbeans.jsf}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="org.apache.openwebbeans.tomcat7" rev="${org.apache.openwebbeans.tomcat7}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="org.apache.xbean.finder" rev="${org.apache.xbean.finder}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="org.eclipse.osgi" rev="${org.eclipse.osgi}" conf="compile->runtime"/>
<dependency org="org.eclipse.virgo.mirrored" name="org.slf4j.api" rev="${org.slf4j.api}" conf="compile->runtime"/>
<dependency org="org.eclipse.virgo.medic" name="org.eclipse.virgo.medic" rev="${org.eclipse.virgo.medic}" conf="compile->runtime"/>
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 1add160..5805ff7 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
@@ -65,7 +65,7 @@
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.ContextUtil;
+import org.apache.openejb.util.Contexts;
import org.eclipse.virgo.medic.eventlog.LogEvent;
import org.eclipse.virgo.web.enterprise.openejb.deployer.log.OpenEjbDeployerLogEvents;
import org.osgi.framework.Bundle;
@@ -117,10 +117,12 @@
private Logger logger = LoggerFactory.getLogger(VirgoDeployerEjb.class);
- public VirgoDeployerEjb(String webContextPath, ClassLoader servletClassLoader) {
+ public VirgoDeployerEjb(ServletContext context) {
// this custom deployment loader fixes deployment of archived web apps
// and sets the webcontextPath as moduleId
- deploymentLoader = new VirgoDeploymentLoader(webContextPath);
+ webContextPath = context.getContextPath();
+ servletClassLoader = context.getClassLoader();
+ deploymentLoader = new VirgoDeploymentLoader(context);
dynamicDeployer = OpenEjbDeployerDSComponent.getDynamicDeployer();
if (dynamicDeployer != null) {
configurationFactory = new ConfigurationFactory(false, dynamicDeployer);
@@ -129,8 +131,6 @@
}
assembler = (Assembler) SystemInstance.get().getComponent(org.apache.openejb.spi.Assembler.class);
- this.webContextPath = webContextPath;
- this.servletClassLoader = servletClassLoader;
try {
resourceProviders = ServiceUtils
.getServiceProvidersByServiceType("Resource");
@@ -153,6 +153,8 @@
Properties p = new Properties();
AppModule appModule = null;
+ ClassLoader webAppClassLoader = null;
+
try {
File file = new File(loc);
appModule = deploymentLoader.load(file);
@@ -165,7 +167,10 @@
// set resources
processResources(appModule, standardContext);
+// ClassLoader old = Thread.currentThread().getContextClassLoader();
+// Thread.currentThread().setContextClassLoader(Assembler.class.getClassLoader());
final AppInfo appInfo = configurationFactory.configureApplication(appModule);
+// Thread.currentThread().setContextClassLoader(old);
if (p != null && p.containsKey(OPENEJB_DEPLOYER_FORCED_APP_ID_PROP)) {
appInfo.appId = p.getProperty(OPENEJB_DEPLOYER_FORCED_APP_ID_PROP);
}
@@ -200,6 +205,10 @@
throw (OpenEJBException) e;
}
throw new OpenEJBException("Error while deploying application with real path '" + loc + "' and web context path '" + this.webContextPath + "'.", e);
+ } finally {
+ if(webAppClassLoader != null) {
+ Thread.currentThread().setContextClassLoader(webAppClassLoader);
+ }
}
}
@@ -281,7 +290,7 @@
if(jndiName.contains("comp/BeanManager"))
continue;
this.logger.debug("Binding " + jndiName + " with value " + value);
- ContextUtil.mkdirs(jndiContext, jndiName);
+ Contexts.createSubcontexts(jndiContext, jndiName);
try {
// Note: This will not rebind the DataSources also
jndiContext.bind(jndiName, value);
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 82741e8..215054e 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
@@ -11,18 +11,56 @@
package org.eclipse.virgo.web.enterprise.openejb.deployer;
+import static org.apache.openejb.util.URLs.toFile;
+
import java.io.File;
import java.io.IOException;
+import java.net.MalformedURLException;
import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.TreeMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
+import javax.servlet.ServletContext;
+
+import org.apache.openejb.ClassLoaderUtil;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.config.AppModule;
+import org.apache.openejb.config.ClientModule;
+import org.apache.openejb.config.ConnectorModule;
import org.apache.openejb.config.DeploymentLoader;
+import org.apache.openejb.config.DeploymentModule;
+import org.apache.openejb.config.EjbModule;
+import org.apache.openejb.config.NewLoaderLogic;
+import org.apache.openejb.config.PersistenceModule;
+import org.apache.openejb.config.ReadDescriptors;
+import org.apache.openejb.config.ResourcesModule;
+import org.apache.openejb.config.TldScanner;
+import org.apache.openejb.config.UnknownModuleTypeException;
+import org.apache.openejb.config.UnsupportedModuleTypeException;
+import org.apache.openejb.config.WebModule;
+import org.apache.openejb.config.event.BeforeDeploymentEvent;
+import org.apache.openejb.core.EmptyResourcesClassLoader;
+import org.apache.openejb.jee.Application;
+import org.apache.openejb.jee.Beans;
+import org.apache.openejb.jee.FacesConfig;
+import org.apache.openejb.jee.JspConfig;
+import org.apache.openejb.jee.Taglib;
+import org.apache.openejb.jee.TldTaglib;
+import org.apache.openejb.jee.WebApp;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.util.URLs;
+import org.apache.xbean.finder.ResourceFinder;
/**
*
@@ -33,62 +71,426 @@
public class VirgoDeploymentLoader extends DeploymentLoader {
private static final String VIRGO_ROOT_APPLICATION_RESERVED_MODULE_ID = "virgoRootApplicationReservedModuleID";
- private final String webContextPath;
+ private ServletContext servletContext;
+ private static final String ddDir = "META-INF/";
- public VirgoDeploymentLoader(String webContextPath) {
+ public VirgoDeploymentLoader(ServletContext context) {
super();
- this.webContextPath = webContextPath;
+ this.servletContext = context;
}
@Override
- public AppModule load(File arg0) throws OpenEJBException {
- //Sets the web context path as the moduleId, leaving the original logic unchanged
- AppModule result = super.load(arg0);
- result.setModuleId(createModuleIDFromWebContextPath());
- return result;
+ public AppModule load(final File jarFile) throws OpenEJBException {
+ // verify we have a valid file
+ final String jarPath;
+ try {
+ jarPath = jarFile.getCanonicalPath();
+ } catch (IOException e) {
+ throw new OpenEJBException("Invalid application file path " + jarFile, e);
+ }
+
+ final URL baseUrl = getFileUrl(jarFile);
+
+ // create a class loader to use for detection of module type
+ // do not use this class loader for any other purposes... it is
+ // non-temp class loader and usage will mess up JPA
+ ClassLoader doNotUseClassLoader = null;// = ClassLoaderUtil.createClassLoader(jarPath, new URL[]{baseUrl}, OpenEJB.class.getClassLoader());
+
+ try {
+ // determine the module type
+ final Class<? extends DeploymentModule> moduleClass;
+
+ try {
+ doNotUseClassLoader = ClassLoaderUtil.createClassLoader(jarPath, new URL[]{baseUrl}, getOpenEJBClassLoader());
+ moduleClass = discoverModuleType(baseUrl, ClassLoaderUtil.createTempClassLoader(doNotUseClassLoader), true);
+ } catch (Exception e) {
+ throw new UnknownModuleTypeException("Unable to determine module type for jar: " + baseUrl.toExternalForm(), e);
+ }
+
+ if (ResourcesModule.class.equals(moduleClass)) {
+ final AppModule appModule = new AppModule(null, jarPath);
+ final ResourcesModule module = new ResourcesModule();
+ module.getAltDDs().put("resources.xml", baseUrl);
+ ReadDescriptors.readResourcesXml(module);
+ module.initAppModule(appModule);
+ // here module is no more useful since everything is in the appmodule
+ appModule.setModuleId(createModuleIDFromWebContextPath());
+ return appModule;
+ }
+
+ //We always load AppModule, as it somewhat likes a wrapper module
+ if (AppModule.class.equals(moduleClass)) {
+ AppModule appModule = createAppModule(jarFile, jarPath);
+ appModule.setModuleId(createModuleIDFromWebContextPath());
+ return appModule;
+ }
+
+ if (EjbModule.class.equals(moduleClass)) {
+ final URL[] urls = new URL[]{baseUrl};
+
+ SystemInstance.get().fireEvent(new BeforeDeploymentEvent(urls));
+
+ final AppModule appModule;
+ //final Class<? extends DeploymentModule> o = EjbModule.class;
+ final EjbModule ejbModule = createEjbModule(baseUrl, jarPath, getWebAppClassLoader());
+
+ // wrap the EJB Module with an Application Module
+ appModule = new AppModule(ejbModule);
+
+ addPersistenceUnits(appModule, baseUrl);
+ appModule.setModuleId(createModuleIDFromWebContextPath());
+ return appModule;
+ }
+
+ if (WebModule.class.equals(moduleClass)) {
+ final File file = toFile(baseUrl);
+
+ // Standalone Web Module
+ final WebModule webModule = createWebModule(file.getAbsolutePath(), file.getAbsolutePath(), getOpenEJBClassLoader(), getContextRoot(), getModuleName());
+ // important to use the webapp classloader here otherwise each time we'll check something using loadclass it will fail (=== empty classloader)
+ final AppModule appModule = new AppModule(webModule.getClassLoader(), file.getAbsolutePath(), new Application(), true);
+ addWebModule(webModule, appModule);
+
+ final Map<String, Object> otherDD = new HashMap<String, Object>();
+ final List<URL> urls = webModule.getScannableUrls();
+ final ResourceFinder finder = new ResourceFinder("", urls.toArray(new URL[urls.size()]));
+ otherDD.putAll(getDescriptors(finder, false));
+
+ // "persistence.xml" is done separately since we manage a list of url and not s single url
+ try {
+ final List<URL> persistenceXmls = finder.findAll(ddDir + "persistence.xml");
+ if (persistenceXmls.size() >= 1) {
+ final URL old = (URL) otherDD.get("persistence.xml");
+ if (old != null && !persistenceXmls.contains(old)) {
+ persistenceXmls.add(old);
+ }
+ otherDD.put("persistence.xml", persistenceXmls);
+ }
+ } catch (IOException e) {
+ // ignored
+ }
+
+ addWebPersistenceDD("persistence.xml", otherDD, appModule);
+ addWebPersistenceDD("persistence-fragment.xml", otherDD, appModule);
+ addPersistenceUnits(appModule, baseUrl);
+ appModule.setStandloneWebModule();
+ appModule.setDelegateFirst(false);
+ appModule.setModuleId(createModuleIDFromWebContextPath());
+ return appModule;
+ }
+
+ if (PersistenceModule.class.equals(moduleClass)) {
+ final String jarLocation = URLs.toFilePath(baseUrl);
+ // final ClassLoader classLoader = ClassLoaderUtil.createTempClassLoader(jarPath, new URL[]{baseUrl}, getOpenEJBClassLoader());
+
+ // wrap the EJB Module with an Application Module
+ final AppModule appModule = new AppModule(getWebAppClassLoader(), jarLocation);
+
+ // Persistence Units
+ addPersistenceUnits(appModule, baseUrl);
+ appModule.setModuleId(createModuleIDFromWebContextPath());
+ return appModule;
+ }
+
+ throw new UnsupportedModuleTypeException("Unsupported module type: " + moduleClass.getSimpleName());
+
+ } finally {
+ // if the application was unpacked appId used to create this class loader will be wrong
+ // We can safely destroy this class loader in either case, as it was not use by any modules
+ if (null != doNotUseClassLoader) {
+ ClassLoaderUtil.destroyClassLoader(doNotUseClassLoader);
+ }
+ }
+ }
+
+ private ClassLoader getWebAppClassLoader() {
+ return Thread.currentThread().getContextClassLoader();
}
-
- private String createModuleIDFromWebContextPath() {
- if (this.webContextPath.equals("")) {
- return VIRGO_ROOT_APPLICATION_RESERVED_MODULE_ID;
+
+ @Override
+ public WebModule createWebModule(final String appId, final String warPath, final ClassLoader parentClassLoader, final String contextRoot, final String moduleName) throws OpenEJBException {
+ File warFile = new File(warPath);
+ ArrayList<URL> webUrls = new ArrayList<URL>();
+
+ //we don't care about web.xml here but the rest
+ final Map<String, URL> descriptors;
+ try {
+ descriptors = getWebDescriptors(warFile);
+ } catch (IOException e) {
+ throw new OpenEJBException("Unable to collect descriptors in web module: " + contextRoot, e);
}
- // remove the slash at the beginning of each webContextPath
- return this.webContextPath.substring(1);
- }
+
+ final WebApp webApp;
+ final URL webXmlUrl = descriptors.get("web.xml");
+ if (webXmlUrl != null) {
+ webApp = ReadDescriptors.readWebApp(webXmlUrl);
+ } else {
+ // no web.xml webapp - possible since Servlet 3.0
+ webApp = new WebApp();
+ }
+
+ webUrls.addAll(Arrays.asList(getWebappUrls(warFile)));
+
+ //Original logic kept from OpenEJB:
+ // in TomEE this is done in init hook since we don't manage tomee webapp classloader
+ // so here is not the best idea for tomee
+ // if we want to manage it in a generic way
+ // simply add a boolean shared between tomcat and openejb world
+ // to know if we should fire it or not
+
+ URL[] webUrlsAsArray = webUrls.toArray(new URL[]{});
+
+ SystemInstance.get().fireEvent(new BeforeDeploymentEvent(webUrlsAsArray, parentClassLoader));
+
+
+ // create web module
+ webApp.setVersion("3.0"); //TODO:hardcoded
+ //TODO: we assume here it would be gemini classloader
+ final WebModule webModule = new WebModule(webApp, contextRoot, getWebAppClassLoader(), warFile.getAbsolutePath(), moduleName);
+ webModule.setUrls(webUrls);
+ webModule.getAltDDs().putAll(descriptors);
+ List<URL> filteredURLs = webUrls;
+ File exclusionList = SystemInstance.get().getConf(NewLoaderLogic.EXCLUSION_FILE);
+ try {
+ filteredURLs = filterWebappUrls(webUrlsAsArray, exclusionList.toURL());
+ } catch (MalformedURLException e) {
+ logger.warning("Unable to apply exclusion list " + exclusionList + " to web app urls. Scannable URLs may contain redundant entries", e);
+ }
+ webModule.setScannableUrls(filteredURLs);
+ //If webModule object is loaded by ejbModule or persitenceModule, no need to load tag libraries, web service and JSF related staffs.
+ //Not needed
+ addTagLibraries(webModule);
+
+ // load faces configuration files
+ addFacesConfigs(webModule);
+
+ addBeansXmls(webModule);
+
+ return webModule;
+ }
@Override
protected String getContextRoot() {
- return webContextPath;
+ return servletContext.getContextPath();
}
+
+ private String createModuleIDFromWebContextPath() {
+ String webContextPath = this.servletContext.getContextPath();
+ if (webContextPath.equals("")) {
+ return VIRGO_ROOT_APPLICATION_RESERVED_MODULE_ID;
+ }
+ // remove the slash at the beginning of each webContextPath
+ return webContextPath.substring(1);
+ }
+
+ private void addBeansXmls(final WebModule webModule) {
+ final List<URL> urls = webModule.getScannableUrls();
+
+ final URLClassLoader loader = new URLClassLoader(urls.toArray(new URL[urls.size()]), new EmptyResourcesClassLoader());
- @Override
- protected Map<String, URL> getWebDescriptors(File warFile) throws IOException {
- //Fixes a bug in OpenEjb that prevents recognising web modules when deploying packed web apps
- Map<String, URL> descriptors = new TreeMap<String, URL>();
- if (warFile.isFile()) {
- URL jarURL = new URL("jar", "", -1, warFile.toURI().toURL() + "!/");
- JarFile jarFile = null;
+ final ArrayList<URL> xmls;
+ try {
+ xmls = Collections.list(loader.getResources("META-INF/beans.xml"));
+ xmls.add((URL) webModule.getAltDDs().get("beans.xml"));
+ } catch (IOException e) {
+
+ return;
+ }
+
+ Beans complete = null;
+ for (final URL url : xmls) {
+ if (url == null) continue;
+ complete = mergeBeansXml(complete, url);
+ }
+
+ webModule.getAltDDs().put("beans.xml", complete);
+ }
+
+ private Beans mergeBeansXml(final Beans current, final URL url) {
+ Beans returnValue = current;
+ try {
+ final Beans beans;
try {
- jarFile = new JarFile(warFile);
- for (JarEntry entry : Collections.list(jarFile.entries())) {
- String entryName = entry.getName();
- if (!entry.isDirectory() && entryName.startsWith("WEB-INF/") && entryName.indexOf('/', "WEB-INF".length()) > 0) {
- descriptors.put(entryName, new URL(jarURL, entry.getName()));
+ beans = ReadDescriptors.readBeans(url.openStream());
+ } catch (IOException e) {
+ return returnValue;
+ }
+
+ if (current == null) {
+ returnValue = beans;
+ } else {
+ current.getAlternativeClasses().addAll(beans.getAlternativeClasses());
+ current.getAlternativeStereotypes().addAll(beans.getAlternativeStereotypes());
+ current.getDecorators().addAll(beans.getDecorators());
+ current.getInterceptors().addAll(beans.getInterceptors());
+ }
+ // check is done here since later we lost the data of the origin
+ ReadDescriptors.checkDuplicatedByBeansXml(beans, returnValue);
+ } catch (OpenEJBException e) {
+ logger.error("Unable to read beans.xml from :" + url.toExternalForm());
+ }
+ return returnValue;
+ }
+
+ private void addWebPersistenceDD(final String name, final Map<String, Object> otherDD, final AppModule appModule) {
+ if (otherDD.containsKey(name)) {
+ List<URL> persistenceUrls = (List<URL>) appModule.getAltDDs().get(name);
+ if (persistenceUrls == null) {
+ persistenceUrls = new ArrayList<URL>();
+ appModule.getAltDDs().put(name, persistenceUrls);
+ }
+
+ if (otherDD.containsKey(name)) {
+ final Object otherUrl = otherDD.get(name);
+ if (otherUrl instanceof URL && !persistenceUrls.contains(otherUrl)) {
+ persistenceUrls.add((URL) otherUrl);
+ } else if (otherUrl instanceof List) {
+ final List<URL> otherList = (List<URL>) otherDD.get(name);
+ for (final URL url : otherList) {
+ if (!persistenceUrls.contains(url)) {
+ persistenceUrls.add(url);
+ }
}
}
- } catch (IOException e) {
- // most likely an invalid jar file
- } finally {
- try {
- if (jarFile != null) {
- jarFile.close();
- }
- } catch (IOException e) {
- // do nothing
- }
}
}
- descriptors.putAll(super.getWebDescriptors(warFile));
- return descriptors;
}
+
+ public static Map<String, URL> getDescriptors(final URL moduleUrl) throws OpenEJBException {
+
+ final ResourceFinder finder = new ResourceFinder(moduleUrl);
+ return getDescriptors(finder);
+ }
+
+ private static Map<String, URL> getDescriptors(final ResourceFinder finder) throws OpenEJBException {
+ return getDescriptors(finder, true);
+ }
+
+ private static Map<String, URL> getDescriptors(final ResourceFinder finder, final boolean log) throws OpenEJBException {
+ try {
+
+ return altDDSources(mapDescriptors(finder), log);
+
+ } catch (IOException e) {
+ throw new OpenEJBException("Unable to determine descriptors in jar.", e);
+ }
+ }
+
+
+ /**
+ * Finds all faces configuration files and stores them in the WebModule
+ *
+ * @param webModule WebModule
+ * @throws OpenEJBException
+ */
+ private void addFacesConfigs(final WebModule webModule) throws OpenEJBException {
+ //*************************IMPORTANT*******************************************
+ // TODO : kmalhi :: Add support to scrape META-INF/faces-config.xml in jar files
+ // look at section 10.4.2 of the JSF v1.2 spec, bullet 1 for details
+ final Set<URL> facesConfigLocations = new HashSet<URL>();
+
+ // web.xml contains faces config locations in the context parameter javax.faces.CONFIG_FILES
+ final File warFile = new File(webModule.getJarLocation());
+ final WebApp webApp = webModule.getWebApp();
+ if (webApp != null) {
+ final String foundContextParam = webApp.contextParamsAsMap().get("javax.faces.CONFIG_FILES");
+ if (foundContextParam != null) {
+ // the value is a comma separated list of config files
+ final String commaDelimitedListOfFiles = foundContextParam.trim();
+ final String[] configFiles = commaDelimitedListOfFiles.split(",");
+ // trim any extra spaces in each file
+ final String[] trimmedConfigFiles = new String[configFiles.length];
+ for (int i = 0; i < configFiles.length; i++) {
+ trimmedConfigFiles[i] = configFiles[i].trim();
+ }
+ // convert each file to a URL and add it to facesConfigLocations
+ for (final String location : trimmedConfigFiles) {
+ if (!location.startsWith("/"))
+ logger.error("A faces configuration file should be context relative when specified in web.xml. Please fix the value of context parameter javax.faces.CONFIG_FILES for the file " + location);
+ try {
+ final File file = new File(warFile, location).getCanonicalFile().getAbsoluteFile();
+ final URL url = file.toURI().toURL();
+ facesConfigLocations.add(url);
+
+ } catch (IOException e) {
+ logger.error("Faces configuration file location bad: " + location, e);
+ }
+ }
+ } else {
+ logger.debug("faces config file is null");
+ }
+ }
+
+ // Search for WEB-INF/faces-config.xml
+ final File webInf = new File(warFile, "WEB-INF");
+ if (webInf.isDirectory()) {
+ File facesConfigFile = new File(webInf, "faces-config.xml");
+ if (facesConfigFile.exists()) {
+ try {
+ facesConfigFile = facesConfigFile.getCanonicalFile().getAbsoluteFile();
+ final URL url = facesConfigFile.toURI().toURL();
+ facesConfigLocations.add(url);
+ } catch (IOException e) {
+ // TODO: kmalhi:: Remove the printStackTrace after testing
+ e.printStackTrace();
+ }
+ }
+ }
+ // load the faces configuration files
+ // TODO:kmalhi:: Its good to have separate FacesConfig objects for multiple configuration files, but what if there is a conflict where the same
+ // managebean is declared in two different files, which one wins? -- check the jsf spec, Hopefully JSF should be able to check for this and
+ // flag an error and not allow the application to be deployed.
+ for (final URL location : facesConfigLocations) {
+ final FacesConfig facesConfig = ReadDescriptors.readFacesConfig(location);
+ webModule.getFacesConfigs().add(facesConfig);
+ if ("file".equals(location.getProtocol())) {
+ webModule.getWatchedResources().add(URLs.toFilePath(location));
+ }
+ }
+ }
+
+ private void addTagLibraries(final WebModule webModule) throws OpenEJBException {
+ final Set<URL> tldLocations = new HashSet<URL>();
+
+ // web.xml contains tag lib locations in nested jsp config elements
+ final File warFile = new File(webModule.getJarLocation());
+ final WebApp webApp = webModule.getWebApp();
+ if (webApp != null) {
+ for (final JspConfig jspConfig : webApp.getJspConfig()) {
+ for (final Taglib taglib : jspConfig.getTaglib()) {
+ String location = taglib.getTaglibLocation();
+ if (!location.startsWith("/")) {
+ // this reproduces a tomcat bug
+ location = "/WEB-INF/" + location;
+ }
+ try {
+ final File file = new File(warFile, location).getCanonicalFile().getAbsoluteFile();
+ tldLocations.addAll(TldScanner.scanForTagLibs(file));
+ } catch (IOException e) {
+ logger.warning("JSP tag library location bad: " + location, e);
+ }
+ }
+ }
+ }
+
+ // WEB-INF/**/*.tld except in WEB-INF/classes and WEB-INF/lib
+ Set<URL> urls = TldScanner.scanWarForTagLibs(warFile);
+ tldLocations.addAll(urls);
+
+ // Search all libs
+ final ClassLoader parentClassLoader = webModule.getClassLoader().getParent();
+ urls = TldScanner.scan(parentClassLoader);
+ tldLocations.addAll(urls);
+
+ // load the tld files
+ for (final URL location : tldLocations) {
+ final TldTaglib taglib = ReadDescriptors.readTldTaglib(location);
+ webModule.getTaglibs().add(taglib);
+ if ("file".equals(location.getProtocol())) {
+ webModule.getWatchedResources().add(URLs.toFilePath(location));
+ }
+ }
+ }
+
+
}
diff --git a/org.eclipse.virgo.web.enterprise.appdeployer/src/main/java/org/eclipse/virgo/web/enterprise/openejb/deployer/VirgoUndeployerEjb.java b/org.eclipse.virgo.web.enterprise.appdeployer/src/main/java/org/eclipse/virgo/web/enterprise/openejb/deployer/VirgoUndeployerEjb.java
index 8a9f492..df1bc35 100755
--- a/org.eclipse.virgo.web.enterprise.appdeployer/src/main/java/org/eclipse/virgo/web/enterprise/openejb/deployer/VirgoUndeployerEjb.java
+++ b/org.eclipse.virgo.web.enterprise.appdeployer/src/main/java/org/eclipse/virgo/web/enterprise/openejb/deployer/VirgoUndeployerEjb.java
@@ -54,10 +54,10 @@
ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class);
Context context = containerSystem.getJNDIContext();
if (appForUndeploy != null) {
- Set<ResourceInfo> resources = appForUndeploy.resourceInfos;
- for (ResourceInfo resource : resources) {
+ Set<String> resources = appForUndeploy.resourceIds;
+ for (String resourceId : resources) {
try {
- context.unbind(resource.id);
+ context.unbind(resourceId);
} catch (NamingException e) {
// do nothing
}
diff --git a/org.eclipse.virgo.web.enterprise.appdeployer/template.mf b/org.eclipse.virgo.web.enterprise.appdeployer/template.mf
index 6b54d1c..974bced 100644
--- a/org.eclipse.virgo.web.enterprise.appdeployer/template.mf
+++ b/org.eclipse.virgo.web.enterprise.appdeployer/template.mf
@@ -6,14 +6,17 @@
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Service-Component: OSGI-INF/virgo.web.enterprise.appdeployer.deployer.xml
Import-Template: javax.ejb;version="0",
+ javax.enterprise.inject.spi;version="0",
+ javax.naming;version="0",
javax.servlet;version="0",
javax.validation;version="0",
org.apache.catalina.*;version="${org.apache.catalina:[=.=.=, +1)}",
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.osgi.framework;version="0",
org.eclipse.virgo.medic.*;version="${org.eclipse.virgo.medic:[=.=.=, +1)}",
- org.slf4j;version="0",
- javax.naming;version="0"
+ org.slf4j;version="0"
Excluded-Exports:
*.internal.*
diff --git a/org.eclipse.virgo.web.enterprise.applistener/src/main/java/org/eclipse/virgo/web/enterprise/applistener/internal/OpenEjbApplicationListener.java b/org.eclipse.virgo.web.enterprise.applistener/src/main/java/org/eclipse/virgo/web/enterprise/applistener/internal/OpenEjbApplicationListener.java
index d845694..4f0958d 100755
--- a/org.eclipse.virgo.web.enterprise.applistener/src/main/java/org/eclipse/virgo/web/enterprise/applistener/internal/OpenEjbApplicationListener.java
+++ b/org.eclipse.virgo.web.enterprise.applistener/src/main/java/org/eclipse/virgo/web/enterprise/applistener/internal/OpenEjbApplicationListener.java
@@ -33,8 +33,7 @@
public void deploy(StandardContext standardContext) throws Exception {
ServletContext context = standardContext.getServletContext();
- String contextPath = context.getContextPath();
- VirgoDeployerEjb deployer = new VirgoDeployerEjb(contextPath, context.getClassLoader());
+ VirgoDeployerEjb deployer = new VirgoDeployerEjb(context);
try {
String realPath = context.getRealPath("");
synchronized (monitor) {
@@ -46,7 +45,7 @@
}
} catch (Exception e) {
if (logger.isErrorEnabled()) {
- logger.error("Failed to initialise enterprise container for application with context path '" + contextPath + "'", e);
+ logger.error("Failed to initialise enterprise container for application with context path '" + context.getContextPath() + "'", e);
}
throw e;
}
@@ -55,8 +54,7 @@
// no need to synchronize the undeploy operation as it is stateless
public void undeploy(StandardContext standardContext) throws Exception {
ServletContext context = standardContext.getServletContext();
- String contextPath = context.getContextPath();
- VirgoDeployerEjb deployer = new VirgoDeployerEjb(contextPath, context.getClassLoader());
+ VirgoDeployerEjb deployer = new VirgoDeployerEjb(context);
try {
String realPath = context.getRealPath("");
if (realPath != null) {
@@ -66,7 +64,7 @@
}
} catch (Exception e) {
if (logger.isErrorEnabled()) {
- logger.error("Failed to destroy enterprise container for application with context path '" + contextPath + "'", e);
+ logger.error("Failed to destroy enterprise container for application with context path '" + context.getContextPath() + "'", e);
}
throw e;
}
diff --git a/org.eclipse.virgo.web.enterprise.jsf.support/.classpath b/org.eclipse.virgo.web.enterprise.jsf.support/.classpath
index 8359b66..54060fb 100755
--- a/org.eclipse.virgo.web.enterprise.jsf.support/.classpath
+++ b/org.eclipse.virgo.web.enterprise.jsf.support/.classpath
@@ -1,16 +1,18 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="src/main/resources"/>
- <classpathentry kind="src" path="src/test/java"/>
- <classpathentry kind="src" path="src/main/java"/>
- <classpathentry kind="src" path="src/test/resources"/>
- <classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/javax.annotation/1.1.0.v201108011116/javax.annotation-1.1.0.v201108011116.jar"/>
- <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <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.mirrored/org.glassfish.com.sun.faces/2.1.6.v201205171319-virgo-1/org.glassfish.com.sun.faces-2.1.6.v201205171319-virgo-1.jar"/>
- <classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/javax.persistence/2.0.4.v201112161009/javax.persistence-2.0.4.v201112161009.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="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src/main/resources"/>
+ <classpathentry kind="src" path="src/test/java"/>
+ <classpathentry kind="src" path="src/main/java"/>
+ <classpathentry kind="src" path="src/test/resources"/>
+ <classpathentry kind="var" path="IVY_CACHE/javax.annotation/javax.annotation/1.1.0.v201105051105/javax.annotation-1.1.0.v201105051105.jar"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <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.mirrored/org.glassfish.com.sun.faces/2.1.6.v201205171319-virgo-1/org.glassfish.com.sun.faces-2.1.6.v201205171319-virgo-1.jar"/>
+ <classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/javax.persistence/2.0.4.v201112161009/javax.persistence-2.0.4.v201112161009.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.openwebbeans.impl/1.1.7.v201304201405/org.apache.openwebbeans.impl-1.1.7.v201304201405.jar"/>
+ <classpathentry kind="var" path="IVY_CACHE/org.eclipse.virgo.mirrored/cdi.api/1.0.0.v201105160744/cdi.api-1.0.0.v201105160744.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.virgo.web.enterprise.jsf.support/ivy.xml b/org.eclipse.virgo.web.enterprise.jsf.support/ivy.xml
index 21d5491..2bcf0b8 100644
--- a/org.eclipse.virgo.web.enterprise.jsf.support/ivy.xml
+++ b/org.eclipse.virgo.web.enterprise.jsf.support/ivy.xml
@@ -13,11 +13,13 @@
</publications>
<dependencies>
+ <dependency org="org.eclipse.virgo.mirrored" name="cdi.api" rev="${cdi.api}" conf="compile->runtime"/>
<dependency org="org.eclipse.virgo.mirrored" name="javax.servlet" rev="${javax.servlet}" conf="compile->runtime"/>
<dependency org="org.eclipse.virgo.mirrored" name="org.glassfish.com.sun.faces" rev="${org.glassfish.com.sun.faces}" conf="compile->runtime"/>
<dependency org="org.eclipse.virgo.mirrored" name="javax.ejb" rev="${javax.ejb}" conf="compile->runtime"/>
<dependency org="org.eclipse.virgo.mirrored" name="javax.persistence" rev="${javax.persistence}" conf="compile->runtime"/>
<dependency org="org.eclipse.virgo.mirrored" name="javax.annotation" rev="${javax.annotation}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.mirrored" name="org.apache.openwebbeans.impl" rev="${org.apache.openwebbeans.impl}" conf="compile->runtime"/>
<dependency org="org.eclipse.virgo.mirrored" name="org.apache.catalina" rev="${org.apache.catalina}" conf="compile->runtime"/>
<dependency org="org.eclipse.virgo.mirrored" name="org.slf4j.api" rev="${org.slf4j.api}" conf="compile->runtime"/>
diff --git a/org.eclipse.virgo.web.enterprise.jsf.support/src/main/java/org/eclipse/virgo/web/enterprise/jsf/support/VirgoJsfInjectionProvider.java b/org.eclipse.virgo.web.enterprise.jsf.support/src/main/java/org/eclipse/virgo/web/enterprise/jsf/support/VirgoJsfInjectionProvider.java
index 21076a8..9d02202 100755
--- a/org.eclipse.virgo.web.enterprise.jsf.support/src/main/java/org/eclipse/virgo/web/enterprise/jsf/support/VirgoJsfInjectionProvider.java
+++ b/org.eclipse.virgo.web.enterprise.jsf.support/src/main/java/org/eclipse/virgo/web/enterprise/jsf/support/VirgoJsfInjectionProvider.java
@@ -31,6 +31,8 @@
import com.sun.faces.spi.InjectionProvider;
import com.sun.faces.spi.InjectionProviderException;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.inject.OWBInjector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -55,13 +57,14 @@
public void inject(Object managedBean) throws InjectionProviderException {
// try injecting everything with OWB's injector instance
try {
- ClassLoader tccl = Thread.currentThread().getContextClassLoader();
- if (tccl != null) {
- Class<?> injector = tccl.loadClass("org.apache.webbeans.inject.OWBInjector");
- Object injectorInstance = injector.newInstance();
- Method method = injector.getDeclaredMethod("inject", new Class<?>[] { Object.class });
- injectorInstance = method.invoke(injectorInstance, new Object[] { managedBean });
- }
+ OWBInjector.inject(WebBeansContext.currentInstance().getBeanManagerImpl(), managedBean, null);
+// ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+// if (tccl != null) {
+// Class<?> injector = tccl.loadClass("org.apache.webbeans.inject.OWBInjector");
+// Object injectorInstance = injector.newInstance();
+// Method method = injector.getDeclaredMethod("inject", new Class<?>[] { Object.class });
+// injectorInstance = method.invoke(injectorInstance, new Object[] { managedBean });
+// }
} catch (Exception e) {
if (logger.isErrorEnabled()) {
logger.error("Failed to invoke OWBInjector for managedBean '"+ managedBean.toString() +"', will fallback to manual processing", e);
diff --git a/org.eclipse.virgo.web.enterprise.jsf.support/template.mf b/org.eclipse.virgo.web.enterprise.jsf.support/template.mf
index b3c2964..a377f49 100644
--- a/org.eclipse.virgo.web.enterprise.jsf.support/template.mf
+++ b/org.eclipse.virgo.web.enterprise.jsf.support/template.mf
@@ -11,6 +11,10 @@
com.sun.faces.spi;version="0",
org.apache.naming;version="${org.apache.catalina:[=.=.=, +1)}",
javax.naming;version="0",
- org.slf4j.*;version="0"
+ org.slf4j.*;version="0",
+ org.apache.webbeans.*;version="0",
+ javax.enterprise.context.spi;version="0",
+ javax.enterprise.inject.spi;version="0",
+ org.apache.webbeans.container;version="0"
Excluded-Exports:
*.internal.*
diff --git a/org.eclipse.virgo.web.enterprise.openejb.fragment.webbeans/src/main/resources/META-INF/MANIFEST.MF b/org.eclipse.virgo.web.enterprise.openejb.fragment.webbeans/src/main/resources/META-INF/MANIFEST.MF
index dbf563b..47bc2fa 100755
--- a/org.eclipse.virgo.web.enterprise.openejb.fragment.webbeans/src/main/resources/META-INF/MANIFEST.MF
+++ b/org.eclipse.virgo.web.enterprise.openejb.fragment.webbeans/src/main/resources/META-INF/MANIFEST.MF
@@ -3,8 +3,12 @@
Bundle-Version: 3.6.0.enterprise
Bundle-Name: OpenEjb integration with OpenWebBeans
Bundle-ManifestVersion: 2
-Import-Package: org.apache.webbeans.web.tomcat,org.apache.webbeans.jsf
- .plugin,org.apache.webbeans.jsf.scopes,org.apache.webbeans.jsf
+Import-Package: org.apache.webbeans.ee.beans,
+ org.apache.webbeans.ee.common.beans,
+ org.apache.webbeans.jsf,
+ org.apache.webbeans.jsf.plugin,
+ org.apache.webbeans.web.tomcat,
+ org.slf4j.spi
Bundle-SymbolicName: org.eclipse.virgo.web.enterprise.openejb.fragment.webbeans
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
diff --git a/org.eclipse.virgo.web.enterprise.openejb.fragment.webbeans/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/org.eclipse.virgo.web.enterprise.openejb.fragment.webbeans/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
deleted file mode 100755
index 5c64241..0000000
--- a/org.eclipse.virgo.web.enterprise.openejb.fragment.webbeans/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
+++ /dev/null
@@ -1,18 +0,0 @@
-#Licensed to the Apache Software Foundation (ASF) under one
-#or more contributor license agreements. See the NOTICE file
-#distributed with this work for additional information
-#regarding copyright ownership. The ASF licenses this file
-#to you under the Apache License, Version 2.0 (the
-#"License"); you may not use this file except in compliance
-#with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-#Unless required by applicable law or agreed to in writing,
-#software distributed under the License is distributed on an
-#"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-#KIND, either express or implied. See the License for the
-#specific language governing permissions and limitations
-#under the License.
-
-org.apache.webbeans.jsf.scopes.Jsf2ScopesExtension
\ No newline at end of file
diff --git a/org.eclipse.virgo.web.enterprise.services.accessor/src/main/java/org/eclipse/virgo/web/enterprise/services/accessor/VirgoEEBundleComparable.java b/org.eclipse.virgo.web.enterprise.services.accessor/src/main/java/org/eclipse/virgo/web/enterprise/services/accessor/VirgoEEBundleComparable.java
new file mode 100755
index 0000000..493dba0
--- /dev/null
+++ b/org.eclipse.virgo.web.enterprise.services.accessor/src/main/java/org/eclipse/virgo/web/enterprise/services/accessor/VirgoEEBundleComparable.java
@@ -0,0 +1,42 @@
+package org.eclipse.virgo.web.enterprise.services.accessor;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+
+public class VirgoEEBundleComparable implements Comparator<Bundle> {
+ List<String> orderedImplBundles;
+
+ public VirgoEEBundleComparable() {
+ orderedImplBundles = new ArrayList<String>(WebAppBundleTrackerCustomizer.getBundles(System.getProperty(WebAppBundleTrackerCustomizer.IMPL_BUNDLES)).keySet());
+ }
+
+ @Override
+ public int compare(Bundle b1, Bundle b2) {
+ if(b1 == b2) {
+ return 0;
+ }
+
+ String name1 = b1.getSymbolicName();
+ String name2 = b2.getSymbolicName();
+
+ Integer index1 = orderedImplBundles.indexOf(name1);
+ Integer index2 = orderedImplBundles.indexOf(name2);
+
+ if(index1 == -1 && index2 == -1) {
+ return name1.compareTo(name2);
+ } else if(index1 == -1) {
+ return 1;
+ } else if(index2 == -1) {
+ return -1;
+ } else { //normal int comparison
+ return index1.compareTo(index2);
+ }
+
+ }
+
+}
diff --git a/org.eclipse.virgo.web.enterprise.services.accessor/src/main/java/org/eclipse/virgo/web/enterprise/services/accessor/WebAppBundleClassLoaderDelegateHook.java b/org.eclipse.virgo.web.enterprise.services.accessor/src/main/java/org/eclipse/virgo/web/enterprise/services/accessor/WebAppBundleClassLoaderDelegateHook.java
index 72be765..053514b 100755
--- a/org.eclipse.virgo.web.enterprise.services.accessor/src/main/java/org/eclipse/virgo/web/enterprise/services/accessor/WebAppBundleClassLoaderDelegateHook.java
+++ b/org.eclipse.virgo.web.enterprise.services.accessor/src/main/java/org/eclipse/virgo/web/enterprise/services/accessor/WebAppBundleClassLoaderDelegateHook.java
@@ -14,11 +14,13 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
@@ -28,6 +30,7 @@
import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegateHook;
import org.eclipse.osgi.framework.internal.core.BundleHost;
import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.framework.wiring.BundleWire;
@@ -37,6 +40,8 @@
class WebAppBundleClassLoaderDelegateHook implements ClassLoaderDelegateHook {
+ private static final String GEMINI_WEB_TOMCAT_SYMBOLIC_NAME = "org.eclipse.gemini.web.tomcat";
+
private static final Logger LOGGER = LoggerFactory.getLogger(WebAppBundleClassLoaderDelegateHook.class);
private static final int MAX_API_SEARCH_DEPTH = 1;
@@ -51,14 +56,47 @@
private final Set<Bundle> implBundles = new CopyOnWriteArraySet<Bundle>();
- private final Map<Bundle, ClassLoader> implBundlesClassloaders = new ConcurrentHashMap<Bundle, ClassLoader>();
+ private final Map<Bundle, ClassLoader> implBundlesClassloaders = Collections.synchronizedMap(new TreeMap<Bundle, ClassLoader>(new VirgoEEBundleComparable()));
private final Map<Bundle, Set<String>> webAppBundles = new ConcurrentHashMap<Bundle, Set<String>>();
private final Set<Bundle> postFindApiBundles = new CopyOnWriteArraySet<Bundle>();
+ private Set<String> negativeCacheClassPrefixes = new HashSet<String>();
+
+ WebAppBundleClassLoaderDelegateHook() {
+ negativeCacheClassPrefixes.add("openwebbeans/Messages");
+ negativeCacheClassPrefixes.add("com.sun.faces.LogStrings");
+ negativeCacheClassPrefixes.add("javax.faces.LogStrings");
+ negativeCacheClassPrefixes.add("org.apache.catalina.loader.LocalStrings");
+ negativeCacheClassPrefixes.add("org.apache.tomcat.util.file.LocalStrings");
+ negativeCacheClassPrefixes.add("org.apache.tomcat.util.scan.LocalStrings");
+ negativeCacheClassPrefixes.add("org.apache.tomcat.util.http.mapper.LocalStrings");
+ negativeCacheClassPrefixes.add("org.apache.tomcat.util.net.res.LocalStrings");
+ negativeCacheClassPrefixes.add("org.apache.tomcat.util.threads.res.LocalStrings");
+ negativeCacheClassPrefixes.add("ValidationMessages");
+ negativeCacheClassPrefixes.add("org.apache.bval.jsr303.ValidationMessages");
+ negativeCacheClassPrefixes.add("com.sun.xml.internal.messaging.saaj.soap.LocalStrings");
+ negativeCacheClassPrefixes.add("org.apache.openejb.package-info");
+ negativeCacheClassPrefixes.add("org.apache.openejb.monitoring.package-info");
+ negativeCacheClassPrefixes.add("org.apache.geronimo.openejb.cdi.GeronimoWebBeansPlugin");
+ negativeCacheClassPrefixes.add("org.apache.openejb.server.rest.RsRegistry");
+ negativeCacheClassPrefixes.add("javax.faces.application.ConfigurableNavigationHandlerBeanInfo");
+ negativeCacheClassPrefixes.add("javax.faces.application.NavigationHandlerBeanInfo");
+ negativeCacheClassPrefixes.add("org.apache.webbeans.jsf.ConversationAwareViewHandlerBeanInfo");
+ negativeCacheClassPrefixes.add("javax.faces.application.ViewHandlerWrapperBeanInfo");
+ negativeCacheClassPrefixes.add("javax.faces.application.ViewHandlerBeanInfo");
+ negativeCacheClassPrefixes.add("javax.faces.component.UIViewRootBeanInfo");
+ negativeCacheClassPrefixes.add("javax.faces.component.UIComponentBaseBeanInfo");
+ negativeCacheClassPrefixes.add("javax.faces.component.UIComponentBeanInfo");
+ negativeCacheClassPrefixes.add("javax.management.MBean");
+ // keep javax.management.MBean out of the list:
+ }
@Override
public Class<?> postFindClass(String name, BundleClassLoader bcl, BundleData bd) throws ClassNotFoundException {
+ if(matchesNegativeCache(name)) {
+ return null;
+ }
if (shouldEnter(MAX_IMPL_SEARCH_DEPTH)) {
try {
enter();
@@ -67,7 +105,8 @@
if (this.implBundles.contains(bundle)) {
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
- if (tccl != null) {
+ //TODO: check why openejb tries to load app classes from itself
+ if (tccl != null/* && isBundleWebAppCL(tccl)*/) {
try {
return tccl.loadClass(name);
} catch (ClassNotFoundException e) {
@@ -142,7 +181,7 @@
if (this.implBundles.contains(bundle)) {
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
- if (tccl != null) {
+ if (tccl != null/* && isBundleWebAppCL(tccl)*/) {
return tccl.getResource(name);
}
}
@@ -215,6 +254,9 @@
@Override
public Class<?> preFindClass(String name, BundleClassLoader bcl, BundleData bd) throws ClassNotFoundException {
+ if(matchesNegativeCache(name)) {
+ return null;
+ }
if (shouldEnter(MAX_API_SEARCH_DEPTH)) {
try {
enter();
@@ -424,6 +466,14 @@
return this.implBundles;
}
+ private boolean isBundleWebAppCL(ClassLoader tccl) {
+ Bundle bundle = FrameworkUtil.getBundle(tccl.getClass());
+ if(bundle!= null && bundle.getSymbolicName().equals(GEMINI_WEB_TOMCAT_SYMBOLIC_NAME)) {
+ return true;
+ }
+ return false;
+ }
+
private String getClassPackage(String className) {
int packageNameEndsIndex = className.lastIndexOf(".");
if(packageNameEndsIndex != -1 && packageNameEndsIndex != className.length() -1) {
@@ -432,4 +482,13 @@
return "";
}
+ private boolean matchesNegativeCache(String className) {
+ for(String prefix : negativeCacheClassPrefixes) {
+ if(className.startsWith(prefix)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
}
diff --git a/org.eclipse.virgo.web.enterprise.services.accessor/src/main/java/org/eclipse/virgo/web/enterprise/services/accessor/WebAppBundleTrackerCustomizer.java b/org.eclipse.virgo.web.enterprise.services.accessor/src/main/java/org/eclipse/virgo/web/enterprise/services/accessor/WebAppBundleTrackerCustomizer.java
index 434bc4a..b5e5249 100755
--- a/org.eclipse.virgo.web.enterprise.services.accessor/src/main/java/org/eclipse/virgo/web/enterprise/services/accessor/WebAppBundleTrackerCustomizer.java
+++ b/org.eclipse.virgo.web.enterprise.services.accessor/src/main/java/org/eclipse/virgo/web/enterprise/services/accessor/WebAppBundleTrackerCustomizer.java
@@ -16,6 +16,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -272,8 +273,8 @@
* @param property
* @return
*/
- private Map<String, VersionRange> getBundles(String property) {
- Map<String, VersionRange> bundles = new HashMap<String, VersionRange>();
+ static LinkedHashMap<String, VersionRange> getBundles(String property) {
+ LinkedHashMap<String, VersionRange> bundles = new LinkedHashMap<String, VersionRange>();
if (property != null) {
final List<String> bundleNames = parse(property);
@@ -302,7 +303,7 @@
return bundles;
}
- private List<String> parse(String property) {
+ private static List<String> parse(String property) {
List<String> result = new ArrayList<String>();
int ind = property.indexOf(COMMA_SEPARATOR);
if (ind >= 0) {
diff --git a/org.eclipse.virgo.web.enterprise.services.accessor/src/test/java/org/eclipse/virgo/web/enterprise/services/accessor/VirgoEEBundleComparableTest.java b/org.eclipse.virgo.web.enterprise.services.accessor/src/test/java/org/eclipse/virgo/web/enterprise/services/accessor/VirgoEEBundleComparableTest.java
new file mode 100755
index 0000000..a656566
--- /dev/null
+++ b/org.eclipse.virgo.web.enterprise.services.accessor/src/test/java/org/eclipse/virgo/web/enterprise/services/accessor/VirgoEEBundleComparableTest.java
@@ -0,0 +1,155 @@
+package org.eclipse.virgo.web.enterprise.services.accessor;
+
+import static org.junit.Assert.*;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.easymock.EasyMock;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+
+public class VirgoEEBundleComparableTest {
+
+private static final String BUNDLE2 = "bundle2";
+private static final String BUNDLE1 = "bundle1";
+private static final String ORG_ECLIPSE_PERSISTENCE_CORE = "org.eclipse.persistence.core";
+private static final String ORG_ECLILSE_PERSISTENCE_JPA = "org.eclipse.persistence.jpa";
+private static final String ORG_APACHE_WEBBEANS_WEB = "org.apache.openwebbeans.web";
+private static final String ORG_APACHE_WEBBEANS_IMPL = "org.apache.openwebbeans.impl";
+private static final String ORG_GLASSFISH_COM_SUN_FACES = "org.glassfish.com.sun.faces";
+private static final String OPENEJB_CORE = "org.apache.openejb.core";
+private static final String ORG_APACHE_WEBBEANS_JSF = "org.apache.openwebbeans.jsf";
+
+//"a;bundle-version\\=1.0.0,b;bundle-version\\=1.0.0")
+ @Test
+ public void testCompareTwoNotSpecialBundles() {
+ System.clearProperty(WebAppBundleTrackerCustomizer.IMPL_BUNDLES);
+ VirgoEEBundleComparable comparable = new VirgoEEBundleComparable();
+
+ Bundle b1 = EasyMock.createMock(Bundle.class);
+ Bundle b2 = EasyMock.createMock(Bundle.class);
+
+ EasyMock.expect(b1.getSymbolicName()).andReturn("a");
+ EasyMock.expect(b2.getSymbolicName()).andReturn("b");
+
+ EasyMock.replay(b1, b2);
+
+ assertEquals("When not matching impl.bundles bundles should be sorted alphabetically",-1, comparable.compare(b1, b2));
+ }
+
+ @Test
+ public void testEqualNotBundles() {
+ System.clearProperty(WebAppBundleTrackerCustomizer.IMPL_BUNDLES);
+ VirgoEEBundleComparable comparable = new VirgoEEBundleComparable();
+
+ Bundle b1 = EasyMock.createMock(Bundle.class);
+ EasyMock.expect(b1.getSymbolicName()).andReturn("a");
+
+ EasyMock.replay(b1);
+
+ assertEquals("Exact bundles comparison is wrong", 0, comparable.compare(b1, b1));
+ }
+
+ @Test
+ public void testTwoBundlesSameSymbolicNames() {
+ System.clearProperty(WebAppBundleTrackerCustomizer.IMPL_BUNDLES);
+ VirgoEEBundleComparable comparable = new VirgoEEBundleComparable();
+
+ Bundle b1 = EasyMock.createMock(Bundle.class);
+ Bundle b2 = EasyMock.createMock(Bundle.class);
+
+ EasyMock.expect(b1.getSymbolicName()).andReturn("a");
+ EasyMock.expect(b2.getSymbolicName()).andReturn("a");
+
+ EasyMock.replay(b1, b2);
+
+ assertEquals("Bundles have same symbolic name, should be equal",0, comparable.compare(b1, b2));
+ }
+
+
+ @Test
+ public void testSpecialToNotSpecialBundles() {
+ System.setProperty(WebAppBundleTrackerCustomizer.IMPL_BUNDLES, "b;bundle-version\\=1.0.0");
+ VirgoEEBundleComparable comparable = new VirgoEEBundleComparable();
+
+ Bundle b1 = EasyMock.createMock(Bundle.class);
+ Bundle b2 = EasyMock.createMock(Bundle.class);
+
+ EasyMock.expect(b1.getSymbolicName()).andReturn("a");
+ EasyMock.expect(b2.getSymbolicName()).andReturn("b");
+
+ EasyMock.replay(b1, b2);
+
+ assertEquals("Bundle b is declared as impl - should be less", -1, comparable.compare(b2, b1));
+ }
+
+ @Test
+ public void testTwoSpecialBundles() {
+ System.setProperty(WebAppBundleTrackerCustomizer.IMPL_BUNDLES, "b;bundle-version\\=1.0.0,a;bundle-version\\=1.0.0");
+ VirgoEEBundleComparable comparable = new VirgoEEBundleComparable();
+
+ Bundle b1 = EasyMock.createMock(Bundle.class);
+ Bundle b2 = EasyMock.createMock(Bundle.class);
+
+ EasyMock.expect(b1.getSymbolicName()).andReturn("a");
+ EasyMock.expect(b2.getSymbolicName()).andReturn("b");
+
+ EasyMock.replay(b1, b2);
+
+ assertEquals("Bundle b is declared first in impl.bundles - should be less",-1, comparable.compare(b2, b1));
+ }
+
+ @Test
+ public void realScenarioSimulation() {
+ System.setProperty(WebAppBundleTrackerCustomizer.IMPL_BUNDLES, "org.apache.openejb.core;bundle-version\\=4.5.2.SNAPSHOT,org.apache.openwebbeans.impl;bundle-version\\=1.1.7,org.glassfish.com.sun.faces;bundle-version\\=2.1.6.v201205171319-sap-3,org.apache.openwebbeans.jsf;bundle-version\\=1.1.6,org.eclipse.persistence.jpa;bundle-version\\=2.4.1.v20121003-ad44345,org.eclipse.persistence.core;bundle-version\\=2.4.1.v20121003-ad44345,org.apache.openwebbeans.web;bundle-version\\=1.1.7");
+
+ Bundle openejb = EasyMock.createMock(Bundle.class);
+ Bundle jsf = EasyMock.createMock(Bundle.class);
+ Bundle webbeans_impl = EasyMock.createMock(Bundle.class);
+ Bundle persistence_jpa = EasyMock.createMock(Bundle.class);
+ Bundle persistence_core = EasyMock.createMock(Bundle.class);
+ Bundle webbeans_web = EasyMock.createMock(Bundle.class);
+ Bundle bundle1 = EasyMock.createMock(Bundle.class);
+ Bundle bundle2 = EasyMock.createMock(Bundle.class);
+ Bundle webbeans_jsf = EasyMock.createMock(Bundle.class);
+
+ EasyMock.expect(openejb.getSymbolicName()).andReturn(OPENEJB_CORE).anyTimes();
+ EasyMock.expect(jsf.getSymbolicName()).andReturn(ORG_GLASSFISH_COM_SUN_FACES).anyTimes();
+ EasyMock.expect(webbeans_impl.getSymbolicName()).andReturn(ORG_APACHE_WEBBEANS_IMPL).anyTimes();
+ EasyMock.expect(webbeans_web.getSymbolicName()).andReturn(ORG_APACHE_WEBBEANS_WEB).anyTimes();
+ EasyMock.expect(persistence_jpa.getSymbolicName()).andReturn(ORG_ECLILSE_PERSISTENCE_JPA).anyTimes();
+ EasyMock.expect(persistence_core.getSymbolicName()).andReturn(ORG_ECLIPSE_PERSISTENCE_CORE).anyTimes();
+ EasyMock.expect(bundle1.getSymbolicName()).andReturn(BUNDLE1).anyTimes();
+ EasyMock.expect(bundle2.getSymbolicName()).andReturn(BUNDLE2).anyTimes();
+ EasyMock.expect(webbeans_jsf.getSymbolicName()).andReturn(ORG_APACHE_WEBBEANS_JSF).anyTimes();
+
+ Set<Bundle> sortedBundlesSet = new TreeSet<Bundle>(new VirgoEEBundleComparable());
+
+ EasyMock.replay(openejb, jsf, persistence_jpa, persistence_core, webbeans_web, webbeans_impl, webbeans_jsf, bundle1, bundle2);
+
+ sortedBundlesSet.add(bundle2);
+ sortedBundlesSet.add(bundle1);
+ sortedBundlesSet.add(webbeans_web);
+ sortedBundlesSet.add(persistence_core);
+ sortedBundlesSet.add(persistence_jpa);
+ sortedBundlesSet.add(jsf);
+ sortedBundlesSet.add(openejb);
+ sortedBundlesSet.add(webbeans_impl);
+ sortedBundlesSet.add(webbeans_jsf);
+
+ Bundle[] sortedBundles = sortedBundlesSet.toArray(new Bundle[sortedBundlesSet.size()]);
+ assertEquals(OPENEJB_CORE, sortedBundles[0].getSymbolicName());
+ assertEquals(ORG_APACHE_WEBBEANS_IMPL, sortedBundles[1].getSymbolicName());
+ assertEquals(ORG_GLASSFISH_COM_SUN_FACES, sortedBundles[2].getSymbolicName());
+ assertEquals(ORG_APACHE_WEBBEANS_JSF, sortedBundles[3].getSymbolicName());
+ assertEquals(ORG_ECLILSE_PERSISTENCE_JPA, sortedBundles[4].getSymbolicName());
+ assertEquals(ORG_ECLIPSE_PERSISTENCE_CORE, sortedBundles[5].getSymbolicName());
+ assertEquals(ORG_APACHE_WEBBEANS_WEB, sortedBundles[6].getSymbolicName());
+ assertEquals(BUNDLE1, sortedBundles[7].getSymbolicName());
+ assertEquals(BUNDLE2, sortedBundles[8].getSymbolicName());
+
+ }
+
+
+}
\ No newline at end of file