You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mu...@apache.org on 2009/04/07 20:00:05 UTC

svn commit: r762880 - in /struts/sandbox/trunk/struts2-osgi-plugin/plugin: ./ src/main/java/org/apache/struts2/osgi/ src/main/resources/

Author: musachy
Date: Tue Apr  7 18:00:04 2009
New Revision: 762880

URL: http://svn.apache.org/viewvc?rev=762880&view=rev
Log:
Add Spring OSGi support

Added:
    struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/SpringOsgiObjectFactory.java
Modified:
    struts/sandbox/trunk/struts2-osgi-plugin/plugin/pom.xml
    struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java
    struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java
    struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java
    struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/FelixOsgiHost.java
    struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
    struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiHost.java
    struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiUtil.java
    struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-plugin.xml

Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/pom.xml
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/pom.xml?rev=762880&r1=762879&r2=762880&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/pom.xml (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/pom.xml Tue Apr  7 18:00:04 2009
@@ -45,19 +45,6 @@
         </dependency>
 
         <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.fileinstall</artifactId>
-            <version>0.9.0</version>
-
-            <exclusions>
-                <exclusion>
-                    <groupId>org.apache.felix</groupId>
-                    <artifactId>javax.servlet</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
             <groupId>org.apache.struts</groupId>
             <artifactId>struts2-core</artifactId>
             <version>2.1.7-SNAPSHOT</version>

Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java?rev=762880&r1=762879&r2=762880&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundleAccessor.java Tue Apr  7 18:00:04 2009
@@ -15,7 +15,7 @@
 
     String CURRENT_BUNDLE_NAME = "__bundle_name__";
 
-    void init(Map<String, Bundle> bundles, BundleContext bundleContext, Map<String, String> packageToBundle);
+    void init(Map<String, Bundle> bundles, Map<String, String> packageToBundle);
 
     Class loadClass(String name) throws ClassNotFoundException;
 
@@ -31,5 +31,11 @@
 
     ServiceReference getServiceReference(String className);
 
+    ServiceReference[] getServiceReferences(String className, String params) throws InvalidSyntaxException;
+
+    public ServiceReference[] getAllServiceReferences(String className);
+
     void addPackageFromBundle(Bundle bundle, String packageName);
+
+    void setBundleContext(BundleContext bundleContext);
 }

Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java?rev=762880&r1=762879&r2=762880&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/BundlePackageLoader.java Tue Apr  7 18:00:04 2009
@@ -68,30 +68,6 @@
             Enumeration<URL> e = bundle.getResources("struts.xml");
             return e.hasMoreElements() ? new EnumeratorIterator<URL>(e) : null;
         }
-        
-        /* 
-         * Try to find the class (className) on this bundle. If the class it not found,
-         * try to find an Spring bean with that name. 
-         */
-        @Override
-        protected boolean verifyAction(String className, String name, Location loc) {
-            try {
-                return bundle.loadClass(className) != null;
-            } catch (Exception e) {
-                if (LOG.isDebugEnabled())
-                    LOG.debug("Unable to find class [#0] in bundle [#1]", className, bundle.getSymbolicName());
-
-                //try to find a bean with that id
-                try {
-                    return OsgiUtil.isValidBean(bundleContext, className);
-                } catch (Exception e1) {
-                    if (LOG.isDebugEnabled())
-                        LOG.debug("Unable to find bean [#0]", className);
-                }
-                
-                return false;
-            }
-        }
     }
     
     static class EnumeratorIterator<E> implements Iterator<E> {

Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java?rev=762880&r1=762879&r2=762880&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/DefaultBundleAccessor.java Tue Apr  7 18:00:04 2009
@@ -41,16 +41,33 @@
     }
 
     public Object getService(ServiceReference ref) {
-        return bundleContext.getService(ref);
+        return bundleContext != null ? bundleContext.getService(ref) : null;
     }
 
     public ServiceReference getServiceReference(String className) {
-        return bundleContext.getServiceReference(className);
+        return bundleContext != null ? bundleContext.getServiceReference(className) : null;
     }
 
-    public void init(Map<String, Bundle> bundles, BundleContext bundleContext, Map<String, String> packageToBundle) {
+    public ServiceReference[] getAllServiceReferences(String className) {
+        if (bundleContext != null) {
+            try {
+                return bundleContext.getServiceReferences(className, null);
+            } catch (InvalidSyntaxException e) {
+                //cannot happen we are passing null as the param
+                if (LOG.isErrorEnabled())
+                    LOG.error("Invalid syntaxt for service lookup", e);
+            }
+        }
+
+        return null;
+    }
+
+    public ServiceReference[] getServiceReferences(String className, String params) throws InvalidSyntaxException {
+        return bundleContext != null ? bundleContext.getServiceReferences(className, params) : null;
+    }
+
+    public void init(Map<String, Bundle> bundles, Map<String, String> packageToBundle) {
         this.bundles = Collections.unmodifiableMap(bundles);
-        this.bundleContext = bundleContext;
         this.packageToBundle = packageToBundle;
         this.packagesByBundle = new HashMap<Bundle, Set<String>>();
         for (Map.Entry<String, String> entry : packageToBundle.entrySet()) {
@@ -93,18 +110,6 @@
         }
 
         if (cls == null) {
-            //try to find a bean with that id (hack for spring that searches all bundles)
-            try {
-                Object bean = OsgiUtil.getBean(bundleContext, className);
-                if (bean != null)
-                    cls = bean.getClass();
-            } catch (Exception e) {
-                if (LOG.isDebugEnabled())
-                    LOG.debug("Unable to find bean [#0]", className);
-            }
-        }
-
-        if (cls == null) {
             throw new ClassNotFoundException("Unable to find class " + className + " in bundles");
         }
         return cls;
@@ -199,4 +204,8 @@
         }
         return null;
     }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
 }

Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/FelixOsgiHost.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/FelixOsgiHost.java?rev=762880&r1=762879&r2=762880&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/FelixOsgiHost.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/FelixOsgiHost.java Tue Apr  7 18:00:04 2009
@@ -26,18 +26,20 @@
 import com.opensymphony.xwork2.util.finder.ResourceFinder;
 import com.opensymphony.xwork2.util.logging.Logger;
 import com.opensymphony.xwork2.util.logging.LoggerFactory;
+import com.opensymphony.xwork2.ActionContext;
 import org.apache.commons.lang.xwork.StringUtils;
 import org.apache.felix.framework.Felix;
 import org.apache.felix.framework.util.FelixConstants;
 import org.apache.felix.main.AutoActivator;
 import org.apache.felix.main.Main;
 import org.apache.felix.shell.ShellService;
+import org.apache.struts2.StrutsStatics;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.Constants;
-import org.osgi.service.log.LogService;
 import org.osgi.util.tracker.ServiceTracker;
 
+import javax.servlet.ServletContext;
 import java.io.File;
 import java.io.FilenameFilter;
 import java.io.IOException;
@@ -63,16 +65,13 @@
 public class FelixOsgiHost implements OsgiHost {
     private static final Logger LOG = LoggerFactory.getLogger(FelixOsgiHost.class);
 
-    private static final String FELIX_FILEINSTALL_POLL = "felix.fileinstall.poll";
-    private static final String FELIX_FILEINSTALL_DIR = "felix.fileinstall.dir";
-    private static final String FELIX_FILEINSTALL_DEBUG = "felix.fileinstall.debug";
-
     private Felix felix;
     private Map<String, Bundle> bundles = Collections.synchronizedMap(new HashMap<String, Bundle>());
     private List<? extends BundleActivator> extraBundleActivators;
     private boolean cleanBundleCache;
     private static Pattern versionPattern = Pattern.compile("([\\d])+[\\.-]");
     private String startRunLevel;
+    private ServletContext servletContext;
 
     protected void startFelix() {
         //load properties from felix embedded file
@@ -90,13 +89,10 @@
         int bundlePaths = addAutoStartBundles(configProps);
 
         // Bundle cache
-        configProps.setProperty(Constants.FRAMEWORK_STORAGE, System.getProperty("java.io.tmpdir") + ".felix-cache");
-
-        // File Install
-        /*String bundlesDir = Thread.currentThread().getContextClassLoader().getResource("bundles").getPath();
-        configProps.put(OsgiConfigurationProvider.FELIX_FILEINSTALL_POLL, "5000");
-        configProps.put(OsgiConfigurationProvider.FELIX_FILEINSTALL_DIR, bundlesDir);
-        configProps.put(OsgiConfigurationProvider.FELIX_FILEINSTALL_DEBUG, "1");*/
+        String storageDir = System.getProperty("java.io.tmpdir") + ".felix-cache";
+        configProps.setProperty(Constants.FRAMEWORK_STORAGE, storageDir);
+        if (LOG.isDebugEnabled())
+            LOG.debug("Storing bundle at [#0]", storageDir);
 
         if (cleanBundleCache) {
             if (LOG.isDebugEnabled())
@@ -108,7 +104,7 @@
         configProps.put(FelixConstants.SERVICE_URLHANDLERS_PROP, "false");
         configProps.put(FelixConstants.LOG_LEVEL_PROP, "4");
         configProps.put(FelixConstants.BUNDLE_CLASSPATH, ".");
-        configProps.put(FelixConstants.FRAMEWORK_BEGINNING_STARTLEVEL, startRunLevel);        
+        configProps.put(FelixConstants.FRAMEWORK_BEGINNING_STARTLEVEL, startRunLevel);
 
         try {
             List<BundleActivator> list = new ArrayList<BundleActivator>();
@@ -134,6 +130,8 @@
                 LOG.error("An error occured while waiting for bundle activation", e);
             }
         }
+
+        addSpringOSGiSupport();
     }
 
     private int addAutoStartBundles(Properties configProps) {
@@ -141,20 +139,34 @@
         List<String> bundleJarsLevel1 = new ArrayList<String>();
         bundleJarsLevel1.add(getJarUrl(ShellService.class));
         bundleJarsLevel1.add(getJarUrl(ServiceTracker.class));
-        bundleJarsLevel1.add(getJarUrl(LogService.class));
+
+        //add third party bundles in level 2
+        List<String> bundleJarsLevel2 = new ArrayList<String>();
+        bundleJarsLevel2.addAll(getBundlesInDir("bundles/other"));
+
+        //start app bundles in level 3
+        List<String> bundleJarsLevel3 = new ArrayList<String>();
+        bundleJarsLevel2.addAll(getBundlesInDir("bundles"));
+
 
         configProps.put(AutoActivator.AUTO_START_PROP + ".1", StringUtils.join(bundleJarsLevel1, " "));
+        configProps.put(AutoActivator.AUTO_START_PROP + ".2", StringUtils.join(bundleJarsLevel2, " "));
+        configProps.put(AutoActivator.AUTO_START_PROP + ".3", StringUtils.join(bundleJarsLevel3, " "));
 
-        //start app bundles in level2
-        List<String> bundleJarsLevel2 = new ArrayList<String>();
+
+        return bundleJarsLevel1.size() + bundleJarsLevel2.size() + bundleJarsLevel3.size();
+    }
+
+    private List<String> getBundlesInDir(String dir) {
+        List<String> bundleJars = new ArrayList<String>();
         try {
+
             ResourceFinder finder = new ResourceFinder();
-            URL url = finder.find("bundles");
+            URL url = finder.find(dir);
             if (url != null) {
                 if ("file".equals(url.getProtocol())) {
                     File bundlerDir = new File(url.toURI());
                     File[] bundles = bundlerDir.listFiles(new FilenameFilter() {
-                        @Override
                         public boolean accept(File file, String name) {
                             return StringUtils.endsWith(name, ".jar");
                         }
@@ -166,26 +178,41 @@
                             String externalForm = bundle.toURI().toURL().toExternalForm();
                             if (LOG.isDebugEnabled())
                                 LOG.debug("Adding bundle [#0]", externalForm);
-                            bundleJarsLevel2.add(externalForm);
-                         }
+                            bundleJars.add(externalForm);
+                        }
 
                     } else if (LOG.isDebugEnabled()) {
-                        LOG.debug("No bundles found under the 'bundles' directory");
+                        LOG.debug("No bundles found under the [#0] directory", dir);
                     }
                 } else if (LOG.isWarnEnabled())
-                    LOG.warn("Unable to read 'bundles' directory");
+                    LOG.warn("Unable to read [#0] directory", dir);
             } else if (LOG.isWarnEnabled())
-                LOG.warn("The 'bundles' directory was not found");
+                LOG.warn("The [#0] directory was not found", dir);
         } catch (Exception e) {
             if (LOG.isWarnEnabled())
-                LOG.warn("Unable load bundles from the 'bundles' directory", e);
-            return 0;
+                LOG.warn("Unable load bundles from the [#0] directory", e, dir);
         }
+        return bundleJars;
+    }
 
-        //autostart bundles in leve 2
-        configProps.put(AutoActivator.AUTO_START_PROP + ".2", StringUtils.join(bundleJarsLevel2, " "));
-
-        return bundleJarsLevel1.size() + bundleJarsLevel2.size();
+    private void addSpringOSGiSupport() {
+        // see the javadoc for org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext for more details
+        // OsgiBundleXmlWebApplicationContext expects the the BundleContext to be set in the ServletContext under the attribute
+        // OsgiBundleXmlWebApplicationContext.BUNDLE_CONTEXT_ATTRIBUTE
+        try {
+            Class clazz = Class.forName("org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext");
+            String key = (String) clazz.getDeclaredField("BUNDLE_CONTEXT_ATTRIBUTE").get(null);
+            servletContext.setAttribute(key, felix.getBundleContext());
+        } catch (ClassNotFoundException e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Spring OSGi support is not enabled");
+            }
+        } catch (Exception e) {
+            if (LOG.isErrorEnabled()) {
+                LOG.error("The API of Spring OSGi has changed and the field [#0] is no longer available. The OSGi plugin needs to be updated", e,
+                        "org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext.BUNDLE_CONTEXT_ATTRIBUTE");
+            }
+        }
     }
 
     private String getJarUrl(Class clazz) {
@@ -275,7 +302,7 @@
     static String getVersionFromString(String str) {
         Matcher matcher = versionPattern.matcher(str);
         List<String> parts = new ArrayList<String>();
-        while(matcher.find()) {
+        while (matcher.find()) {
             parts.add(matcher.group(1));
         }
 
@@ -283,7 +310,7 @@
         if (parts.size() == 0)
             return "1.0.0";
 
-        while(parts.size() < 3)
+        while (parts.size() < 3)
             parts.add("0");
 
         return StringUtils.join(parts, ".");
@@ -294,8 +321,8 @@
         try {
             return finder.findProperties(fileName);
         } catch (IOException e) {
-           if (LOG.isErrorEnabled())
-               LOG.error("Unable to read property file [#]", fileName);
+            if (LOG.isErrorEnabled())
+                LOG.error("Unable to read property file [#]", fileName);
             return new Properties();
         }
     }
@@ -308,7 +335,11 @@
     }
 
     public Map<String, Bundle> getBundles() {
-        return bundles;
+        return Collections.unmodifiableMap(bundles);
+    }
+
+    public void addBundle(Bundle bundle) {
+        bundles.put(bundle.getSymbolicName(), bundle);
     }
 
     public void destroy() throws Exception {
@@ -333,4 +364,9 @@
     public void setStartRunLevel(String startRunLevel) {
         this.startRunLevel = startRunLevel;
     }
+
+    @Inject
+    public void setServletContext(ServletContext servletContext) {
+        this.servletContext = servletContext;
+    }
 }

Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java?rev=762880&r1=762879&r2=762880&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java Tue Apr  7 18:00:04 2009
@@ -78,6 +78,7 @@
         } catch (InvalidSyntaxException e) {
             throw new ConfigurationException(e);
         }
+        
         Map<String, String> packageToBundle = new HashMap<String, String>();
         Set<String> bundleNames = new HashSet<String>();
         if (refs != null) {
@@ -96,7 +97,7 @@
                 }
             }
         }
-        bundleAccessor.init(osgiHost.getBundles(), bundleContext, packageToBundle);
+        bundleAccessor.init(osgiHost.getBundles(), packageToBundle);
 
         //reload container that will load configuration based on bundles (like convention plugin)
         reloadExtraProviders(configuration.getContainer());
@@ -185,6 +186,7 @@
         public void start(BundleContext context) throws Exception {
             context.addBundleListener(this);
             bundleContext = context;
+            bundleAccessor.setBundleContext(bundleContext);
         }
 
         public void stop(BundleContext ctx) throws Exception {
@@ -195,7 +197,7 @@
                 if (LOG.isDebugEnabled())
                     LOG.debug("Started bundle [#0]", evt.getBundle().getSymbolicName());
 
-                osgiHost.getBundles().put(evt.getBundle().getSymbolicName(), evt.getBundle());
+                osgiHost.addBundle(evt.getBundle());
                 bundlesChanged = true;
             }
         }

Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiHost.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiHost.java?rev=762880&r1=762879&r2=762880&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiHost.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiHost.java Tue Apr  7 18:00:04 2009
@@ -31,4 +31,5 @@
     void init() throws Exception;
     void setExtraBundleActivators(List<? extends BundleActivator> extraBundleActivators);
     Map<String, Bundle> getBundles();
+    void addBundle(Bundle bundle);
 }

Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiUtil.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiUtil.java?rev=762880&r1=762879&r2=762880&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiUtil.java (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/OsgiUtil.java Tue Apr  7 18:00:04 2009
@@ -15,28 +15,6 @@
 public class OsgiUtil {
     private static final Logger LOG = LoggerFactory.getLogger(OsgiUtil.class);
 
-    public static boolean isValidBean(BundleContext bundleContext, String beanId) throws InvalidSyntaxException, SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-        return getBean(bundleContext, beanId) != null;
-    }
-
-    public static Object getBean(BundleContext bundleContext, String beanId) throws InvalidSyntaxException, SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-        ServiceReference[] references = bundleContext.getAllServiceReferences(
-                "org.springframework.context.ApplicationContext", null);
-        if (references != null && references.length > 0) {
-            Object beanFactory = bundleContext.getService(references[0]);
-            //this class and the BeanFactory service are loaded by different classloaders
-            //so we cannot cast to a common interface (is there any other (nice) way of doing this?)
-            return getBean(beanFactory, beanId);
-        }
-
-        return null;
-    }
-
-    private static Object getBean(Object beanFactory, String beanId) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
-        Method getBeanMethod = beanFactory.getClass().getMethod("getBean", String.class);
-        return getBeanMethod.invoke(beanFactory, beanId);
-    }
-
     /**
      * A bundle is a jar, and a bunble URL will be useless to clients, this method translates
      * a URL to a resource inside a bundle from "bundle:something/path" to "jar:file:bundlelocation!/path"
@@ -52,4 +30,36 @@
 
         return bundleUrl;
     }
+
+    /**
+     * Calls getBean() on the passed object using refelection. Used on Spring context
+     * because they are loaded from bundles (in anothe class loader)
+     */
+    public static Object getBean(Object beanFactory, String beanId) {
+        try {
+            Method getBeanMethod = beanFactory.getClass().getMethod("getBean", String.class);
+            return getBeanMethod.invoke(beanFactory, beanId);
+        } catch (Exception ex) {
+            if (LOG.isErrorEnabled())
+                LOG.error("Unable to call getBean() on object of type [#0], with bean id [#1]", ex, beanFactory.getClass().getName(), beanId);
+        }
+
+        return null;
+    }
+
+    /**
+     * Calls containsBean on the passed object using refelection. Used on Spring context
+     * because they are loaded from bundles (in anothe class loader)
+     */
+    public static boolean containsBean(Object beanFactory, String beanId) {
+        try {
+            Method getBeanMethod = beanFactory.getClass().getMethod("containsBean", String.class);
+            return (Boolean) getBeanMethod.invoke(beanFactory, beanId);
+        } catch (Exception ex) {
+            if (LOG.isErrorEnabled())
+                LOG.error("Unable to call containsBean() on object of type [#0], with bean id [#1]", ex, beanFactory.getClass().getName(), beanId);
+        }
+
+        return false;
+    }
 }

Added: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/SpringOsgiObjectFactory.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/SpringOsgiObjectFactory.java?rev=762880&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/SpringOsgiObjectFactory.java (added)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/java/org/apache/struts2/osgi/SpringOsgiObjectFactory.java Tue Apr  7 18:00:04 2009
@@ -0,0 +1,76 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+package org.apache.struts2.osgi;
+
+import com.opensymphony.xwork2.ObjectFactory;
+import com.opensymphony.xwork2.inject.Inject;
+import org.osgi.framework.ServiceReference;
+
+import java.util.Map;
+
+public class SpringOsgiObjectFactory extends ObjectFactory {
+    private final static String SPRING_SERVICE_NAME = "org.springframework.context.ApplicationContext";
+
+    private BundleAccessor bundleAccessor;
+
+    public Object buildBean(String className, Map<String, Object> extraContext, boolean injectInternal) throws Exception {
+        return containsBean(className) ? getBean(className) : super.buildBean(className, extraContext);
+    }
+
+    public Object buildBean(Class clazz, Map<String, Object> extraContext) throws Exception {
+        return clazz.newInstance();
+    }
+
+    public Class getClassInstance(String className) throws ClassNotFoundException {
+        return containsBean(className) ? getBean(className).getClass() : super.getClassInstance(className);
+    }
+
+    protected Object getBean(String beanName) {
+        ServiceReference[] refs = bundleAccessor.getAllServiceReferences(SPRING_SERVICE_NAME);
+        if (refs != null) {
+            for (ServiceReference ref : refs) {
+                Object context = bundleAccessor.getService(ref);
+                if (OsgiUtil.containsBean(context, beanName))
+                    return OsgiUtil.getBean(context, beanName);
+            }
+        }
+
+        return null;
+    }
+
+    protected boolean containsBean(String beanName) {
+        ServiceReference[] refs = bundleAccessor.getAllServiceReferences(SPRING_SERVICE_NAME);
+        if (refs != null) {
+            for (ServiceReference ref : refs) {
+                Object context = bundleAccessor.getService(ref);
+                if (OsgiUtil.containsBean(context, beanName))
+                    return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Inject
+    public void setBundleAccessor(BundleAccessor bundleAccessor) {
+        this.bundleAccessor = bundleAccessor;
+    }
+}

Modified: struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-plugin.xml
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-plugin.xml?rev=762880&r1=762879&r2=762880&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-plugin.xml (original)
+++ struts/sandbox/trunk/struts2-osgi-plugin/plugin/src/main/resources/struts-plugin.xml Tue Apr  7 18:00:04 2009
@@ -1,17 +1,10 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 
 <!DOCTYPE struts PUBLIC
-    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
-    "http://struts.apache.org/dtds/struts-2.0.dtd">
-    
-<struts>
-    <bean type="org.apache.struts2.osgi.BundleAccessor" class="org.apache.struts2.osgi.DefaultBundleAccessor" />
-    <bean type="org.apache.struts2.osgi.PackageLoader" class="org.apache.struts2.osgi.BundlePackageLoader" />
-    <bean name="osgi" type="com.opensymphony.xwork2.ObjectFactory" class="org.apache.struts2.osgi.DelegatingObjectFactory" />
-    <bean name="osgi" type="com.opensymphony.xwork2.config.PackageProvider" class="org.apache.struts2.osgi.OsgiConfigurationProvider" />
-    <bean name="felix" type="org.apache.struts2.osgi.OsgiHost" class="org.apache.struts2.osgi.FelixOsgiHost" />
-    <bean name="osgi" type="com.opensymphony.xwork2.util.finder.ClassLoaderInterface" class="org.apache.struts2.osgi.BundleClassLoaderInterface" />
+    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
+    "http://struts.apache.org/dtds/struts-2.1.7.dtd">
     
+<struts order="10">
     <constant name="struts.objectFactory" value="osgi" />
     <constant name="struts.objectFactory.delegate" value="struts" />
     <constant name="struts.freemarker.manager.classname" value="org.apache.struts2.osgi.BundleFreemarkerManager" />
@@ -20,5 +13,13 @@
     <constant name="struts.convention.action.includeJars" value="jar:file:.*?/bundles/.*?\.jar(!/)?" />
 
     <constant name="struts.osgi.clearBundleCache" value="true" />
-    <constant name="struts.osgi.startRunLevel" value="2" />
+    <constant name="struts.osgi.startRunLevel" value="3" />
+
+    <bean type="org.apache.struts2.osgi.BundleAccessor" class="org.apache.struts2.osgi.DefaultBundleAccessor" />
+    <bean type="org.apache.struts2.osgi.PackageLoader" class="org.apache.struts2.osgi.BundlePackageLoader" />
+    <bean name="osgi" type="com.opensymphony.xwork2.ObjectFactory" class="org.apache.struts2.osgi.DelegatingObjectFactory" />
+    <bean name="springOsgi" type="com.opensymphony.xwork2.ObjectFactory" class="org.apache.struts2.osgi.SpringOsgiObjectFactory" />
+    <bean name="osgi" type="com.opensymphony.xwork2.config.PackageProvider" class="org.apache.struts2.osgi.OsgiConfigurationProvider" />
+    <bean name="felix" type="org.apache.struts2.osgi.OsgiHost" class="org.apache.struts2.osgi.FelixOsgiHost" />
+    <bean name="osgi" type="com.opensymphony.xwork2.util.finder.ClassLoaderInterface" class="org.apache.struts2.osgi.BundleClassLoaderInterface" />
 </struts>